mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-07 09:19:19 +00:00
fix(work-orders): split status cell to satisfy max-lines-per-function
This commit is contained in:
parent
6b415f732c
commit
ccfb3d9e6d
1 changed files with 85 additions and 88 deletions
|
|
@ -1,46 +1,28 @@
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
import { AlertTriangle, Check } from "lucide-react";
|
import { AlertTriangle, Check } from "lucide-react";
|
||||||
|
|
||||||
import { Popover } from "@mui/material";
|
import { Popover } from "@mui/material";
|
||||||
import { Text } from "@/components/ui/text";
|
import { Text } from "@/components/ui/text";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ALL_WIZARD_STATUSES,
|
ALL_WIZARD_STATUSES,
|
||||||
type WizardWOStatus,
|
type WizardWOStatus,
|
||||||
} from "@/domain/work-orders/types/work-order-wizard";
|
} from "@/domain/work-orders/types/work-order-wizard";
|
||||||
|
|
||||||
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
||||||
import {
|
import {
|
||||||
formatClosabilityMissingTitle,
|
formatClosabilityMissingTitle,
|
||||||
getClosabilityGaps,
|
getClosabilityGaps,
|
||||||
} from "@/domain/work-orders/utils/wo-closability";
|
} from "@/domain/work-orders/utils/wo-closability";
|
||||||
|
|
||||||
import { HoverChevron } from "./hover-chevron";
|
import { HoverChevron } from "./hover-chevron";
|
||||||
|
|
||||||
import { WoTableStatusLabel } from "./wo-table-status-label";
|
import { WoTableStatusLabel } from "./wo-table-status-label";
|
||||||
|
|
||||||
type StatusCellProps = {
|
type StatusCellProps = {
|
||||||
wo: WorkOrderTableRow;
|
wo: WorkOrderTableRow;
|
||||||
|
|
||||||
onChangeStatus: (status: WizardWOStatus) => void;
|
onChangeStatus: (status: WizardWOStatus) => void;
|
||||||
|
|
||||||
onOpenSlideOver: () => void;
|
onOpenSlideOver: () => void;
|
||||||
|
|
||||||
onPastDueAttempt?: () => void;
|
onPastDueAttempt?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function StatusCell({
|
function rowClosabilityGaps(wo: WorkOrderTableRow) {
|
||||||
wo,
|
return getClosabilityGaps({
|
||||||
|
|
||||||
onChangeStatus,
|
|
||||||
|
|
||||||
onOpenSlideOver,
|
|
||||||
|
|
||||||
onPastDueAttempt,
|
|
||||||
}: StatusCellProps) {
|
|
||||||
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
|
|
||||||
const closabilityGaps = getClosabilityGaps({
|
|
||||||
dispatcherId: wo.dispatcherId,
|
dispatcherId: wo.dispatcherId,
|
||||||
dispatcherName: wo.dispatcherName,
|
dispatcherName: wo.dispatcherName,
|
||||||
tech: wo.tech,
|
tech: wo.tech,
|
||||||
|
|
@ -53,73 +35,91 @@ export function StatusCell({
|
||||||
upliftSummary: wo.upliftSummary,
|
upliftSummary: wo.upliftSummary,
|
||||||
hasPendingUplift: wo.hasPendingUplift,
|
hasPendingUplift: wo.hasPendingUplift,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function PastDueStatusCell({
|
||||||
|
onOpenSlideOver,
|
||||||
|
onPastDueAttempt,
|
||||||
|
}: {
|
||||||
|
onOpenSlideOver: () => void;
|
||||||
|
onPastDueAttempt?: () => void;
|
||||||
|
}) {
|
||||||
|
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onPastDueAttempt?.();
|
||||||
|
setAnchorEl(e.currentTarget);
|
||||||
|
}}
|
||||||
|
title="This WO missed its deadline. Update the Due Date to unlock status updates."
|
||||||
|
className="group/cell flex w-full cursor-pointer items-center gap-1.5 whitespace-nowrap leading-none transition-opacity hover:opacity-80"
|
||||||
|
style={{ fontSize: 12.5, fontWeight: 600, color: "var(--status-pastdue-text)" }}
|
||||||
|
>
|
||||||
|
<span className="h-2 w-2 shrink-0 rounded-full bg-[#BE123C]" />
|
||||||
|
Past Due
|
||||||
|
<HoverChevron />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Popover
|
||||||
|
open={Boolean(anchorEl)}
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
onClose={() => setAnchorEl(null)}
|
||||||
|
anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
slotProps={{
|
||||||
|
paper: { className: "w-[264px] overflow-hidden rounded-lg border border-border p-0" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex items-start gap-2 p-3"
|
||||||
|
style={{ background: "var(--status-pending-bg)" }}
|
||||||
|
>
|
||||||
|
<AlertTriangle size={13} className="mt-0.5 shrink-0 text-[var(--warning)]" />
|
||||||
|
<div>
|
||||||
|
<Text
|
||||||
|
as="p"
|
||||||
|
style={{
|
||||||
|
fontSize: 11,
|
||||||
|
lineHeight: 1.375,
|
||||||
|
color: "var(--status-pending-text)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
This work order is past due. Update the Due Date before the status can be updated.
|
||||||
|
</Text>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onOpenSlideOver();
|
||||||
|
setAnchorEl(null);
|
||||||
|
}}
|
||||||
|
className="mt-2 block text-[11px] font-medium text-[var(--color-primary)]"
|
||||||
|
>
|
||||||
|
Update Due Date →
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Popover>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StatusCell({
|
||||||
|
wo,
|
||||||
|
onChangeStatus,
|
||||||
|
onOpenSlideOver,
|
||||||
|
onPastDueAttempt,
|
||||||
|
}: StatusCellProps) {
|
||||||
|
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
|
||||||
|
const closabilityGaps = rowClosabilityGaps(wo);
|
||||||
|
|
||||||
if (wo.isPastDue) {
|
if (wo.isPastDue) {
|
||||||
return (
|
return (
|
||||||
<>
|
<PastDueStatusCell onOpenSlideOver={onOpenSlideOver} onPastDueAttempt={onPastDueAttempt} />
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
onPastDueAttempt?.();
|
|
||||||
|
|
||||||
setAnchorEl(e.currentTarget);
|
|
||||||
}}
|
|
||||||
title="This WO missed its deadline. Update the Due Date to unlock status updates."
|
|
||||||
className="group/cell flex w-full cursor-pointer items-center gap-1.5 whitespace-nowrap leading-none transition-opacity hover:opacity-80"
|
|
||||||
style={{ fontSize: 12.5, fontWeight: 600, color: "var(--status-pastdue-text)" }}
|
|
||||||
>
|
|
||||||
<span className="h-2 w-2 shrink-0 rounded-full bg-[#BE123C]" />
|
|
||||||
Past Due
|
|
||||||
<HoverChevron />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<Popover
|
|
||||||
open={Boolean(anchorEl)}
|
|
||||||
anchorEl={anchorEl}
|
|
||||||
onClose={() => setAnchorEl(null)}
|
|
||||||
anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
|
|
||||||
onClick={(e) => e.stopPropagation()}
|
|
||||||
slotProps={{
|
|
||||||
paper: { className: "w-[264px] overflow-hidden rounded-lg border border-border p-0" },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="flex items-start gap-2 p-3"
|
|
||||||
style={{ background: "var(--status-pending-bg)" }}
|
|
||||||
>
|
|
||||||
<AlertTriangle size={13} className="mt-0.5 shrink-0 text-[var(--warning)]" />
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<Text
|
|
||||||
as="p"
|
|
||||||
style={{
|
|
||||||
fontSize: 11,
|
|
||||||
lineHeight: 1.375,
|
|
||||||
color: "var(--status-pending-text)",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
This work order is past due. Update the Due Date before the status can be updated.
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
onOpenSlideOver();
|
|
||||||
|
|
||||||
setAnchorEl(null);
|
|
||||||
}}
|
|
||||||
className="mt-2 block text-[11px] font-medium text-[var(--color-primary)]"
|
|
||||||
>
|
|
||||||
Update Due Date →
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Popover>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,7 +129,6 @@ export function StatusCell({
|
||||||
type="button"
|
type="button"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
setAnchorEl(e.currentTarget);
|
setAnchorEl(e.currentTarget);
|
||||||
}}
|
}}
|
||||||
className="group/cell flex w-full items-center gap-1 transition-opacity hover:opacity-80"
|
className="group/cell flex w-full items-center gap-1 transition-opacity hover:opacity-80"
|
||||||
|
|
@ -139,7 +138,6 @@ export function StatusCell({
|
||||||
) : (
|
) : (
|
||||||
<span className="text-[11px] text-[var(--color-text-muted)]">—</span>
|
<span className="text-[11px] text-[var(--color-text-muted)]">—</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<HoverChevron />
|
<HoverChevron />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
@ -177,8 +175,7 @@ export function StatusCell({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<WoTableStatusLabel status={status} />
|
<WoTableStatusLabel status={status} />
|
||||||
|
{Boolean(wo.status === status) && (
|
||||||
{wo.status === status && (
|
|
||||||
<Check size={10} className="ml-auto text-[var(--color-primary)]" />
|
<Check size={10} className="ml-auto text-[var(--color-primary)]" />
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue