mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-05 15:22:04 +00:00
The open work-order query keeps its cached result between dialog opens, so on reopen the background refetch ran while isLoading was false and Delete was enabled with the previous count. A work order created at the site since the last open could be deleted past without a warning. Treat an in-flight fetch as an unknown count: Delete and View open work orders wait, the stale copy is hidden and the checking spinner shows until the fresh count arrives.
110 lines
3.9 KiB
TypeScript
110 lines
3.9 KiB
TypeScript
import { useNavigate } from "react-router";
|
|
import {
|
|
Button,
|
|
CircularProgress,
|
|
Dialog,
|
|
DialogActions,
|
|
DialogContent,
|
|
DialogContentText,
|
|
DialogTitle,
|
|
} from "@mui/material";
|
|
import { DIALOG_BLUR_BACKDROP_SX } from "@/components/ui/dialog-blur-backdrop";
|
|
import { useDeleteLocation } from "@/domain/locations/use-cases/use-delete-location";
|
|
import { useSiteOpenWorkOrders } from "@/domain/locations/use-cases/use-site-open-work-orders";
|
|
import { buildSiteOpenWorkOrdersHref } from "@/domain/work-orders/utils/dashboard-drilldown-params";
|
|
import { buildWorkOrderIdsHref } from "@/domain/work-orders/utils/work-order-ids-filter";
|
|
|
|
interface SiteDeleteDialogProps {
|
|
open: boolean;
|
|
siteId: string;
|
|
siteCode: string;
|
|
onClose: () => void;
|
|
onDeleted: () => void;
|
|
}
|
|
|
|
const CHECK_FAILED_MESSAGE =
|
|
"Couldn't check this site for open work orders. Try again before deleting it.";
|
|
|
|
function describeDeletion(siteCode: string, openCount: number): string {
|
|
if (openCount === 0) {
|
|
return `This will permanently remove ${siteCode} from Sites. This cannot be undone.`;
|
|
}
|
|
const noun = openCount === 1 ? "work order" : "work orders";
|
|
return `This will permanently remove ${siteCode} from Sites. It still has ${openCount} open ${noun} — deleting the site won't cancel them automatically. This cannot be undone.`;
|
|
}
|
|
|
|
/** Delete confirmation; warns with the open work-order count and links to those work orders. */
|
|
export function SiteDeleteDialog({
|
|
open,
|
|
siteId,
|
|
siteCode,
|
|
onClose,
|
|
onDeleted,
|
|
}: SiteDeleteDialogProps) {
|
|
const navigate = useNavigate();
|
|
const deleteLocation = useDeleteLocation();
|
|
const {
|
|
data: openWorkOrders,
|
|
isLoading,
|
|
isError,
|
|
isFetching,
|
|
refetch,
|
|
} = useSiteOpenWorkOrders(siteId, open);
|
|
const openCount = openWorkOrders?.count ?? 0;
|
|
// Without a current count the warning cannot be trusted, so Delete waits for a successful check.
|
|
// `isFetching` covers reopening: the count cached from the last open is stale until the refetch lands.
|
|
const countUnknown = isLoading || isFetching || isError;
|
|
// The server caps the id list; when it doesn't cover the stated count, open the site's whole board.
|
|
const openIds = openWorkOrders?.workOrderIds ?? [];
|
|
const openWorkOrdersHref =
|
|
openIds.length > 0 && openIds.length >= openCount
|
|
? buildWorkOrderIdsHref(openIds)
|
|
: buildSiteOpenWorkOrdersHref(siteId);
|
|
|
|
return (
|
|
<Dialog
|
|
open={open}
|
|
onClose={() => {
|
|
if (!deleteLocation.isPending) {
|
|
onClose();
|
|
}
|
|
}}
|
|
aria-labelledby="site-delete-title"
|
|
slotProps={{ backdrop: { sx: DIALOG_BLUR_BACKDROP_SX } }}
|
|
>
|
|
<DialogTitle id="site-delete-title">Delete this site?</DialogTitle>
|
|
<DialogContent>
|
|
{isFetching && !isError && (
|
|
<CircularProgress size={20} aria-label="Checking open work orders" />
|
|
)}
|
|
{isError && <DialogContentText role="alert">{CHECK_FAILED_MESSAGE}</DialogContentText>}
|
|
{!countUnknown && (
|
|
<DialogContentText>{describeDeletion(siteCode, openCount)}</DialogContentText>
|
|
)}
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Button variant="text" onClick={onClose} disabled={deleteLocation.isPending}>
|
|
Cancel
|
|
</Button>
|
|
{isError && (
|
|
<Button variant="outlined" disabled={isFetching} onClick={() => void refetch()}>
|
|
Try again
|
|
</Button>
|
|
)}
|
|
{!countUnknown && openCount > 0 && (
|
|
<Button variant="outlined" onClick={() => navigate(openWorkOrdersHref)}>
|
|
View open work orders
|
|
</Button>
|
|
)}
|
|
<Button
|
|
variant="contained"
|
|
color="error"
|
|
disabled={countUnknown || deleteLocation.isPending}
|
|
onClick={() => deleteLocation.mutate(siteId, { onSuccess: onDeleted })}
|
|
>
|
|
{deleteLocation.isPending ? "Deleting..." : "Delete"}
|
|
</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
);
|
|
}
|