diff --git a/web/src/app/mapfixes/[mapfixId]/_reviewButtons.tsx b/web/src/app/mapfixes/[mapfixId]/_reviewButtons.tsx index 008fc11..c9138c0 100644 --- a/web/src/app/mapfixes/[mapfixId]/_reviewButtons.tsx +++ b/web/src/app/mapfixes/[mapfixId]/_reviewButtons.tsx @@ -3,13 +3,25 @@ import { MapfixStatus } from "@/app/ts/Mapfix"; import { Button, ButtonOwnProps } from "@mui/material"; import { useState, useEffect } from "react"; -type Actions = "Completed" | "Submit" | "Reject" | "Revoke" -type ApiActions = Lowercase<Actions> | "request-changes" | "trigger-validate" | "retry-validate" | "trigger-upload" | "reset-uploading" | "reset-validating" -type Review = Actions | "Request Changes" | "Accept" | "Validate" | "Upload" | "Reset Uploading (fix softlocked status)" | "Reset Validating (fix softlocked status)" | "Request Changes" +interface ReviewAction { + name: string, + action: string, +} + +const ReviewActions = { + Submit: {name:"Submit",action:"trigger-submit"} as ReviewAction, + Revoke: {name:"Revoke",action:"revoke"} as ReviewAction, + Accept: {name:"Accept",action:"trigger-validate"} as ReviewAction, + Reject: {name:"Reject",action:"reject"} as ReviewAction, + Validate: {name:"Validate",action:"retry-validate"} as ReviewAction, + ResetValidating: {name:"Reset Validating (fix softlocked status)",action:"reset-validating"} as ReviewAction, + RequestChanges: {name:"Request Changes",action:"request-changes"} as ReviewAction, + Upload: {name:"Upload",action:"trigger-upload"} as ReviewAction, + ResetUploading: {name:"Reset Uploading (fix softlocked status)",action:"reset-uploading"} as ReviewAction, +} interface ReviewButton { - name: Review, - action: ApiActions, + action: ReviewAction, mapfixId: string, color: ButtonOwnProps["color"] } @@ -20,7 +32,7 @@ interface ReviewId { mapfixSubmitter: number, } -async function ReviewButtonClicked(action: ApiActions, mapfixId: string) { +async function ReviewButtonClicked(action: string, mapfixId: string) { try { const response = await fetch(`/api/mapfixes/${mapfixId}/status/${action}`, { method: "POST", @@ -46,7 +58,7 @@ function ReviewButton(props: ReviewButton) { return <Button color={props.color} variant="contained" - onClick={() => { ReviewButtonClicked(props.action, props.mapfixId) }}>{props.name}</Button> + onClick={() => { ReviewButtonClicked(props.action.action, props.mapfixId) }}>{props.action.name}</Button> } export default function ReviewButtons(props: ReviewId) { @@ -95,10 +107,10 @@ export default function ReviewButtons(props: ReviewId) { const is_submitter = user === props.mapfixSubmitter; if (is_submitter) { if ([MapfixStatus.UnderConstruction, MapfixStatus.ChangesRequested].includes(mapfixStatus!)) { - visibleButtons.push({ name: "Submit", action: "submit", color: "info", mapfixId }); + visibleButtons.push({ action: ReviewActions.Submit, color: "info", mapfixId }); } if ([MapfixStatus.Submitted, MapfixStatus.ChangesRequested].includes(mapfixStatus!)) { - visibleButtons.push({ name: "Revoke", action: "revoke", color: "info", mapfixId }); + visibleButtons.push({ action: ReviewActions.Revoke, color: "info", mapfixId }); } } @@ -106,14 +118,14 @@ export default function ReviewButtons(props: ReviewId) { // you can't review your own mapfix! // note that this means there needs to be more than one person with MapfixReview if (!is_submitter && mapfixStatus === MapfixStatus.Submitted) { - visibleButtons.push({ name: "Accept", action: "trigger-validate", color: "info", mapfixId }); - visibleButtons.push({ name: "Reject", action: "reject", color: "error", mapfixId }); + visibleButtons.push({ action: ReviewActions.Accept, color: "info", mapfixId }); + visibleButtons.push({ action: ReviewActions.Reject, color: "error", mapfixId }); } if (mapfixStatus === MapfixStatus.AcceptedUnvalidated) { - visibleButtons.push({ name: "Validate", action: "retry-validate", color: "info", mapfixId }); + visibleButtons.push({ action: ReviewActions.Validate, color: "info", mapfixId }); } if (mapfixStatus === MapfixStatus.Validating) { - visibleButtons.push({ name: "Reset Validating (fix softlocked status)", action: "reset-validating", color: "error", mapfixId }); + visibleButtons.push({ action: ReviewActions.ResetValidating, color: "error", mapfixId }); } // this button serves the same purpose as Revoke if you are both // the map submitter and have MapfixReview when status is Submitted @@ -121,16 +133,16 @@ export default function ReviewButtons(props: ReviewId) { [MapfixStatus.Validated, MapfixStatus.AcceptedUnvalidated].includes(mapfixStatus!) || !is_submitter && mapfixStatus == MapfixStatus.Submitted ) { - visibleButtons.push({ name: "Request Changes", action: "request-changes", color: "error", mapfixId }); + visibleButtons.push({ action: ReviewActions.RequestChanges, color: "error", mapfixId }); } } if (roles&RolesConstants.MapfixUpload) { if (mapfixStatus === MapfixStatus.Validated) { - visibleButtons.push({ name: "Upload", action: "trigger-upload", color: "info", mapfixId }); + visibleButtons.push({ action: ReviewActions.Upload, color: "info", mapfixId }); } if (mapfixStatus === MapfixStatus.Uploading) { - visibleButtons.push({ name: "Reset Uploading (fix softlocked status)", action: "reset-uploading", color: "error", mapfixId }); + visibleButtons.push({ action: ReviewActions.ResetUploading, color: "error", mapfixId }); } } @@ -140,7 +152,7 @@ export default function ReviewButtons(props: ReviewId) { <p>No available actions</p> ) : ( visibleButtons.map((btn) => ( - <ReviewButton key={btn.action} {...btn} /> + <ReviewButton key={btn.action.action} {...btn} /> )) )} </section> diff --git a/web/src/app/submissions/[submissionId]/_reviewButtons.tsx b/web/src/app/submissions/[submissionId]/_reviewButtons.tsx index 345d435..aa68897 100644 --- a/web/src/app/submissions/[submissionId]/_reviewButtons.tsx +++ b/web/src/app/submissions/[submissionId]/_reviewButtons.tsx @@ -3,13 +3,25 @@ import { SubmissionStatus } from "@/app/ts/Submission"; import { Button, ButtonOwnProps } from "@mui/material"; import { useState, useEffect } from "react"; -type Actions = "Completed" | "Submit" | "Reject" | "Revoke" -type ApiActions = Lowercase<Actions> | "request-changes" | "trigger-validate" | "retry-validate" | "trigger-upload" | "reset-uploading" | "reset-validating" -type Review = Actions | "Request Changes" | "Accept" | "Validate" | "Upload" | "Reset Uploading (fix softlocked status)" | "Reset Validating (fix softlocked status)" | "Request Changes" +interface ReviewAction { + name: string, + action: string, +} + +const ReviewActions = { + Submit: {name:"Submit",action:"trigger-submit"} as ReviewAction, + Revoke: {name:"Revoke",action:"revoke"} as ReviewAction, + Accept: {name:"Accept",action:"trigger-validate"} as ReviewAction, + Reject: {name:"Reject",action:"reject"} as ReviewAction, + Validate: {name:"Validate",action:"retry-validate"} as ReviewAction, + ResetValidating: {name:"Reset Validating (fix softlocked status)",action:"reset-validating"} as ReviewAction, + RequestChanges: {name:"Request Changes",action:"request-changes"} as ReviewAction, + Upload: {name:"Upload",action:"trigger-upload"} as ReviewAction, + ResetUploading: {name:"Reset Uploading (fix softlocked status)",action:"reset-uploading"} as ReviewAction, +} interface ReviewButton { - name: Review, - action: ApiActions, + action: ReviewAction, submissionId: string, color: ButtonOwnProps["color"] } @@ -20,7 +32,7 @@ interface ReviewId { submissionSubmitter: number, } -async function ReviewButtonClicked(action: ApiActions, submissionId: string) { +async function ReviewButtonClicked(action: string, submissionId: string) { try { const response = await fetch(`/api/submissions/${submissionId}/status/${action}`, { method: "POST", @@ -46,7 +58,7 @@ function ReviewButton(props: ReviewButton) { return <Button color={props.color} variant="contained" - onClick={() => { ReviewButtonClicked(props.action, props.submissionId) }}>{props.name}</Button> + onClick={() => { ReviewButtonClicked(props.action.action, props.submissionId) }}>{props.action.name}</Button> } export default function ReviewButtons(props: ReviewId) { @@ -95,10 +107,10 @@ export default function ReviewButtons(props: ReviewId) { const is_submitter = user === props.submissionSubmitter; if (is_submitter) { if ([SubmissionStatus.UnderConstruction, SubmissionStatus.ChangesRequested].includes(submissionStatus!)) { - visibleButtons.push({ name: "Submit", action: "submit", color: "info", submissionId }); + visibleButtons.push({ action: ReviewActions.Submit, color: "info", submissionId }); } if ([SubmissionStatus.Submitted, SubmissionStatus.ChangesRequested].includes(submissionStatus!)) { - visibleButtons.push({ name: "Revoke", action: "revoke", color: "info", submissionId }); + visibleButtons.push({ action: ReviewActions.Revoke, color: "info", submissionId }); } } @@ -106,14 +118,14 @@ export default function ReviewButtons(props: ReviewId) { // you can't review your own submission! // note that this means there needs to be more than one person with SubmissionReview if (!is_submitter && submissionStatus === SubmissionStatus.Submitted) { - visibleButtons.push({ name: "Accept", action: "trigger-validate", color: "info", submissionId }); - visibleButtons.push({ name: "Reject", action: "reject", color: "error", submissionId }); + visibleButtons.push({ action: ReviewActions.Accept, color: "info", submissionId }); + visibleButtons.push({ action: ReviewActions.Reject, color: "error", submissionId }); } if (submissionStatus === SubmissionStatus.AcceptedUnvalidated) { - visibleButtons.push({ name: "Validate", action: "retry-validate", color: "info", submissionId }); + visibleButtons.push({ action: ReviewActions.Validate, color: "info", submissionId }); } if (submissionStatus === SubmissionStatus.Validating) { - visibleButtons.push({ name: "Reset Validating (fix softlocked status)", action: "reset-validating", color: "error", submissionId }); + visibleButtons.push({ action: ReviewActions.ResetValidating, color: "error", submissionId }); } // this button serves the same purpose as Revoke if you are both // the map submitter and have SubmissionReview when status is Submitted @@ -121,17 +133,17 @@ export default function ReviewButtons(props: ReviewId) { [SubmissionStatus.Validated, SubmissionStatus.AcceptedUnvalidated].includes(submissionStatus!) || !is_submitter && submissionStatus == SubmissionStatus.Submitted ) { - visibleButtons.push({ name: "Request Changes", action: "request-changes", color: "error", submissionId }); + visibleButtons.push({ action: ReviewActions.RequestChanges, color: "error", submissionId }); } } if (roles&RolesConstants.SubmissionUpload) { if (submissionStatus === SubmissionStatus.Validated) { - visibleButtons.push({ name: "Upload", action: "trigger-upload", color: "info", submissionId }); + visibleButtons.push({ action: ReviewActions.Upload, color: "info", submissionId }); } // TODO: hide Reset buttons for 10 seconds if (submissionStatus === SubmissionStatus.Uploading) { - visibleButtons.push({ name: "Reset Uploading (fix softlocked status)", action: "reset-uploading", color: "error", submissionId }); + visibleButtons.push({ action: ReviewActions.ResetUploading, color: "error", submissionId }); } } @@ -141,7 +153,7 @@ export default function ReviewButtons(props: ReviewId) { <p>No available actions</p> ) : ( visibleButtons.map((btn) => ( - <ReviewButton key={btn.action} {...btn} /> + <ReviewButton key={btn.action.action} {...btn} /> )) )} </section>