@burdenoff/microfe-assethandler 2026.714.2 → 2026.719.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assethandler/AssetHandlerRoutes.d.ts.map +1 -1
- package/dist/assethandler/AssetHandlerRoutes.js +9 -17
- package/dist/assethandler/AssetHandlerRoutes.js.map +1 -1
- package/dist/assethandler/ops/NewWorkOrderDialog.d.ts.map +1 -1
- package/dist/assethandler/ops/NewWorkOrderDialog.js +110 -74
- package/dist/assethandler/ops/NewWorkOrderDialog.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCreatePage.d.ts.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCreatePage.js +189 -126
- package/dist/assethandler/pages/AssetsAssetCreatePage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetDetailPage.d.ts.map +1 -1
- package/dist/assethandler/pages/AssetsAssetDetailPage.js +312 -251
- package/dist/assethandler/pages/AssetsAssetDetailPage.js.map +1 -1
- package/dist/assethandler/pages/OperationsWorkOrderDetailPage.d.ts.map +1 -1
- package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js +286 -222
- package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js.map +1 -1
- package/dist/stories/ListEmptyState.stories.d.ts +10 -0
- package/dist/stories/ListEmptyState.stories.d.ts.map +1 -0
- package/dist/stories/SectionHeader.stories.d.ts +10 -0
- package/dist/stories/SectionHeader.stories.d.ts.map +1 -0
- package/dist/stories/StatTile.stories.d.ts +10 -0
- package/dist/stories/StatTile.stories.d.ts.map +1 -0
- package/dist/utils/pageContext.d.ts.map +1 -1
- package/dist/utils/pageContext.js +26 -18
- package/dist/utils/pageContext.js.map +1 -1
- package/package.json +16 -3
- package/dist/assethandler/pages/EsgDashboardPage.js +0 -423
- package/dist/assethandler/pages/EsgDashboardPage.js.map +0 -1
- package/dist/assethandler/pages/KnowledgeBasePage.js +0 -521
- package/dist/assethandler/pages/KnowledgeBasePage.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OperationsWorkOrderDetailPage.js","names":[],"sources":["../../../src/assethandler/pages/OperationsWorkOrderDetailPage.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from 'react';\nimport { useAssetHandlerNavigate } from '../hooks/useAssetHandlerNavigate';\nimport {\n Button,\n GradientText,\n PagePurpose,\n Input,\n Label,\n Textarea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowLeft, CheckCircle, Pencil, Loader2, Wrench, Package, User } from 'lucide-react';\nimport { useParams } from 'react-router-dom';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { notify } from '../utils/toast';\nimport { cn } from '../utils/cn';\nimport {\n AttachmentsPanel,\n CommentsPanel,\n ActivityTimeline,\n NotFoundState,\n ChartCard,\n} from '../components';\n\nconst WORK_ORDER_QUERY = gql`\n query AssetHandlerWorkOrder($id: ID!) {\n workOrder(id: $id) {\n id\n title\n description\n type\n status\n priority\n assetId\n assignedTo\n createdAt\n updatedAt\n completedAt\n }\n }\n`;\n\ninterface WorkOrderRecord {\n id: string;\n title: string;\n description?: string | null;\n type: string;\n status: string;\n priority: string;\n assetId?: string | null;\n assignedTo?: string | null;\n createdAt: string;\n updatedAt?: string | null;\n completedAt?: string | null;\n}\n\ninterface WorkOrderQueryResult {\n workOrder: WorkOrderRecord | null;\n}\n\nconst COMPLETE_WORK_ORDER_MUTATION = gql`\n mutation AssetHandlerCompleteWorkOrder($id: ID!, $input: CompleteWorkOrderInput!) {\n completeWorkOrder(id: $id, input: $input) {\n id\n status\n completedAt\n }\n }\n`;\n\nconst UPDATE_WORK_ORDER_MUTATION = gql`\n mutation AssetHandlerUpdateWorkOrder($id: ID!, $input: UpdateWorkOrderInput!) {\n updateWorkOrder(id: $id, input: $input) {\n id\n }\n }\n`;\n\nconst WORK_ORDER_TYPES = ['CORRECTIVE', 'PREVENTIVE', 'PREDICTIVE', 'EMERGENCY'] as const;\nconst WORK_ORDER_STATUSES = [\n 'DRAFT',\n 'SCHEDULED',\n 'APPROVED',\n 'IN_PROGRESS',\n 'COMPLETED',\n 'CANCELLED',\n] as const;\nconst PRIORITIES = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] as const;\n\ntype Tone = 'neutral' | 'info' | 'warning' | 'success' | 'error';\n\nconst TONE_CLASS: Record<Tone, string> = {\n neutral: 'bg-bg-sunken text-text-secondary',\n info: 'bg-status-info-subtle text-status-info-text',\n warning: 'bg-status-warning-subtle text-status-warning-text',\n success: 'bg-status-success-subtle text-status-success-text',\n error: 'bg-status-error-subtle text-status-error-text',\n};\n\nconst PRIORITY_TONE: Record<string, Tone> = {\n critical: 'error',\n high: 'warning',\n medium: 'info',\n low: 'success',\n};\nconst STATUS_TONE: Record<string, Tone> = {\n draft: 'neutral',\n scheduled: 'neutral',\n approved: 'info',\n in_progress: 'info',\n completed: 'success',\n cancelled: 'error',\n};\n\nfunction Pill({ tone, children }: { tone: Tone; children: ReactNode }) {\n return (\n <span\n className={cn(\n 'inline-flex items-center whitespace-nowrap rounded-full px-2.5 py-0.5 text-xs font-medium capitalize',\n TONE_CLASS[tone]\n )}\n >\n {children}\n </span>\n );\n}\n\nconst LIFECYCLE = ['draft', 'scheduled', 'approved', 'in_progress', 'completed'] as const;\n\nfunction LifecycleStepper({ status }: { status: string }) {\n const cancelled = status === 'cancelled';\n const currentIndex = LIFECYCLE.indexOf(status as (typeof LIFECYCLE)[number]);\n return (\n <div className=\"flex items-center gap-1 overflow-x-auto pb-1\">\n {LIFECYCLE.map((step, i) => {\n const done = !cancelled && currentIndex >= 0 && i < currentIndex;\n const current = !cancelled && i === currentIndex;\n return (\n <div key={step} className=\"flex min-w-0 flex-1 items-center gap-1\">\n <div className=\"flex min-w-0 flex-col items-center gap-1.5\">\n <span\n className={cn(\n 'flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-[10px] font-bold',\n done && 'bg-status-success-bg text-status-success-text',\n current && 'bg-action-primary-bg text-action-primary-text',\n !done && !current && 'bg-bg-sunken text-text-muted'\n )}\n >\n {done ? <CheckCircle className=\"h-3.5 w-3.5\" /> : i + 1}\n </span>\n <span\n className={cn(\n 'whitespace-nowrap text-[11px] capitalize',\n current ? 'font-semibold text-text-primary' : 'text-text-secondary'\n )}\n >\n {step.replace(/_/g, ' ')}\n </span>\n </div>\n {i < LIFECYCLE.length - 1 ? (\n <span\n className={cn(\n 'mb-5 h-0.5 flex-1 rounded-full',\n done ? 'bg-status-success-bg' : 'bg-border-seam'\n )}\n />\n ) : null}\n </div>\n );\n })}\n {cancelled ? (\n <span className=\"ml-3 shrink-0 rounded-full bg-status-error-subtle px-2.5 py-0.5 text-xs font-medium text-status-error-text\">\n Cancelled\n </span>\n ) : null}\n </div>\n );\n}\n\nconst humanize = (value: string) =>\n value\n .toLowerCase()\n .replace(/_/g, ' ')\n .replace(/^\\w/, (c) => c.toUpperCase());\n\ninterface EditForm {\n title: string;\n description: string;\n type: string;\n priority: string;\n status: string;\n assignedTo: string;\n}\n\nexport function OperationsWorkOrderDetailPage() {\n const navigate = useAssetHandlerNavigate();\n const { workOrderId } = useParams<{ workOrderId: string }>();\n const { assets } = useAssetHandlerStore();\n\n const { data, loading, refetch } = useQuery<WorkOrderQueryResult>(WORK_ORDER_QUERY, {\n variables: { id: workOrderId ?? '' },\n skip: !workOrderId,\n fetchPolicy: 'cache-and-network',\n });\n\n const [showComplete, setShowComplete] = useState(false);\n const [showEdit, setShowEdit] = useState(false);\n const [completeForm, setCompleteForm] = useState({ actualCost: '', notes: '' });\n const [editForm, setEditForm] = useState<EditForm | null>(null);\n\n const assetName = useMemo(() => {\n const byId = new Map(assets.map((a) => [a.id, a.name]));\n return (id: string | null | undefined) => (id ? (byId.get(id) ?? id) : null);\n }, [assets]);\n\n const [completeWorkOrder, { loading: completing }] = useMutation(COMPLETE_WORK_ORDER_MUTATION, {\n refetchQueries: ['AssetHandlerBootstrap'],\n onCompleted: () => {\n notify.success('Work order completed', 'The job has been signed off.');\n setShowComplete(false);\n void refetch();\n },\n onError: (error) => notify.error('Could not complete work order', error.message),\n });\n\n const [updateWorkOrder, { loading: updating }] = useMutation(UPDATE_WORK_ORDER_MUTATION, {\n refetchQueries: ['AssetHandlerBootstrap'],\n onCompleted: () => {\n notify.success('Work order updated', 'Your changes have been saved.');\n setShowEdit(false);\n void refetch();\n },\n onError: (error) => notify.error('Could not update work order', error.message),\n });\n\n if (loading && !data) {\n return (\n <div className=\"space-y-3 p-6\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div key={i} className=\"h-10 rounded-md bg-bg-sunken motion-safe:animate-vc-shimmer\" />\n ))}\n </div>\n );\n }\n\n const raw = data?.workOrder;\n if (!raw) {\n return (\n <NotFoundState\n entityLabel=\"Work order\"\n description=\"This work order may have been completed or removed. Return to the operations hub to find it.\"\n backLabel=\"Back to operations\"\n onBack={() => navigate('/operations/operations-hub')}\n />\n );\n }\n\n const wo = {\n ...raw,\n status: raw.status.toLowerCase(),\n priority: raw.priority.toLowerCase(),\n type: raw.type.toLowerCase(),\n };\n const isClosed = wo.status === 'completed' || wo.status === 'cancelled';\n const linkedAsset = assetName(wo.assetId);\n\n const openEdit = () => {\n setEditForm({\n title: raw.title,\n description: raw.description ?? '',\n type: raw.type.toUpperCase(),\n priority: raw.priority.toUpperCase(),\n status: raw.status.toUpperCase(),\n assignedTo: raw.assignedTo ?? '',\n });\n setShowEdit(true);\n };\n\n const setEdit = (field: keyof EditForm, value: string) =>\n setEditForm((prev) => (prev ? { ...prev, [field]: value } : prev));\n\n const submitComplete = () => {\n const parsedCost = Number(completeForm.actualCost);\n void completeWorkOrder({\n variables: {\n id: wo.id,\n input: {\n actualCost:\n completeForm.actualCost.trim() !== '' && Number.isFinite(parsedCost)\n ? parsedCost\n : null,\n notes: completeForm.notes.trim() || null,\n },\n },\n });\n };\n\n const submitEdit = () => {\n if (!editForm) return;\n if (!editForm.title.trim()) {\n notify.warning('Title required', 'A work order must have a title.');\n return;\n }\n void updateWorkOrder({\n variables: {\n id: wo.id,\n input: {\n title: editForm.title.trim(),\n description: editForm.description.trim() || null,\n type: editForm.type,\n priority: editForm.priority,\n status: editForm.status,\n assignedTo: editForm.assignedTo.trim() || null,\n },\n },\n });\n };\n\n const detailRows: { label: string; value: ReactNode }[] = [\n {\n label: 'Asset',\n value: linkedAsset ? (\n <button\n type=\"button\"\n className=\"font-medium text-action-primary-text hover:underline\"\n onClick={() => navigate('/assets/' + wo.assetId)}\n >\n {linkedAsset}\n </button>\n ) : (\n <span className=\"text-text-secondary\">Unassigned</span>\n ),\n },\n { label: 'Type', value: <span className=\"capitalize\">{humanize(wo.type)}</span> },\n {\n label: 'Assigned technician',\n value: wo.assignedTo || <span className=\"text-text-secondary\">Unassigned</span>,\n },\n {\n label: 'Created',\n value: wo.createdAt ? new Date(wo.createdAt).toLocaleDateString() : '—',\n },\n {\n label: 'Completed',\n value: wo.completedAt ? new Date(wo.completedAt).toLocaleDateString() : '—',\n },\n ];\n\n return (\n <div className=\"space-y-6 p-4 sm:p-6\">\n {/* header */}\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-3\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Go back\"\n className=\"shrink-0\"\n onClick={() => navigate('/operations/operations-hub')}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div className=\"min-w-0\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-text-secondary\">\n Maintenance / Work Order Detail\n </p>\n <h1 className=\"truncate text-2xl font-bold\">\n <GradientText>{wo.title}</GradientText>\n </h1>\n <p className=\"mt-0.5 font-mono text-xs text-text-secondary\">{wo.id}</p>\n </div>\n </div>\n <div className=\"flex w-full items-center gap-2 sm:w-auto\">\n <Button size=\"sm\" variant=\"outline\" className=\"flex-1 sm:flex-none\" onClick={openEdit}>\n <Pencil className=\"mr-2 h-4 w-4\" />\n Edit\n </Button>\n {!isClosed ? (\n <Button size=\"sm\" className=\"flex-1 sm:flex-none\" onClick={() => setShowComplete(true)}>\n <CheckCircle className=\"mr-2 h-4 w-4\" />\n Complete\n </Button>\n ) : null}\n </div>\n </div>\n\n {/* status hero strip */}\n <ChartCard title=\"Status\">\n <div className=\"flex flex-wrap items-center gap-x-8 gap-y-4\">\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Priority</p>\n <div className=\"mt-1\">\n <Pill tone={PRIORITY_TONE[wo.priority] ?? 'neutral'}>{wo.priority}</Pill>\n </div>\n </div>\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Status</p>\n <div className=\"mt-1\">\n <Pill tone={STATUS_TONE[wo.status] ?? 'neutral'}>{wo.status.replace(/_/g, ' ')}</Pill>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <User className=\"h-4 w-4 text-text-muted\" />\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Technician</p>\n <p className=\"mt-0.5 text-sm font-medium text-text-primary\">\n {wo.assignedTo || 'Unassigned'}\n </p>\n </div>\n </div>\n {linkedAsset ? (\n <div className=\"flex items-center gap-2\">\n <Package className=\"h-4 w-4 text-text-muted\" />\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Asset</p>\n <button\n type=\"button\"\n className=\"mt-0.5 text-sm font-medium text-action-primary-text hover:underline\"\n onClick={() => navigate('/assets/' + wo.assetId)}\n >\n {linkedAsset}\n </button>\n </div>\n </div>\n ) : null}\n </div>\n <div className=\"mt-5 border-t border-border-seam pt-4\">\n <LifecycleStepper status={wo.status} />\n </div>\n </ChartCard>\n\n <div className=\"grid gap-6 lg:grid-cols-3\">\n {/* main column */}\n <div className=\"space-y-6 lg:col-span-2\">\n <ChartCard title=\"Details\" icon={Wrench}>\n <div>\n <h4 className=\"text-xs font-semibold uppercase tracking-wide text-text-secondary\">\n Description\n </h4>\n <p className=\"mt-1 text-sm text-text-primary\">{wo.description || '—'}</p>\n </div>\n <dl className=\"mt-4 divide-y divide-border-seam text-sm\">\n {detailRows.map((row) => (\n <div\n key={row.label}\n className=\"flex flex-col gap-0.5 py-2.5 sm:flex-row sm:items-center sm:justify-between\"\n >\n <dt className=\"text-text-secondary\">{row.label}</dt>\n <dd className=\"font-medium text-text-primary sm:text-right\">{row.value}</dd>\n </div>\n ))}\n </dl>\n </ChartCard>\n\n <PagePurpose>\n The full brief for a single work order: what needs doing, on which asset and by whom.\n Track the job from open to complete and keep the asset's maintenance history\n accurate.\n </PagePurpose>\n </div>\n\n {/* persistent context rail */}\n <div className=\"space-y-6\">\n <AttachmentsPanel entityType=\"assethandler-work-order\" entityId={wo.id} />\n <CommentsPanel entityType=\"assethandler-work-order\" entityId={wo.id} />\n <ActivityTimeline resourceId={wo.id} />\n </div>\n </div>\n\n {/* Complete dialog */}\n <ResponsiveDialog open={showComplete} onOpenChange={setShowComplete}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Complete work order</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Record the final cost and any closing notes. This marks the work order as completed.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label>Actual Cost</Label>\n <Input\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n placeholder=\"e.g., 750\"\n value={completeForm.actualCost}\n onChange={(e) =>\n setCompleteForm((prev) => ({ ...prev, actualCost: e.target.value }))\n }\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Notes</Label>\n <Textarea\n placeholder=\"What was done to close this out?\"\n value={completeForm.notes}\n onChange={(e) => setCompleteForm((prev) => ({ ...prev, notes: e.target.value }))}\n rows={3}\n />\n </div>\n </div>\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setShowComplete(false)} disabled={completing}>\n Cancel\n </Button>\n <Button onClick={submitComplete} disabled={completing}>\n {completing ? <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" /> : null}\n {completing ? 'Completing…' : 'Complete work order'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Edit dialog */}\n <ResponsiveDialog open={showEdit} onOpenChange={setShowEdit}>\n <ResponsiveDialogContent className=\"max-h-[85vh] overflow-y-auto sm:max-w-xl\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Edit work order</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Update the work order's details and status.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n {editForm ? (\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label>Title</Label>\n <Input value={editForm.title} onChange={(e) => setEdit('title', e.target.value)} />\n </div>\n <div className=\"space-y-2\">\n <Label>Description</Label>\n <Textarea\n value={editForm.description}\n onChange={(e) => setEdit('description', e.target.value)}\n rows={2}\n />\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label>Type</Label>\n <Select value={editForm.type} onValueChange={(v) => setEdit('type', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {WORK_ORDER_TYPES.map((t) => (\n <SelectItem key={t} value={t}>\n {humanize(t)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>Priority</Label>\n <Select value={editForm.priority} onValueChange={(v) => setEdit('priority', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {PRIORITIES.map((p) => (\n <SelectItem key={p} value={p}>\n {humanize(p)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>Status</Label>\n <Select value={editForm.status} onValueChange={(v) => setEdit('status', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {WORK_ORDER_STATUSES.map((s) => (\n <SelectItem key={s} value={s}>\n {humanize(s)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label>Assigned To</Label>\n <Input\n value={editForm.assignedTo}\n onChange={(e) => setEdit('assignedTo', e.target.value)}\n />\n </div>\n </div>\n ) : null}\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setShowEdit(false)} disabled={updating}>\n Cancel\n </Button>\n <Button onClick={submitEdit} disabled={updating}>\n {updating ? <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" /> : null}\n {updating ? 'Saving…' : 'Save changes'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAoCA,IAAM,KAAmB,CAAG;;;;;;;;;;;;;;;;GAoCtB,KAA+B,CAAG;;;;;;;;GAUlC,KAA6B,CAAG;;;;;;GAQhC,KAAmB;CAAC;CAAc;CAAc;CAAc;CAAY,EAC1E,KAAsB;CAC1B;CACA;CACA;CACA;CACA;CACA;CACD,EACK,KAAa;CAAC;CAAY;CAAQ;CAAU;CAAM,EAIlD,IAAmC;CACvC,SAAS;CACT,MAAM;CACN,SAAS;CACT,SAAS;CACT,OAAO;CACR,EAEK,KAAsC;CAC1C,UAAU;CACV,MAAM;CACN,QAAQ;CACR,KAAK;CACN,EACK,IAAoC;CACxC,OAAO;CACP,WAAW;CACX,UAAU;CACV,aAAa;CACb,WAAW;CACX,WAAW;CACZ;AAED,SAAS,EAAK,EAAE,SAAM,eAAiD;AACrE,QACE,kBAAC,QAAD;EACE,WAAW,EACT,wGACA,EAAW,GACZ;EAEA;EACI,CAAA;;AAIX,IAAM,IAAY;CAAC;CAAS;CAAa;CAAY;CAAe;CAAY;AAEhF,SAAS,EAAiB,EAAE,aAA8B;CACxD,IAAM,IAAY,MAAW,aACvB,IAAe,EAAU,QAAQ,EAAqC;AAC5E,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACG,EAAU,KAAK,GAAM,MAAM;GAC1B,IAAM,IAAO,CAAC,KAAa,KAAgB,KAAK,IAAI,GAC9C,IAAU,CAAC,KAAa,MAAM;AACpC,UACE,kBAAC,OAAD;IAAgB,WAAU;cAA1B,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,QAAD;MACE,WAAW,EACT,wFACA,KAAQ,iDACR,KAAW,iDACX,CAAC,KAAQ,CAAC,KAAW,+BACtB;gBAEA,IAAO,kBAAC,GAAD,EAAa,WAAU,eAAgB,CAAA,GAAG,IAAI;MACjD,CAAA,EACP,kBAAC,QAAD;MACE,WAAW,EACT,4CACA,IAAU,oCAAoC,sBAC/C;gBAEA,EAAK,QAAQ,MAAM,IAAI;MACnB,CAAA,CACH;QACL,IAAI,EAAU,SAAS,IACtB,kBAAC,QAAD,EACE,WAAW,EACT,kCACA,IAAO,yBAAyB,iBACjC,EACD,CAAA,GACA,KACA;MA7BI,EA6BJ;IAER,EACD,IACC,kBAAC,QAAD;GAAM,WAAU;aAA6G;GAEtH,CAAA,GACL,KACA;;;AAIV,IAAM,KAAY,MAChB,EACG,aAAa,CACb,QAAQ,MAAM,IAAI,CAClB,QAAQ,QAAQ,MAAM,EAAE,aAAa,CAAC;AAW3C,SAAgB,IAAgC;CAC9C,IAAM,IAAW,GAAyB,EACpC,EAAE,mBAAgB,IAAoC,EACtD,EAAE,cAAW,GAAsB,EAEnC,EAAE,SAAM,YAAS,eAAY,EAA+B,IAAkB;EAClF,WAAW,EAAE,IAAI,KAAe,IAAI;EACpC,MAAM,CAAC;EACP,aAAa;EACd,CAAC,EAEI,CAAC,IAAc,KAAmB,EAAS,GAAM,EACjD,CAAC,IAAU,KAAe,EAAS,GAAM,EACzC,CAAC,GAAc,KAAmB,EAAS;EAAE,YAAY;EAAI,OAAO;EAAI,CAAC,EACzE,CAAC,GAAU,KAAe,EAA0B,KAAK,EAEzD,KAAY,SAAc;EAC9B,IAAM,IAAO,IAAI,IAAI,EAAO,KAAK,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AACvD,UAAQ,MAAmC,IAAM,EAAK,IAAI,EAAG,IAAI,IAAM;IACtE,CAAC,EAAO,CAAC,EAEN,CAAC,IAAmB,EAAE,SAAS,OAAgB,EAAY,IAA8B;EAC7F,gBAAgB,CAAC,wBAAwB;EACzC,mBAAmB;AAGZ,GAFL,EAAO,QAAQ,wBAAwB,+BAA+B,EACtE,EAAgB,GAAM,EACjB,GAAS;;EAEhB,UAAU,MAAU,EAAO,MAAM,iCAAiC,EAAM,QAAQ;EACjF,CAAC,EAEI,CAAC,IAAiB,EAAE,SAAS,OAAc,EAAY,IAA4B;EACvF,gBAAgB,CAAC,wBAAwB;EACzC,mBAAmB;AAGZ,GAFL,EAAO,QAAQ,sBAAsB,gCAAgC,EACrE,EAAY,GAAM,EACb,GAAS;;EAEhB,UAAU,MAAU,EAAO,MAAM,+BAA+B,EAAM,QAAQ;EAC/E,CAAC;AAEF,KAAI,KAAW,CAAC,EACd,QACE,kBAAC,OAAD;EAAK,WAAU;YACZ,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,OAAD,EAAa,WAAU,+DAAgE,EAA7E,EAA6E,CACvF;EACE,CAAA;CAIV,IAAM,IAAM,GAAM;AAClB,KAAI,CAAC,EACH,QACE,kBAAC,IAAD;EACE,aAAY;EACZ,aAAY;EACZ,WAAU;EACV,cAAc,EAAS,6BAA6B;EACpD,CAAA;CAIN,IAAM,IAAK;EACT,GAAG;EACH,QAAQ,EAAI,OAAO,aAAa;EAChC,UAAU,EAAI,SAAS,aAAa;EACpC,MAAM,EAAI,KAAK,aAAa;EAC7B,EACK,KAAW,EAAG,WAAW,eAAe,EAAG,WAAW,aACtD,IAAc,GAAU,EAAG,QAAQ,EAEnC,WAAiB;AASrB,EARA,EAAY;GACV,OAAO,EAAI;GACX,aAAa,EAAI,eAAe;GAChC,MAAM,EAAI,KAAK,aAAa;GAC5B,UAAU,EAAI,SAAS,aAAa;GACpC,QAAQ,EAAI,OAAO,aAAa;GAChC,YAAY,EAAI,cAAc;GAC/B,CAAC,EACF,EAAY,GAAK;IAGb,KAAW,GAAuB,MACtC,GAAa,MAAU,KAAO;EAAE,GAAG;GAAO,IAAQ;EAAO,CAAS,EAE9D,WAAuB;EAC3B,IAAM,IAAa,OAAO,EAAa,WAAW;AAC7C,KAAkB,EACrB,WAAW;GACT,IAAI,EAAG;GACP,OAAO;IACL,YACE,EAAa,WAAW,MAAM,KAAK,MAAM,OAAO,SAAS,EAAW,GAChE,IACA;IACN,OAAO,EAAa,MAAM,MAAM,IAAI;IACrC;GACF,EACF,CAAC;IAGE,WAAmB;AAClB,SACL;OAAI,CAAC,EAAS,MAAM,MAAM,EAAE;AAC1B,MAAO,QAAQ,kBAAkB,kCAAkC;AACnE;;AAEG,MAAgB,EACnB,WAAW;IACT,IAAI,EAAG;IACP,OAAO;KACL,OAAO,EAAS,MAAM,MAAM;KAC5B,aAAa,EAAS,YAAY,MAAM,IAAI;KAC5C,MAAM,EAAS;KACf,UAAU,EAAS;KACnB,QAAQ,EAAS;KACjB,YAAY,EAAS,WAAW,MAAM,IAAI;KAC3C;IACF,EACF,CAAC;;IAGE,KAAoD;EACxD;GACE,OAAO;GACP,OAAO,IACL,kBAAC,UAAD;IACE,MAAK;IACL,WAAU;IACV,eAAe,EAAS,aAAa,EAAG,QAAQ;cAE/C;IACM,CAAA,GAET,kBAAC,QAAD;IAAM,WAAU;cAAsB;IAAiB,CAAA;GAE1D;EACD;GAAE,OAAO;GAAQ,OAAO,kBAAC,QAAD;IAAM,WAAU;cAAc,EAAS,EAAG,KAAK;IAAQ,CAAA;GAAE;EACjF;GACE,OAAO;GACP,OAAO,EAAG,cAAc,kBAAC,QAAD;IAAM,WAAU;cAAsB;IAAiB,CAAA;GAChF;EACD;GACE,OAAO;GACP,OAAO,EAAG,YAAY,IAAI,KAAK,EAAG,UAAU,CAAC,oBAAoB,GAAG;GACrE;EACD;GACE,OAAO;GACP,OAAO,EAAG,cAAc,IAAI,KAAK,EAAG,YAAY,CAAC,oBAAoB,GAAG;GACzE;EACF;AAED,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,SAAQ;MACR,MAAK;MACL,cAAW;MACX,WAAU;MACV,eAAe,EAAS,6BAA6B;gBAErD,kBAAC,IAAD,EAAW,WAAU,WAAY,CAAA;MAC1B,CAAA,EACT,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,KAAD;QAAG,WAAU;kBAAoE;QAE7E,CAAA;OACJ,kBAAC,MAAD;QAAI,WAAU;kBACZ,kBAAC,IAAD,EAAA,UAAe,EAAG,OAAqB,CAAA;QACpC,CAAA;OACL,kBAAC,KAAD;QAAG,WAAU;kBAAgD,EAAG;QAAO,CAAA;OACnE;QACF;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAQ,MAAK;MAAK,SAAQ;MAAU,WAAU;MAAsB,SAAS;gBAA7E,CACE,kBAAC,IAAD,EAAQ,WAAU,gBAAiB,CAAA,EAAA,OAE5B;SACP,KAKE,OAJF,kBAAC,GAAD;MAAQ,MAAK;MAAK,WAAU;MAAsB,eAAe,EAAgB,GAAK;gBAAtF,CACE,kBAAC,GAAD,EAAa,WAAU,gBAAiB,CAAA,EAAA,WAEjC;QAEP;OACF;;GAGN,kBAAC,GAAD;IAAW,OAAM;cAAjB,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAsD;OAAY,CAAA,EAC/E,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD;QAAM,MAAM,GAAc,EAAG,aAAa;kBAAY,EAAG;QAAgB,CAAA;OACrE,CAAA,CACF,EAAA,CAAA;MACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAsD;OAAU,CAAA,EAC7E,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD;QAAM,MAAM,EAAY,EAAG,WAAW;kBAAY,EAAG,OAAO,QAAQ,MAAM,IAAI;QAAQ,CAAA;OAClF,CAAA,CACF,EAAA,CAAA;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,2BAA4B,CAAA,EAC5C,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAc,CAAA,EACjF,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAG,cAAc;QAChB,CAAA,CACA,EAAA,CAAA,CACF;;MACL,IACC,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,IAAD,EAAS,WAAU,2BAA4B,CAAA,EAC/C,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAS,CAAA,EAC5E,kBAAC,UAAD;QACE,MAAK;QACL,WAAU;QACV,eAAe,EAAS,aAAa,EAAG,QAAQ;kBAE/C;QACM,CAAA,CACL,EAAA,CAAA,CACF;WACJ;MACA;QACN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,GAAD,EAAkB,QAAQ,EAAG,QAAU,CAAA;KACnC,CAAA,CACI;;GAEZ,kBAAC,OAAD;IAAK,WAAU;cAAf,CAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAW,OAAM;MAAU,MAAM;gBAAjC,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;OAAI,WAAU;iBAAoE;OAE7E,CAAA,EACL,kBAAC,KAAD;OAAG,WAAU;iBAAkC,EAAG,eAAe;OAAQ,CAAA,CACrE,EAAA,CAAA,EACN,kBAAC,MAAD;OAAI,WAAU;iBACX,GAAW,KAAK,MACf,kBAAC,OAAD;QAEE,WAAU;kBAFZ,CAIE,kBAAC,MAAD;SAAI,WAAU;mBAAuB,EAAI;SAAW,CAAA,EACpD,kBAAC,MAAD;SAAI,WAAU;mBAA+C,EAAI;SAAW,CAAA,CACxE;UALC,EAAI,MAKL,CACN;OACC,CAAA,CACK;SAEZ,kBAAC,GAAD,EAAA,UAAa,gLAIC,CAAA,CACV;QAGN,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD;OAAkB,YAAW;OAA0B,UAAU,EAAG;OAAM,CAAA;MAC1E,kBAAC,GAAD;OAAe,YAAW;OAA0B,UAAU,EAAG;OAAM,CAAA;MACvE,kBAAC,GAAD,EAAkB,YAAY,EAAG,IAAM,CAAA;MACnC;OACF;;GAGN,kBAAC,GAAD;IAAkB,MAAM;IAAc,cAAc;cAClD,kBAAC,GAAD,EAAA,UAAA;KACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAuB,uBAA2C,CAAA,EAClE,kBAAC,GAAD,EAAA,UAA6B,wFAEC,CAAA,CACP,EAAA,CAAA;KACzB,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAA,UAAO,eAAmB,CAAA,EAC1B,kBAAC,GAAD;QACE,MAAK;QACL,KAAI;QACJ,MAAK;QACL,aAAY;QACZ,OAAO,EAAa;QACpB,WAAW,MACT,GAAiB,OAAU;SAAE,GAAG;SAAM,YAAY,EAAE,OAAO;SAAO,EAAE;QAEtE,CAAA,CACE;UACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAA,UAAO,SAAa,CAAA,EACpB,kBAAC,GAAD;QACE,aAAY;QACZ,OAAO,EAAa;QACpB,WAAW,MAAM,GAAiB,OAAU;SAAE,GAAG;SAAM,OAAO,EAAE,OAAO;SAAO,EAAE;QAChF,MAAM;QACN,CAAA,CACE;SACF;;KACN,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAQ,SAAQ;MAAU,eAAe,EAAgB,GAAM;MAAE,UAAU;gBAAY;MAE9E,CAAA,EACT,kBAAC,GAAD;MAAQ,SAAS;MAAgB,UAAU;gBAA3C,CACG,IAAa,kBAAC,GAAD,EAAS,WAAU,6BAA8B,CAAA,GAAG,MACjE,IAAa,gBAAgB,sBACvB;QACc,EAAA,CAAA;KACD,EAAA,CAAA;IACT,CAAA;GAGnB,kBAAC,GAAD;IAAkB,MAAM;IAAU,cAAc;cAC9C,kBAAC,GAAD;KAAyB,WAAU;eAAnC;MACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAuB,mBAAuC,CAAA,EAC9D,kBAAC,GAAD,EAAA,UAA6B,+CAEC,CAAA,CACP,EAAA,CAAA;MACxB,IACC,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD,EAAA,UAAO,SAAa,CAAA,EACpB,kBAAC,GAAD;UAAO,OAAO,EAAS;UAAO,WAAW,MAAM,EAAQ,SAAS,EAAE,OAAO,MAAM;UAAI,CAAA,CAC/E;;QACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD,EAAA,UAAO,eAAmB,CAAA,EAC1B,kBAAC,GAAD;UACE,OAAO,EAAS;UAChB,WAAW,MAAM,EAAQ,eAAe,EAAE,OAAO,MAAM;UACvD,MAAM;UACN,CAAA,CACE;;QACN,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAA,UAAO,QAAY,CAAA,EACnB,kBAAC,GAAD;YAAQ,OAAO,EAAS;YAAM,gBAAgB,MAAM,EAAQ,QAAQ,EAAE;sBAAtE,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAe,CAAA,EACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,GAAiB,KAAK,MACrB,kBAAC,GAAD;aAAoB,OAAO;uBACxB,EAAS,EAAE;aACD,EAFI,EAEJ,CACb,EACY,CAAA,CACT;cACL;;UACN,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAA,UAAO,YAAgB,CAAA,EACvB,kBAAC,GAAD;YAAQ,OAAO,EAAS;YAAU,gBAAgB,MAAM,EAAQ,YAAY,EAAE;sBAA9E,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAe,CAAA,EACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,GAAW,KAAK,MACf,kBAAC,GAAD;aAAoB,OAAO;uBACxB,EAAS,EAAE;aACD,EAFI,EAEJ,CACb,EACY,CAAA,CACT;cACL;;UACN,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAA,UAAO,UAAc,CAAA,EACrB,kBAAC,GAAD;YAAQ,OAAO,EAAS;YAAQ,gBAAgB,MAAM,EAAQ,UAAU,EAAE;sBAA1E,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAe,CAAA,EACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,GAAoB,KAAK,MACxB,kBAAC,GAAD;aAAoB,OAAO;uBACxB,EAAS,EAAE;aACD,EAFI,EAEJ,CACb,EACY,CAAA,CACT;cACL;;UACF;;QACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD,EAAA,UAAO,eAAmB,CAAA,EAC1B,kBAAC,GAAD;UACE,OAAO,EAAS;UAChB,WAAW,MAAM,EAAQ,cAAc,EAAE,OAAO,MAAM;UACtD,CAAA,CACE;;QACF;WACJ;MACJ,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;OAAQ,SAAQ;OAAU,eAAe,EAAY,GAAM;OAAE,UAAU;iBAAU;OAExE,CAAA,EACT,kBAAC,GAAD;OAAQ,SAAS;OAAY,UAAU;iBAAvC,CACG,IAAW,kBAAC,GAAD,EAAS,WAAU,6BAA8B,CAAA,GAAG,MAC/D,IAAW,YAAY,eACjB;SACc,EAAA,CAAA;MACD;;IACT,CAAA;GACf"}
|
|
1
|
+
{"version":3,"file":"OperationsWorkOrderDetailPage.js","names":[],"sources":["../../../src/assethandler/pages/OperationsWorkOrderDetailPage.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from 'react';\nimport { useAssetHandlerNavigate } from '../hooks/useAssetHandlerNavigate';\nimport {\n Button,\n GradientText,\n PagePurpose,\n Input,\n Label,\n Textarea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowLeft, CheckCircle, Pencil, Loader2, Wrench, Package, User } from 'lucide-react';\nimport { useParams } from 'react-router-dom';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { notify } from '../utils/toast';\nimport { cn } from '../utils/cn';\nimport {\n AttachmentsPanel,\n CommentsPanel,\n ActivityTimeline,\n NotFoundState,\n ChartCard,\n} from '../components';\n\nconst WORK_ORDER_QUERY = gql`\n query AssetHandlerWorkOrder($id: ID!) {\n workOrder(id: $id) {\n id\n title\n description\n type\n status\n priority\n assetId\n assignedTo\n createdAt\n updatedAt\n completedAt\n checklist\n }\n }\n`;\n\n// checklist is a JSON scalar on the wire — model each item loosely and coerce\n// (mirrors OperationsMaintenanceDetailPage.tsx's checklist handling).\ninterface RawChecklistItem {\n task?: unknown;\n completed?: unknown;\n}\n\ninterface WorkOrderRecord {\n id: string;\n title: string;\n description?: string | null;\n type: string;\n status: string;\n priority: string;\n assetId?: string | null;\n assignedTo?: string | null;\n createdAt: string;\n updatedAt?: string | null;\n completedAt?: string | null;\n checklist?: RawChecklistItem[] | null;\n}\n\ninterface WorkOrderQueryResult {\n workOrder: WorkOrderRecord | null;\n}\n\nconst COMPLETE_WORK_ORDER_MUTATION = gql`\n mutation AssetHandlerCompleteWorkOrder($id: ID!, $input: CompleteWorkOrderInput!) {\n completeWorkOrder(id: $id, input: $input) {\n id\n status\n completedAt\n }\n }\n`;\n\nconst UPDATE_WORK_ORDER_MUTATION = gql`\n mutation AssetHandlerUpdateWorkOrder($id: ID!, $input: UpdateWorkOrderInput!) {\n updateWorkOrder(id: $id, input: $input) {\n id\n }\n }\n`;\n\nconst SET_WORK_ORDER_CHECKLIST_ITEM_MUTATION = gql`\n mutation AssetHandlerSetWorkOrderChecklistItem(\n $workOrderId: ID!\n $index: Int!\n $completed: Boolean!\n ) {\n setWorkOrderChecklistItem(workOrderId: $workOrderId, index: $index, completed: $completed) {\n id\n checklist\n }\n }\n`;\n\nconst WORK_ORDER_TYPES = ['CORRECTIVE', 'PREVENTIVE', 'PREDICTIVE', 'EMERGENCY'] as const;\nconst WORK_ORDER_STATUSES = [\n 'DRAFT',\n 'SCHEDULED',\n 'APPROVED',\n 'IN_PROGRESS',\n 'COMPLETED',\n 'CANCELLED',\n] as const;\nconst PRIORITIES = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] as const;\n\ntype Tone = 'neutral' | 'info' | 'warning' | 'success' | 'error';\n\nconst TONE_CLASS: Record<Tone, string> = {\n neutral: 'bg-bg-sunken text-text-secondary',\n info: 'bg-status-info-subtle text-status-info-text',\n warning: 'bg-status-warning-subtle text-status-warning-text',\n success: 'bg-status-success-subtle text-status-success-text',\n error: 'bg-status-error-subtle text-status-error-text',\n};\n\nconst PRIORITY_TONE: Record<string, Tone> = {\n critical: 'error',\n high: 'warning',\n medium: 'info',\n low: 'success',\n};\nconst STATUS_TONE: Record<string, Tone> = {\n draft: 'neutral',\n scheduled: 'neutral',\n approved: 'info',\n in_progress: 'info',\n completed: 'success',\n cancelled: 'error',\n};\n\nfunction Pill({ tone, children }: { tone: Tone; children: ReactNode }) {\n return (\n <span\n className={cn(\n 'inline-flex items-center whitespace-nowrap rounded-full px-2.5 py-0.5 text-xs font-medium capitalize',\n TONE_CLASS[tone]\n )}\n >\n {children}\n </span>\n );\n}\n\nconst LIFECYCLE = ['draft', 'scheduled', 'approved', 'in_progress', 'completed'] as const;\n\nfunction LifecycleStepper({ status }: { status: string }) {\n const cancelled = status === 'cancelled';\n const currentIndex = LIFECYCLE.indexOf(status as (typeof LIFECYCLE)[number]);\n return (\n <div className=\"flex items-center gap-1 overflow-x-auto pb-1\">\n {LIFECYCLE.map((step, i) => {\n const done = !cancelled && currentIndex >= 0 && i < currentIndex;\n const current = !cancelled && i === currentIndex;\n return (\n <div key={step} className=\"flex min-w-0 flex-1 items-center gap-1\">\n <div className=\"flex min-w-0 flex-col items-center gap-1.5\">\n <span\n className={cn(\n 'flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-[10px] font-bold',\n done && 'bg-status-success-bg text-status-success-text',\n current && 'bg-action-primary-bg text-action-primary-text',\n !done && !current && 'bg-bg-sunken text-text-muted'\n )}\n >\n {done ? <CheckCircle className=\"h-3.5 w-3.5\" /> : i + 1}\n </span>\n <span\n className={cn(\n 'whitespace-nowrap text-[11px] capitalize',\n current ? 'font-semibold text-text-primary' : 'text-text-secondary'\n )}\n >\n {step.replace(/_/g, ' ')}\n </span>\n </div>\n {i < LIFECYCLE.length - 1 ? (\n <span\n className={cn(\n 'mb-5 h-0.5 flex-1 rounded-full',\n done ? 'bg-status-success-bg' : 'bg-border-seam'\n )}\n />\n ) : null}\n </div>\n );\n })}\n {cancelled ? (\n <span className=\"ml-3 shrink-0 rounded-full bg-status-error-subtle px-2.5 py-0.5 text-xs font-medium text-status-error-text\">\n Cancelled\n </span>\n ) : null}\n </div>\n );\n}\n\nconst humanize = (value: string) =>\n value\n .toLowerCase()\n .replace(/_/g, ' ')\n .replace(/^\\w/, (c) => c.toUpperCase());\n\ninterface EditForm {\n title: string;\n description: string;\n type: string;\n priority: string;\n status: string;\n assignedTo: string;\n}\n\nexport function OperationsWorkOrderDetailPage() {\n const navigate = useAssetHandlerNavigate();\n const { workOrderId } = useParams<{ workOrderId: string }>();\n const { assets, refetchBootstrap } = useAssetHandlerStore();\n\n const { data, loading, refetch } = useQuery<WorkOrderQueryResult>(WORK_ORDER_QUERY, {\n variables: { id: workOrderId ?? '' },\n skip: !workOrderId,\n fetchPolicy: 'cache-and-network',\n });\n\n const [showComplete, setShowComplete] = useState(false);\n const [showEdit, setShowEdit] = useState(false);\n const [completeForm, setCompleteForm] = useState({ actualCost: '', notes: '' });\n const [editForm, setEditForm] = useState<EditForm | null>(null);\n const [pendingIndex, setPendingIndex] = useState<number | null>(null);\n\n const assetName = useMemo(() => {\n const byId = new Map(assets.map((a) => [a.id, a.name]));\n return (id: string | null | undefined) => (id ? (byId.get(id) ?? id) : null);\n }, [assets]);\n\n const [completeWorkOrder, { loading: completing }] = useMutation(COMPLETE_WORK_ORDER_MUTATION, {\n refetchQueries: ['AssetHandlerBootstrap'],\n onCompleted: () => {\n notify.success('Work order completed', 'The job has been signed off.');\n setShowComplete(false);\n void refetch();\n },\n onError: (error) => notify.error('Could not complete work order', error.message),\n });\n\n const [updateWorkOrder, { loading: updating }] = useMutation(UPDATE_WORK_ORDER_MUTATION, {\n refetchQueries: ['AssetHandlerBootstrap'],\n onCompleted: () => {\n notify.success('Work order updated', 'Your changes have been saved.');\n setShowEdit(false);\n void refetch();\n },\n onError: (error) => notify.error('Could not update work order', error.message),\n });\n\n const [setChecklistItem] = useMutation(SET_WORK_ORDER_CHECKLIST_ITEM_MUTATION, {\n onCompleted: () => {\n setPendingIndex(null);\n void refetch();\n refetchBootstrap();\n },\n onError: (error) => {\n setPendingIndex(null);\n notify.error('Could not update checklist', error.message);\n },\n });\n\n if (loading && !data) {\n return (\n <div className=\"space-y-3 p-6\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div key={i} className=\"h-10 rounded-md bg-bg-sunken motion-safe:animate-vc-shimmer\" />\n ))}\n </div>\n );\n }\n\n const raw = data?.workOrder;\n if (!raw) {\n return (\n <NotFoundState\n entityLabel=\"Work order\"\n description=\"This work order may have been completed or removed. Return to the operations hub to find it.\"\n backLabel=\"Back to operations\"\n onBack={() => navigate('/operations/operations-hub')}\n />\n );\n }\n\n const wo = {\n ...raw,\n status: raw.status.toLowerCase(),\n priority: raw.priority.toLowerCase(),\n type: raw.type.toLowerCase(),\n checklist: (raw.checklist ?? []).map((item) => ({\n task: String(item.task ?? 'Task'),\n completed: Boolean(item.completed),\n })),\n };\n const isClosed = wo.status === 'completed' || wo.status === 'cancelled';\n const linkedAsset = assetName(wo.assetId);\n const completedTasks = wo.checklist.filter((c) => c.completed).length;\n const totalTasks = wo.checklist.length;\n const checklistProgress = totalTasks === 0 ? 0 : Math.round((completedTasks / totalTasks) * 100);\n\n const toggleChecklistItem = (index: number, completed: boolean) => {\n setPendingIndex(index);\n void setChecklistItem({ variables: { workOrderId: wo.id, index, completed } });\n };\n\n const openEdit = () => {\n setEditForm({\n title: raw.title,\n description: raw.description ?? '',\n type: raw.type.toUpperCase(),\n priority: raw.priority.toUpperCase(),\n status: raw.status.toUpperCase(),\n assignedTo: raw.assignedTo ?? '',\n });\n setShowEdit(true);\n };\n\n const setEdit = (field: keyof EditForm, value: string) =>\n setEditForm((prev) => (prev ? { ...prev, [field]: value } : prev));\n\n const submitComplete = () => {\n const parsedCost = Number(completeForm.actualCost);\n void completeWorkOrder({\n variables: {\n id: wo.id,\n input: {\n actualCost:\n completeForm.actualCost.trim() !== '' && Number.isFinite(parsedCost)\n ? parsedCost\n : null,\n notes: completeForm.notes.trim() || null,\n },\n },\n });\n };\n\n const submitEdit = () => {\n if (!editForm) return;\n if (!editForm.title.trim()) {\n notify.warning('Title required', 'A work order must have a title.');\n return;\n }\n void updateWorkOrder({\n variables: {\n id: wo.id,\n input: {\n title: editForm.title.trim(),\n description: editForm.description.trim() || null,\n type: editForm.type,\n priority: editForm.priority,\n status: editForm.status,\n assignedTo: editForm.assignedTo.trim() || null,\n },\n },\n });\n };\n\n const detailRows: { label: string; value: ReactNode }[] = [\n {\n label: 'Asset',\n value: linkedAsset ? (\n <button\n type=\"button\"\n className=\"font-medium text-action-primary-text hover:underline\"\n onClick={() => navigate('/assets/' + wo.assetId)}\n >\n {linkedAsset}\n </button>\n ) : (\n <span className=\"text-text-secondary\">Unassigned</span>\n ),\n },\n { label: 'Type', value: <span className=\"capitalize\">{humanize(wo.type)}</span> },\n {\n label: 'Assigned technician',\n value: wo.assignedTo || <span className=\"text-text-secondary\">Unassigned</span>,\n },\n {\n label: 'Created',\n value: wo.createdAt ? new Date(wo.createdAt).toLocaleDateString() : '—',\n },\n {\n label: 'Completed',\n value: wo.completedAt ? new Date(wo.completedAt).toLocaleDateString() : '—',\n },\n ];\n\n return (\n <div className=\"space-y-6 p-4 sm:p-6\">\n {/* header */}\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-3\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Go back\"\n className=\"shrink-0\"\n onClick={() => navigate('/operations/operations-hub')}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div className=\"min-w-0\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-text-secondary\">\n Maintenance / Work Order Detail\n </p>\n <h1 className=\"truncate text-2xl font-bold\">\n <GradientText>{wo.title}</GradientText>\n </h1>\n <p className=\"mt-0.5 font-mono text-xs text-text-secondary\">{wo.id}</p>\n </div>\n </div>\n <div className=\"flex w-full items-center gap-2 sm:w-auto\">\n <Button size=\"sm\" variant=\"outline\" className=\"flex-1 sm:flex-none\" onClick={openEdit}>\n <Pencil className=\"mr-2 h-4 w-4\" />\n Edit\n </Button>\n {!isClosed ? (\n <Button size=\"sm\" className=\"flex-1 sm:flex-none\" onClick={() => setShowComplete(true)}>\n <CheckCircle className=\"mr-2 h-4 w-4\" />\n Complete\n </Button>\n ) : null}\n </div>\n </div>\n\n {/* status hero strip */}\n <ChartCard title=\"Status\">\n <div className=\"flex flex-wrap items-center gap-x-8 gap-y-4\">\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Priority</p>\n <div className=\"mt-1\">\n <Pill tone={PRIORITY_TONE[wo.priority] ?? 'neutral'}>{wo.priority}</Pill>\n </div>\n </div>\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Status</p>\n <div className=\"mt-1\">\n <Pill tone={STATUS_TONE[wo.status] ?? 'neutral'}>{wo.status.replace(/_/g, ' ')}</Pill>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <User className=\"h-4 w-4 text-text-muted\" />\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Technician</p>\n <p className=\"mt-0.5 text-sm font-medium text-text-primary\">\n {wo.assignedTo || 'Unassigned'}\n </p>\n </div>\n </div>\n {linkedAsset ? (\n <div className=\"flex items-center gap-2\">\n <Package className=\"h-4 w-4 text-text-muted\" />\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Asset</p>\n <button\n type=\"button\"\n className=\"mt-0.5 text-sm font-medium text-action-primary-text hover:underline\"\n onClick={() => navigate('/assets/' + wo.assetId)}\n >\n {linkedAsset}\n </button>\n </div>\n </div>\n ) : null}\n </div>\n <div className=\"mt-5 border-t border-border-seam pt-4\">\n <LifecycleStepper status={wo.status} />\n </div>\n </ChartCard>\n\n <div className=\"grid gap-6 lg:grid-cols-3\">\n {/* main column */}\n <div className=\"space-y-6 lg:col-span-2\">\n <ChartCard title=\"Details\" icon={Wrench}>\n <div>\n <h4 className=\"text-xs font-semibold uppercase tracking-wide text-text-secondary\">\n Description\n </h4>\n <p className=\"mt-1 text-sm text-text-primary\">{wo.description || '—'}</p>\n </div>\n <dl className=\"mt-4 divide-y divide-border-seam text-sm\">\n {detailRows.map((row) => (\n <div\n key={row.label}\n className=\"flex flex-col gap-0.5 py-2.5 sm:flex-row sm:items-center sm:justify-between\"\n >\n <dt className=\"text-text-secondary\">{row.label}</dt>\n <dd className=\"font-medium text-text-primary sm:text-right\">{row.value}</dd>\n </div>\n ))}\n </dl>\n </ChartCard>\n\n <ChartCard title={`Checklist (${completedTasks}/${totalTasks})`}>\n {totalTasks === 0 ? (\n <p className=\"text-sm text-text-secondary\">No checklist items for this job.</p>\n ) : (\n <>\n <div className=\"mb-3 h-2 overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-full rounded-full bg-action-primary-bg transition-all\"\n style={{ width: `${checklistProgress}%` }}\n />\n </div>\n <div className=\"space-y-2\">\n {wo.checklist.map((item, i) => (\n <label\n key={i}\n className=\"flex cursor-pointer items-center gap-3 rounded border border-border-seam p-2.5\"\n >\n <input\n type=\"checkbox\"\n className=\"h-4 w-4 accent-action-primary-bg\"\n checked={item.completed}\n disabled={pendingIndex === i}\n onChange={(e) => toggleChecklistItem(i, e.target.checked)}\n />\n <span\n className={cn(\n 'text-sm',\n item.completed && 'text-text-secondary line-through'\n )}\n >\n {item.task}\n </span>\n {pendingIndex === i ? (\n <Loader2 className=\"ml-auto h-3.5 w-3.5 animate-spin text-text-secondary\" />\n ) : null}\n </label>\n ))}\n </div>\n </>\n )}\n </ChartCard>\n\n <PagePurpose>\n The full brief for a single work order: what needs doing, on which asset and by whom.\n Track the job from open to complete and keep the asset's maintenance history\n accurate.\n </PagePurpose>\n </div>\n\n {/* persistent context rail */}\n <div className=\"space-y-6\">\n <AttachmentsPanel entityType=\"assethandler-work-order\" entityId={wo.id} />\n <CommentsPanel entityType=\"assethandler-work-order\" entityId={wo.id} />\n <ActivityTimeline resourceId={wo.id} />\n </div>\n </div>\n\n {/* Complete dialog */}\n <ResponsiveDialog open={showComplete} onOpenChange={setShowComplete}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Complete work order</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Record the final cost and any closing notes. This marks the work order as completed.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label>Actual Cost</Label>\n <Input\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n placeholder=\"e.g., 750\"\n value={completeForm.actualCost}\n onChange={(e) =>\n setCompleteForm((prev) => ({ ...prev, actualCost: e.target.value }))\n }\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Notes</Label>\n <Textarea\n placeholder=\"What was done to close this out?\"\n value={completeForm.notes}\n onChange={(e) => setCompleteForm((prev) => ({ ...prev, notes: e.target.value }))}\n rows={3}\n />\n </div>\n </div>\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setShowComplete(false)} disabled={completing}>\n Cancel\n </Button>\n <Button onClick={submitComplete} disabled={completing}>\n {completing ? <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" /> : null}\n {completing ? 'Completing…' : 'Complete work order'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Edit dialog */}\n <ResponsiveDialog open={showEdit} onOpenChange={setShowEdit}>\n <ResponsiveDialogContent className=\"max-h-[85vh] overflow-y-auto sm:max-w-xl\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Edit work order</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Update the work order's details and status.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n {editForm ? (\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label>Title</Label>\n <Input value={editForm.title} onChange={(e) => setEdit('title', e.target.value)} />\n </div>\n <div className=\"space-y-2\">\n <Label>Description</Label>\n <Textarea\n value={editForm.description}\n onChange={(e) => setEdit('description', e.target.value)}\n rows={2}\n />\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label>Type</Label>\n <Select value={editForm.type} onValueChange={(v) => setEdit('type', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {WORK_ORDER_TYPES.map((t) => (\n <SelectItem key={t} value={t}>\n {humanize(t)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>Priority</Label>\n <Select value={editForm.priority} onValueChange={(v) => setEdit('priority', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {PRIORITIES.map((p) => (\n <SelectItem key={p} value={p}>\n {humanize(p)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>Status</Label>\n <Select value={editForm.status} onValueChange={(v) => setEdit('status', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {WORK_ORDER_STATUSES.map((s) => (\n <SelectItem key={s} value={s}>\n {humanize(s)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label>Assigned To</Label>\n <Input\n value={editForm.assignedTo}\n onChange={(e) => setEdit('assignedTo', e.target.value)}\n />\n </div>\n </div>\n ) : null}\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setShowEdit(false)} disabled={updating}>\n Cancel\n </Button>\n <Button onClick={submitEdit} disabled={updating}>\n {updating ? <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" /> : null}\n {updating ? 'Saving…' : 'Save changes'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { ListEmptyState } from '../assethandler/components/ListEmptyState';
|
|
3
|
+
|
|
4
|
+
declare const meta: Meta<typeof ListEmptyState>;
|
|
5
|
+
export default meta;
|
|
6
|
+
type Story = StoryObj<typeof meta>;
|
|
7
|
+
export declare const Default: Story;
|
|
8
|
+
export declare const WithAction: Story;
|
|
9
|
+
export declare const CustomDescription: Story;
|
|
10
|
+
//# sourceMappingURL=ListEmptyState.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ListEmptyState.stories.d.ts","sourceRoot":"","sources":["../../src/stories/ListEmptyState.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAE3E,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,cAAc,CAMrC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAUxB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAM/B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { SectionHeader } from '../assethandler/components/SectionHeader';
|
|
3
|
+
|
|
4
|
+
declare const meta: Meta<typeof SectionHeader>;
|
|
5
|
+
export default meta;
|
|
6
|
+
type Story = StoryObj<typeof meta>;
|
|
7
|
+
export declare const Default: Story;
|
|
8
|
+
export declare const WithIconAndActions: Story;
|
|
9
|
+
export declare const Hero: Story;
|
|
10
|
+
//# sourceMappingURL=SectionHeader.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SectionHeader.stories.d.ts","sourceRoot":"","sources":["../../src/stories/SectionHeader.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAEzE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,aAAa,CAMpC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAYhC,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,KAMlB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { StatTile } from '../assethandler/components/StatTile';
|
|
3
|
+
|
|
4
|
+
declare const meta: Meta<typeof StatTile>;
|
|
5
|
+
export default meta;
|
|
6
|
+
type Story = StoryObj<typeof meta>;
|
|
7
|
+
export declare const Default: Story;
|
|
8
|
+
export declare const WithTrend: Story;
|
|
9
|
+
export declare const HeroWithSpark: Story;
|
|
10
|
+
//# sourceMappingURL=StatTile.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatTile.stories.d.ts","sourceRoot":"","sources":["../../src/stories/StatTile.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAE/D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,QAAQ,CAM/B,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAW3B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageContext.d.ts","sourceRoot":"","sources":["../../src/utils/pageContext.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,UAAU,wBAAwB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAG1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IAGpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,IAAI,WAAW,CAoB/C;
|
|
1
|
+
{"version":3,"file":"pageContext.d.ts","sourceRoot":"","sources":["../../src/utils/pageContext.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,UAAU,wBAAwB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAG1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IAGpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,IAAI,WAAW,CAoB/C;AA4BD,wBAAgB,sCAAsC,CACpD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,wBAAwB,CA2D1B"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
//#region src/utils/pageContext.ts
|
|
2
2
|
function e() {
|
|
3
|
-
let e = window.location.href, t = window.location.pathname.split("/").filter(Boolean).slice(0, 3).join("/") || "home",
|
|
3
|
+
let e = window.location.href, t = window.location.pathname.split("/").filter(Boolean).slice(0, 3).join("/") || "home", n = i(window.location.pathname, window.location.search);
|
|
4
4
|
return {
|
|
5
5
|
currentUrl: e,
|
|
6
6
|
currentPage: t,
|
|
7
|
-
entityType:
|
|
8
|
-
entityId:
|
|
7
|
+
entityType: n.entityType,
|
|
8
|
+
entityId: n.entityId,
|
|
9
9
|
platform: "assethandler",
|
|
10
10
|
version: "2026.402.1",
|
|
11
11
|
viewportSize: `${window.innerWidth}x${window.innerHeight}`,
|
|
@@ -16,9 +16,17 @@ function e() {
|
|
|
16
16
|
function t(e, t) {
|
|
17
17
|
return t.match(e);
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
var n = "/assethandler";
|
|
20
|
+
function r(e) {
|
|
21
|
+
return e === n ? "/" : e.startsWith(`${n}/`) ? e.slice(13) || "/" : e;
|
|
22
|
+
}
|
|
23
|
+
function i(e, n) {
|
|
24
|
+
let i = r(e), a = new URLSearchParams(n);
|
|
25
|
+
if (i === "/assets/asset-check-in-out") return {
|
|
26
|
+
entityType: "ASSETHANDLER_ASSET_ASSIGNMENT",
|
|
27
|
+
metadata: { routePattern: i }
|
|
28
|
+
};
|
|
29
|
+
for (let [e, n] of [
|
|
22
30
|
[/^\/assets\/([^/]+)$/, "ASSETHANDLER_ASSET"],
|
|
23
31
|
[/^\/itil\/incidents\/([^/]+)$/, "ASSETHANDLER_INCIDENT"],
|
|
24
32
|
[/^\/itil\/changes\/([^/]+)$/, "ASSETHANDLER_CHANGE"],
|
|
@@ -34,23 +42,23 @@ function n(e, n) {
|
|
|
34
42
|
[/^\/advanced\/discovery-jobs\/([^/]+)$/, "ASSETHANDLER_DISCOVERY_JOB"],
|
|
35
43
|
[/^\/advanced\/cmdb-browser\/([^/]+)$/, "ASSETHANDLER_CMDB_ITEM"]
|
|
36
44
|
]) {
|
|
37
|
-
let
|
|
38
|
-
if (
|
|
39
|
-
entityType:
|
|
40
|
-
entityId:
|
|
41
|
-
metadata: { routePattern:
|
|
45
|
+
let r = t(e, i);
|
|
46
|
+
if (r) return {
|
|
47
|
+
entityType: n,
|
|
48
|
+
entityId: r[1],
|
|
49
|
+
metadata: { routePattern: e.source }
|
|
42
50
|
};
|
|
43
51
|
}
|
|
44
|
-
let
|
|
45
|
-
let
|
|
46
|
-
return
|
|
52
|
+
let o = a.get("tab") ?? (() => {
|
|
53
|
+
let e = i.split("/").filter(Boolean);
|
|
54
|
+
return e.length > 2 ? e[e.length - 1] : void 0;
|
|
47
55
|
})();
|
|
48
56
|
return {
|
|
49
|
-
activeTab:
|
|
57
|
+
activeTab: o ?? void 0,
|
|
50
58
|
metadata: {
|
|
51
|
-
...
|
|
52
|
-
...
|
|
53
|
-
...
|
|
59
|
+
...o ? { activeTab: o } : {},
|
|
60
|
+
...a.get("selectedAssetId") ? { selectedAssetId: a.get("selectedAssetId") } : {},
|
|
61
|
+
...a.get("actionId") ? { actionId: a.get("actionId") } : {}
|
|
54
62
|
}
|
|
55
63
|
};
|
|
56
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageContext.js","names":[],"sources":["../../src/utils/pageContext.ts"],"sourcesContent":["/**\n * Page context gathering — captures the user's current browser context\n * to be sent alongside every assistant prompt for better AI awareness.\n */\n\ninterface ConversationContextShape {\n entityType?: string;\n entityId?: string;\n activeTab?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface PageContext {\n // `currentUrl` (NOT `activeUrl`) — must match the agent's allowed-context-key\n // contract, otherwise the agent filters it out.\n currentUrl: string;\n currentPage: string;\n // The entity the user is currently looking at, resolved from the route. Lets\n // the assistant act on \"this / current / here\" without asking for an id.\n entityType?: string;\n entityId?: string;\n platform: string;\n version: string;\n viewportSize: string;\n userAgent: string;\n timestamp: string;\n}\n\nexport function gatherPageContext(): PageContext {\n const url = window.location.href;\n const pathSegments = window.location.pathname.split('/').filter(Boolean);\n const currentPage = pathSegments.slice(0, 3).join('/') || 'home';\n const entity = resolveAssetHandlerConversationContext(\n window.location.pathname,\n window.location.search\n );\n\n return {\n currentUrl: url,\n currentPage,\n entityType: entity.entityType,\n entityId: entity.entityId,\n platform: 'assethandler',\n version: import.meta.env.VITE_APP_VERSION ?? '2026.402.1',\n viewportSize: `${window.innerWidth}x${window.innerHeight}`,\n userAgent: navigator.userAgent,\n timestamp: new Date().toISOString(),\n };\n}\n\nfunction matchPath(pattern: RegExp, pathname: string): RegExpMatchArray | null {\n return pathname.match(pattern);\n}\n\nexport function resolveAssetHandlerConversationContext(\n pathname: string,\n search: string\n): ConversationContextShape {\n const params = new URLSearchParams(search);\n const directMatches: Array<[RegExp, string]> = [\n [/^\\/assets\\/([^/]+)$/, 'ASSETHANDLER_ASSET'],\n [/^\\/itil\\/incidents\\/([^/]+)$/, 'ASSETHANDLER_INCIDENT'],\n [/^\\/itil\\/changes\\/([^/]+)$/, 'ASSETHANDLER_CHANGE'],\n [/^\\/itil\\/problems\\/([^/]+)$/, 'ASSETHANDLER_PROBLEM'],\n [/^\\/operations\\/work-orders\\/([^/]+)$/, 'ASSETHANDLER_WORK_ORDER'],\n [/^\\/operations\\/maintenance\\/([^/]+)$/, 'ASSETHANDLER_MAINTENANCE'],\n [/^\\/finance\\/budgets\\/([^/]+)$/, 'ASSETHANDLER_BUDGET'],\n [/^\\/finance\\/invoices\\/([^/]+)$/, 'ASSETHANDLER_INVOICE'],\n [/^\\/transactions\\/([^/]+)$/, 'ASSETHANDLER_TRANSACTION'],\n [/^\\/security\\/compliance\\/([^/]+)$/, 'ASSETHANDLER_COMPLIANCE_FRAMEWORK'],\n [/^\\/security\\/policies\\/([^/]+)$/, 'ASSETHANDLER_POLICY'],\n [/^\\/security\\/events\\/([^/]+)$/, 'ASSETHANDLER_SECURITY_EVENT'],\n [/^\\/advanced\\/discovery-jobs\\/([^/]+)$/, 'ASSETHANDLER_DISCOVERY_JOB'],\n [/^\\/advanced\\/cmdb-browser\\/([^/]+)$/, 'ASSETHANDLER_CMDB_ITEM'],\n ];\n\n for (const [pattern, entityType] of directMatches) {\n const match = matchPath(pattern,
|
|
1
|
+
{"version":3,"file":"pageContext.js","names":[],"sources":["../../src/utils/pageContext.ts"],"sourcesContent":["/**\n * Page context gathering — captures the user's current browser context\n * to be sent alongside every assistant prompt for better AI awareness.\n */\n\ninterface ConversationContextShape {\n entityType?: string;\n entityId?: string;\n activeTab?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface PageContext {\n // `currentUrl` (NOT `activeUrl`) — must match the agent's allowed-context-key\n // contract, otherwise the agent filters it out.\n currentUrl: string;\n currentPage: string;\n // The entity the user is currently looking at, resolved from the route. Lets\n // the assistant act on \"this / current / here\" without asking for an id.\n entityType?: string;\n entityId?: string;\n platform: string;\n version: string;\n viewportSize: string;\n userAgent: string;\n timestamp: string;\n}\n\nexport function gatherPageContext(): PageContext {\n const url = window.location.href;\n const pathSegments = window.location.pathname.split('/').filter(Boolean);\n const currentPage = pathSegments.slice(0, 3).join('/') || 'home';\n const entity = resolveAssetHandlerConversationContext(\n window.location.pathname,\n window.location.search\n );\n\n return {\n currentUrl: url,\n currentPage,\n entityType: entity.entityType,\n entityId: entity.entityId,\n platform: 'assethandler',\n version: import.meta.env.VITE_APP_VERSION ?? '2026.402.1',\n viewportSize: `${window.innerWidth}x${window.innerHeight}`,\n userAgent: navigator.userAgent,\n timestamp: new Date().toISOString(),\n };\n}\n\nfunction matchPath(pattern: RegExp, pathname: string): RegExpMatchArray | null {\n return pathname.match(pattern);\n}\n\n/**\n * The host app shell (assethandler-app/src/routes/AppRoutes.tsx, `path=\"/assethandler/*\"`\n * + `basePath=\"/assethandler\"`) and the standalone dev harness (src/dev/main.tsx) both\n * mount this MFE at this fixed prefix. The route-matching table below is written against\n * the MFE-relative path (e.g. `/assets/:id`), so the prefix must be stripped from\n * `window.location.pathname` (e.g. `/assethandler/assets/:id`) before matching —\n * otherwise none of the patterns can ever match in the shipped app (BOFF-3748).\n */\nconst MOUNT_PREFIX = '/assethandler';\n\nfunction stripMountPrefix(pathname: string): string {\n if (pathname === MOUNT_PREFIX) {\n return '/';\n }\n if (pathname.startsWith(`${MOUNT_PREFIX}/`)) {\n return pathname.slice(MOUNT_PREFIX.length) || '/';\n }\n // Already relative (e.g. called directly with an MFE-relative path in tests) —\n // pass through unchanged rather than mis-stripping an unrelated path.\n return pathname;\n}\n\nexport function resolveAssetHandlerConversationContext(\n pathname: string,\n search: string\n): ConversationContextShape {\n const relativePath = stripMountPrefix(pathname);\n const params = new URLSearchParams(search);\n\n // Asset check-in/out is a workflow page, not an id-keyed detail route (see\n // AssetHandlerRoutes.tsx `assets/asset-check-in-out`), so it can't join the\n // id-capturing table below — map it directly instead.\n if (relativePath === '/assets/asset-check-in-out') {\n return {\n entityType: 'ASSETHANDLER_ASSET_ASSIGNMENT',\n metadata: { routePattern: relativePath },\n };\n }\n\n const directMatches: Array<[RegExp, string]> = [\n [/^\\/assets\\/([^/]+)$/, 'ASSETHANDLER_ASSET'],\n [/^\\/itil\\/incidents\\/([^/]+)$/, 'ASSETHANDLER_INCIDENT'],\n [/^\\/itil\\/changes\\/([^/]+)$/, 'ASSETHANDLER_CHANGE'],\n [/^\\/itil\\/problems\\/([^/]+)$/, 'ASSETHANDLER_PROBLEM'],\n [/^\\/operations\\/work-orders\\/([^/]+)$/, 'ASSETHANDLER_WORK_ORDER'],\n [/^\\/operations\\/maintenance\\/([^/]+)$/, 'ASSETHANDLER_MAINTENANCE'],\n [/^\\/finance\\/budgets\\/([^/]+)$/, 'ASSETHANDLER_BUDGET'],\n [/^\\/finance\\/invoices\\/([^/]+)$/, 'ASSETHANDLER_INVOICE'],\n [/^\\/transactions\\/([^/]+)$/, 'ASSETHANDLER_TRANSACTION'],\n [/^\\/security\\/compliance\\/([^/]+)$/, 'ASSETHANDLER_COMPLIANCE_FRAMEWORK'],\n [/^\\/security\\/policies\\/([^/]+)$/, 'ASSETHANDLER_POLICY'],\n [/^\\/security\\/events\\/([^/]+)$/, 'ASSETHANDLER_SECURITY_EVENT'],\n [/^\\/advanced\\/discovery-jobs\\/([^/]+)$/, 'ASSETHANDLER_DISCOVERY_JOB'],\n [/^\\/advanced\\/cmdb-browser\\/([^/]+)$/, 'ASSETHANDLER_CMDB_ITEM'],\n ];\n\n for (const [pattern, entityType] of directMatches) {\n const match = matchPath(pattern, relativePath);\n if (match) {\n return {\n entityType,\n entityId: match[1],\n metadata: {\n routePattern: pattern.source,\n },\n };\n }\n }\n\n const activeTab =\n params.get('tab') ??\n (() => {\n const segments = relativePath.split('/').filter(Boolean);\n return segments.length > 2 ? segments[segments.length - 1] : undefined;\n })();\n\n return {\n activeTab: activeTab ?? undefined,\n metadata: {\n ...(activeTab ? { activeTab } : {}),\n ...(params.get('selectedAssetId') ? { selectedAssetId: params.get('selectedAssetId') } : {}),\n ...(params.get('actionId') ? { actionId: params.get('actionId') } : {}),\n },\n };\n}\n"],"mappings":";AA4BA,SAAgB,IAAiC;CAC/C,IAAM,IAAM,OAAO,SAAS,MAEtB,IADe,OAAO,SAAS,SAAS,MAAM,IAAI,CAAC,OAAO,QAAQ,CACvC,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,IAAI,QACpD,IAAS,EACb,OAAO,SAAS,UAChB,OAAO,SAAS,OACjB;AAED,QAAO;EACL,YAAY;EACZ;EACA,YAAY,EAAO;EACnB,UAAU,EAAO;EACjB,UAAU;EACV,SAA6C;EAC7C,cAAc,GAAG,OAAO,WAAW,GAAG,OAAO;EAC7C,WAAW,UAAU;EACrB,4BAAW,IAAI,MAAM,EAAC,aAAa;EACpC;;AAGH,SAAS,EAAU,GAAiB,GAA2C;AAC7E,QAAO,EAAS,MAAM,EAAQ;;AAWhC,IAAM,IAAe;AAErB,SAAS,EAAiB,GAA0B;AASlD,QARI,MAAa,IACR,MAEL,EAAS,WAAW,GAAG,EAAa,GAAG,GAClC,EAAS,MAAM,GAAoB,IAAI,MAIzC;;AAGT,SAAgB,EACd,GACA,GAC0B;CAC1B,IAAM,IAAe,EAAiB,EAAS,EACzC,IAAS,IAAI,gBAAgB,EAAO;AAK1C,KAAI,MAAiB,6BACnB,QAAO;EACL,YAAY;EACZ,UAAU,EAAE,cAAc,GAAc;EACzC;AAoBH,MAAK,IAAM,CAAC,GAAS,MAjB0B;EAC7C,CAAC,uBAAuB,qBAAqB;EAC7C,CAAC,gCAAgC,wBAAwB;EACzD,CAAC,8BAA8B,sBAAsB;EACrD,CAAC,+BAA+B,uBAAuB;EACvD,CAAC,wCAAwC,0BAA0B;EACnE,CAAC,wCAAwC,2BAA2B;EACpE,CAAC,iCAAiC,sBAAsB;EACxD,CAAC,kCAAkC,uBAAuB;EAC1D,CAAC,6BAA6B,2BAA2B;EACzD,CAAC,qCAAqC,oCAAoC;EAC1E,CAAC,mCAAmC,sBAAsB;EAC1D,CAAC,iCAAiC,8BAA8B;EAChE,CAAC,yCAAyC,6BAA6B;EACvE,CAAC,uCAAuC,yBAAyB;EAClE,EAEkD;EACjD,IAAM,IAAQ,EAAU,GAAS,EAAa;AAC9C,MAAI,EACF,QAAO;GACL;GACA,UAAU,EAAM;GAChB,UAAU,EACR,cAAc,EAAQ,QACvB;GACF;;CAIL,IAAM,IACJ,EAAO,IAAI,MAAM,WACV;EACL,IAAM,IAAW,EAAa,MAAM,IAAI,CAAC,OAAO,QAAQ;AACxD,SAAO,EAAS,SAAS,IAAI,EAAS,EAAS,SAAS,KAAK,KAAA;KAC3D;AAEN,QAAO;EACL,WAAW,KAAa,KAAA;EACxB,UAAU;GACR,GAAI,IAAY,EAAE,cAAW,GAAG,EAAE;GAClC,GAAI,EAAO,IAAI,kBAAkB,GAAG,EAAE,iBAAiB,EAAO,IAAI,kBAAkB,EAAE,GAAG,EAAE;GAC3F,GAAI,EAAO,IAAI,WAAW,GAAG,EAAE,UAAU,EAAO,IAAI,WAAW,EAAE,GAAG,EAAE;GACvE;EACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-assethandler",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.719.1",
|
|
4
4
|
"description": "Burdenoff AssetHandler Microfrontend",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -33,14 +33,18 @@
|
|
|
33
33
|
"lint:sanity": "if [ \"${CI:-}\" = \"true\" ]; then bun run lint; else bun run lint -- --cache --cache-location .eslintcache; fi",
|
|
34
34
|
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
35
35
|
"type:check": "tsc --noEmit",
|
|
36
|
-
"
|
|
36
|
+
"test": "bun test",
|
|
37
|
+
"sanity": "bun run codegen && bun run lint:sanity && bun run format && bun run type:check && bun run test && bun run build",
|
|
37
38
|
"codegen:all": "bun run schema:pull && bun run codegen",
|
|
38
39
|
"switch:status": "bun scripts/deps-mode.ts status",
|
|
39
40
|
"switch:remote": "bun scripts/deps-mode.ts remote",
|
|
40
41
|
"switch:local": "bun scripts/deps-mode.ts local",
|
|
41
42
|
"switch:check": "bun scripts/deps-mode.ts check",
|
|
42
43
|
"prepare": "lefthook install || true",
|
|
43
|
-
"format:check": "prettier --check \"src/**/*.{ts,tsx}\""
|
|
44
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
|
|
45
|
+
"storybook": "storybook dev -p 6006",
|
|
46
|
+
"build-storybook": "storybook build",
|
|
47
|
+
"test:storybook": "test-storybook"
|
|
44
48
|
},
|
|
45
49
|
"dependencies": {
|
|
46
50
|
"@apollo/client": "^4.0.11",
|
|
@@ -69,6 +73,14 @@
|
|
|
69
73
|
"@graphql-inspector/cli": "^6.0.7",
|
|
70
74
|
"@types/react": "^19.0.2",
|
|
71
75
|
"@types/react-dom": "^19.0.2",
|
|
76
|
+
"@storybook/addon-essentials": "^8.6.0",
|
|
77
|
+
"@storybook/addon-interactions": "^8.6.0",
|
|
78
|
+
"@storybook/react": "^8.6.0",
|
|
79
|
+
"@storybook/react-vite": "^8.6.0",
|
|
80
|
+
"@storybook/test": "^8.6.0",
|
|
81
|
+
"@storybook/test-runner": "0.24.4",
|
|
82
|
+
"@tailwindcss/vite": "^4.3.2",
|
|
83
|
+
"@types/bun": "^1.3.9",
|
|
72
84
|
"@vitejs/plugin-react": "^4.3.4",
|
|
73
85
|
"autoprefixer": "^10.4.20",
|
|
74
86
|
"eslint": "^9.18.0",
|
|
@@ -78,6 +90,7 @@
|
|
|
78
90
|
"lefthook": "^2.1.1",
|
|
79
91
|
"postcss": "^8.4.49",
|
|
80
92
|
"prettier": "^3.4.2",
|
|
93
|
+
"storybook": "^8.6.0",
|
|
81
94
|
"tailwindcss": "^4.0.0",
|
|
82
95
|
"typescript": "^5.9.0",
|
|
83
96
|
"typescript-eslint": "^8.54.0",
|