mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-07 16:19:01 +00:00
An empty tradeOptions array meant two different things: "facets query still in flight" and "vocabulary genuinely unavailable". Both enabled fail-open free text and showed the outage warning, so a normal cold fetch looked like an outage. Anything committed in that window was added to knownTradesRef and stayed selectable after the canonical list arrived, permanently undermining the gate. Expose the facets query isLoading as tradesLoading, thread it to the field as tradeOptionsLoading, and keep the canonical gate active while loading. The outage warning now shows only once the query has settled empty.
95 lines
2.9 KiB
TypeScript
95 lines
2.9 KiB
TypeScript
import { useEffect } from "react";
|
|
import {
|
|
Box,
|
|
Button,
|
|
CircularProgress,
|
|
Dialog,
|
|
DialogActions,
|
|
DialogContent,
|
|
DialogTitle,
|
|
Stack,
|
|
} from "@mui/material";
|
|
import { Text } from "@/components/ui/text";
|
|
import { VendorRosterConflictAlert } from "./vendor-roster-conflict-alert";
|
|
import { VendorRosterFormFields } from "./vendor-roster-form-fields";
|
|
import { VendorRosterLoadErrorAlert } from "./vendor-roster-load-error";
|
|
import { useVendorRosterForm } from "./use-vendor-roster-form";
|
|
|
|
interface VendorCreateModalProps {
|
|
open: boolean;
|
|
onClose: () => void;
|
|
}
|
|
|
|
export function VendorCreateModal({ open, onClose }: VendorCreateModalProps) {
|
|
const form = useVendorRosterForm({
|
|
mode: "create",
|
|
onSuccess: onClose,
|
|
startWithTechnician: true,
|
|
});
|
|
const { resetForm } = form;
|
|
|
|
useEffect(() => {
|
|
if (!open) resetForm();
|
|
}, [open, resetForm]);
|
|
|
|
return (
|
|
<Dialog
|
|
open={open}
|
|
onClose={form.isSaving ? undefined : onClose}
|
|
fullWidth
|
|
maxWidth="sm"
|
|
aria-labelledby="vendor-create-dialog-title"
|
|
slotProps={{
|
|
paper: {
|
|
role: "dialog",
|
|
sx: { maxHeight: "88vh", borderRadius: 2 },
|
|
},
|
|
}}
|
|
>
|
|
<DialogTitle id="vendor-create-dialog-title">
|
|
<Text variant="title" as="span">
|
|
Add Vendor
|
|
</Text>
|
|
<Text variant="description" tone="muted" sx={{ mt: 0.5 }}>
|
|
Register a vendor company and its technicians.
|
|
</Text>
|
|
</DialogTitle>
|
|
<DialogContent sx={{ maxHeight: "55vh" }}>
|
|
<Stack spacing={2} className="mt-1">
|
|
{form.loadErrorMessage !== null && (
|
|
<VendorRosterLoadErrorAlert message={form.loadErrorMessage} onRetry={form.retryLoad} />
|
|
)}
|
|
{form.conflict !== null && (
|
|
<VendorRosterConflictAlert conflict={form.conflict} onReload={form.reload} />
|
|
)}
|
|
<Box component="form" id="vendor-create-form" onSubmit={form.handleSubmit(form.submit)}>
|
|
<VendorRosterFormFields
|
|
control={form.control}
|
|
errors={form.errors}
|
|
companies={form.companies}
|
|
tradeOptions={form.trades}
|
|
tradeOptionsLoading={form.tradesLoading}
|
|
selectedCompanyId={form.selectedCompanyId}
|
|
onSelectCompany={form.selectCompany}
|
|
onClearSelectedCompany={form.clearSelectedCompany}
|
|
/>
|
|
</Box>
|
|
</Stack>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Button onClick={onClose} disabled={form.isSaving}>
|
|
Cancel
|
|
</Button>
|
|
<Button
|
|
color="primary"
|
|
variant="contained"
|
|
type="submit"
|
|
form="vendor-create-form"
|
|
disabled={form.isSaving}
|
|
>
|
|
{form.isSaving ? <CircularProgress size={20} color="inherit" /> : "Add Vendor"}
|
|
</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
);
|
|
}
|