diff --git a/frontend/src/components/resources/build/actions.tsx b/frontend/src/components/resources/build/actions.tsx index 7fbb3efe1..a3a06ad36 100644 --- a/frontend/src/components/resources/build/actions.tsx +++ b/frontend/src/components/resources/build/actions.tsx @@ -12,6 +12,12 @@ export const RunBuild = ({ id }: { id: string }) => { { build: id }, { refetchInterval: 5000 } ).data?.building; + const updates = useRead("ListUpdates", { + query: { + "target.type": "Build", + "target.id": id, + }, + }).data; const { mutate: run_mutate, isPending: runPending } = useExecute("RunBuild"); const { mutate: cancel_mutate, isPending: cancelPending } = useExecute("CancelBuild"); @@ -24,6 +30,18 @@ export const RunBuild = ({ id }: { id: string }) => { ) return null; + // updates come in in descending order, so 'find' will find latest update matching operation + const latestBuild = updates?.updates.find( + (u) => u.operation === Types.Operation.RunBuild + ); + const latestCancel = updates?.updates.find( + (u) => u.operation === Types.Operation.CancelBuild + ); + const cancelDisabled = + cancelPending || (latestCancel && latestBuild) + ? latestCancel!.start_ts > latestBuild!.start_ts + : false; + if (building) { return ( { variant="destructive" icon={} onClick={() => cancel_mutate({ build: id })} - disabled={cancelPending} + disabled={cancelDisabled} /> ); } else { diff --git a/frontend/src/components/updates/resource.tsx b/frontend/src/components/updates/resource.tsx index caa90bfb4..e6f0f85e7 100644 --- a/frontend/src/components/updates/resource.tsx +++ b/frontend/src/components/updates/resource.tsx @@ -15,7 +15,7 @@ import { Section } from "@components/layouts"; import { UpdateDetails, UpdateUser } from "./details"; import { UpdateStatus } from "@monitor/client/dist/types"; import { fmt_date, fmt_version } from "@lib/formatting"; -import { usableResourcePath, version_is_none } from "@lib/utils"; +import { getUpdateQuery, usableResourcePath, version_is_none } from "@lib/utils"; import { Card } from "@ui/card"; import { UsableResource } from "@types"; @@ -108,35 +108,3 @@ export const ResourceUpdates = ({ type, id }: Types.ResourceTarget) => { ); }; - -const getUpdateQuery = ( - target: Types.ResourceTarget, - deployments: Types.DeploymentListItem[] | undefined -) => { - const build_id = - target.type === "Deployment" - ? deployments?.find((d) => d.id === target.id)?.info.build_id - : undefined; - if (build_id) { - return { - $or: [ - { - "target.type": target.type, - "target.id": target.id, - }, - { - "target.type": "Build", - "target.id": build_id, - operation: { - $in: [Types.Operation.RunBuild, Types.Operation.CancelBuild], - }, - }, - ], - }; - } else { - return { - "target.type": target.type, - "target.id": target.id, - }; - } -}; diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts index f8864262e..148b9833c 100644 --- a/frontend/src/lib/utils.ts +++ b/frontend/src/lib/utils.ts @@ -125,3 +125,35 @@ export const logToHtml = (log: string) => { }); return convert.toHtml(sanitized); }; + +export const getUpdateQuery = ( + target: Types.ResourceTarget, + deployments: Types.DeploymentListItem[] | undefined +) => { + const build_id = + target.type === "Deployment" + ? deployments?.find((d) => d.id === target.id)?.info.build_id + : undefined; + if (build_id) { + return { + $or: [ + { + "target.type": target.type, + "target.id": target.id, + }, + { + "target.type": "Build", + "target.id": build_id, + operation: { + $in: [Types.Operation.RunBuild, Types.Operation.CancelBuild], + }, + }, + ], + }; + } else { + return { + "target.type": target.type, + "target.id": target.id, + }; + } +}; \ No newline at end of file