mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-05 01:22:06 +00:00
Merge remote-tracking branch 'origin/feat/ab/sh-292-notification-center' into HEAD
# Conflicts: # src/app/(protected)/workorders/_hooks/use-work-orders-list-page.ts
This commit is contained in:
commit
ff1a946e74
2 changed files with 100 additions and 49 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import type { Dispatch, SetStateAction } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import type {
|
||||
WorkOrderTablePatch,
|
||||
|
|
@ -19,6 +20,8 @@ function isSlideOverInfoLocked(status: string | null | undefined): boolean {
|
|||
return isWorkOrderFullyLocked(status) || isWorkOrderCoreLocked(status);
|
||||
}
|
||||
|
||||
type StateSetter<T> = Dispatch<SetStateAction<T>>;
|
||||
|
||||
type UseSlideOverEditStateArgs = {
|
||||
row: WorkOrderTableRow | null;
|
||||
editMode: boolean;
|
||||
|
|
@ -33,6 +36,47 @@ type UseSlideOverEditStateArgs = {
|
|||
openRequestKey?: number;
|
||||
};
|
||||
|
||||
function useSlideOverInitialization({
|
||||
row,
|
||||
editMode,
|
||||
initialTab,
|
||||
setTab,
|
||||
setDraft,
|
||||
setBaseline,
|
||||
setEditing,
|
||||
setShowUnsaved,
|
||||
setUnsavedIntent,
|
||||
}: {
|
||||
row: WorkOrderTableRow | null;
|
||||
editMode: boolean;
|
||||
initialTab: SlideOverTab;
|
||||
setTab: (tab: SlideOverTab) => void;
|
||||
setDraft: StateSetter<WorkOrderTableRow | null>;
|
||||
setBaseline: StateSetter<WorkOrderTableRow | null>;
|
||||
setEditing: StateSetter<boolean>;
|
||||
setShowUnsaved: StateSetter<boolean>;
|
||||
setUnsavedIntent: StateSetter<"close" | "cancel-edit" | null>;
|
||||
}) {
|
||||
useEffect(() => {
|
||||
if (!row) {
|
||||
setDraft(null);
|
||||
setBaseline(null);
|
||||
setEditing(false);
|
||||
setShowUnsaved(false);
|
||||
setUnsavedIntent(null);
|
||||
return;
|
||||
}
|
||||
setDraft(row);
|
||||
setBaseline(row);
|
||||
setEditing(editMode && !isSlideOverInfoLocked(row.status));
|
||||
setTab(editMode ? "info" : initialTab);
|
||||
setShowUnsaved(false);
|
||||
setUnsavedIntent(null);
|
||||
// Intentionally identity-only: depending on `row` would absorb optimistic patches.
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps -- row.id / editMode gate
|
||||
}, [row?.id, editMode]);
|
||||
}
|
||||
|
||||
export function useSlideOverEditState({
|
||||
row,
|
||||
editMode,
|
||||
|
|
@ -53,24 +97,17 @@ export function useSlideOverEditState({
|
|||
|
||||
// Reset draft/baseline only when the opened WO identity or editMode intent changes —
|
||||
// not on every optimistic parent-row field update during a failed/in-flight save.
|
||||
useEffect(() => {
|
||||
if (!row) {
|
||||
setDraft(null);
|
||||
setBaseline(null);
|
||||
setEditing(false);
|
||||
setShowUnsaved(false);
|
||||
setUnsavedIntent(null);
|
||||
return;
|
||||
}
|
||||
setDraft(row);
|
||||
setBaseline(row);
|
||||
setEditing(editMode && !isSlideOverInfoLocked(row.status));
|
||||
setTab(editMode ? "info" : initialTab);
|
||||
setShowUnsaved(false);
|
||||
setUnsavedIntent(null);
|
||||
// Intentionally identity-only: depending on `row` would absorb optimistic patches.
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps -- row.id / editMode gate
|
||||
}, [row?.id, editMode]);
|
||||
useSlideOverInitialization({
|
||||
row,
|
||||
editMode,
|
||||
initialTab,
|
||||
setTab,
|
||||
setDraft,
|
||||
setBaseline,
|
||||
setEditing,
|
||||
setShowUnsaved,
|
||||
setUnsavedIntent,
|
||||
});
|
||||
|
||||
// Re-apply the requested tab on every open, including a second notification for the work order
|
||||
// already on screen (same row id) where the identity effect above does not re-run. Tab-only so
|
||||
|
|
@ -110,8 +147,7 @@ export function useSlideOverEditState({
|
|||
});
|
||||
}, [infoSource, editing, baseline]);
|
||||
|
||||
const activeDraft = draft ?? infoSource;
|
||||
const dirtyBaseline = baseline ?? infoSource;
|
||||
const [activeDraft, dirtyBaseline] = [draft ?? infoSource, baseline ?? infoSource];
|
||||
const isDirty = useMemo(() => {
|
||||
if (!dirtyBaseline || !activeDraft || !editing) return false;
|
||||
return isSlideOverDraftDirty(activeDraft, dirtyBaseline);
|
||||
|
|
|
|||
|
|
@ -19,40 +19,56 @@ import { guardDialogClose } from "@/lib/dialog-guard";
|
|||
import { useWorkOrdersListFilters } from "./use-work-orders-list-filters";
|
||||
import { useWorkOrdersTableData } from "./use-work-orders-table-data";
|
||||
|
||||
function useSlideOverState() {
|
||||
const [row, setRow] = useState<WorkOrderTableRow | null>(null);
|
||||
const [edit, setEdit] = useState(false);
|
||||
const [tab, setTab] = useState<SlideOverTab>("info");
|
||||
const [highlight, setHighlight] = useState<CommentHighlight | null>(null);
|
||||
function useSlideOverOpenState() {
|
||||
const [slideOverRow, setSlideOverRow] = useState<WorkOrderTableRow | null>(null);
|
||||
const [slideOverEdit, setSlideOverEdit] = useState(false);
|
||||
const [slideOverTab, setSlideOverTab] = useState<SlideOverTab>("info");
|
||||
const [slideOverHighlight, setSlideOverHighlight] = useState<CommentHighlight | null>(null);
|
||||
// Bumps on every open() so the slide-over re-applies tab/highlight even when a second
|
||||
// notification targets the work order already on screen (same row id).
|
||||
const [openRequestKey, setOpenRequestKey] = useState(0);
|
||||
const [slideOverOpenRequestKey, setSlideOverOpenRequestKey] = useState(0);
|
||||
|
||||
const open = (
|
||||
next: WorkOrderTableRow,
|
||||
nextEdit = false,
|
||||
nextTab: SlideOverTab = "info",
|
||||
nextHighlight: CommentHighlight | null = null,
|
||||
const handleOpenSlideOver = (
|
||||
row: WorkOrderTableRow,
|
||||
edit = false,
|
||||
tab: SlideOverTab = "info",
|
||||
highlight: CommentHighlight | null = null,
|
||||
) => {
|
||||
setRow(next);
|
||||
setEdit(nextEdit);
|
||||
setTab(nextTab);
|
||||
setHighlight(nextHighlight);
|
||||
setOpenRequestKey((key) => key + 1);
|
||||
setSlideOverRow(row);
|
||||
setSlideOverEdit(edit);
|
||||
setSlideOverTab(tab);
|
||||
setSlideOverHighlight(highlight);
|
||||
setSlideOverOpenRequestKey((key) => key + 1);
|
||||
};
|
||||
|
||||
const close = () => {
|
||||
setRow(null);
|
||||
setEdit(false);
|
||||
setHighlight(null);
|
||||
const handleCloseSlideOver = () => {
|
||||
setSlideOverRow(null);
|
||||
setSlideOverEdit(false);
|
||||
setSlideOverHighlight(null);
|
||||
};
|
||||
|
||||
return { row, edit, tab, highlight, openRequestKey, open, close };
|
||||
return {
|
||||
slideOverRow,
|
||||
slideOverEdit,
|
||||
slideOverTab,
|
||||
slideOverHighlight,
|
||||
slideOverOpenRequestKey,
|
||||
handleOpenSlideOver,
|
||||
handleCloseSlideOver,
|
||||
};
|
||||
}
|
||||
|
||||
export function useWorkOrdersListPage() {
|
||||
const [wizardOpen, setWizardOpen] = useState(false);
|
||||
const slideOver = useSlideOverState();
|
||||
const {
|
||||
slideOverRow,
|
||||
slideOverEdit,
|
||||
slideOverTab,
|
||||
slideOverHighlight,
|
||||
slideOverOpenRequestKey,
|
||||
handleOpenSlideOver,
|
||||
handleCloseSlideOver: closeSlideOverState,
|
||||
} = useSlideOverOpenState();
|
||||
const [confirmCancel, setConfirmCancel] = useState<WorkOrderTableRow | null>(null);
|
||||
const [confirmComplete, setConfirmComplete] = useState<WorkOrderTableRow | null>(null);
|
||||
const [docRow, setDocRow] = useState<WorkOrderTableRow | null>(null);
|
||||
|
|
@ -86,7 +102,6 @@ export function useWorkOrdersListPage() {
|
|||
[vendors],
|
||||
);
|
||||
|
||||
const slideOverRow = slideOver.row;
|
||||
const activeSlideOverRow = useMemo(() => {
|
||||
if (!slideOverRow) return null;
|
||||
return tableData.rows.find((row) => row.id === slideOverRow.id) ?? slideOverRow;
|
||||
|
|
@ -108,7 +123,7 @@ export function useWorkOrdersListPage() {
|
|||
}, [upliftsRow, tableData.rows]);
|
||||
|
||||
const handleCloseSlideOver = () => {
|
||||
slideOver.close();
|
||||
closeSlideOverState();
|
||||
tableData.setSelectedId(null);
|
||||
};
|
||||
|
||||
|
|
@ -156,10 +171,10 @@ export function useWorkOrdersListPage() {
|
|||
return {
|
||||
wizardOpen,
|
||||
setWizardOpen,
|
||||
slideOverEdit: slideOver.edit,
|
||||
slideOverTab: slideOver.tab,
|
||||
slideOverHighlight: slideOver.highlight,
|
||||
slideOverOpenRequestKey: slideOver.openRequestKey,
|
||||
slideOverEdit,
|
||||
slideOverTab,
|
||||
slideOverHighlight,
|
||||
slideOverOpenRequestKey,
|
||||
confirmCancel,
|
||||
setConfirmCancel,
|
||||
confirmComplete,
|
||||
|
|
@ -185,7 +200,7 @@ export function useWorkOrdersListPage() {
|
|||
activeDocRow,
|
||||
activeMediaRow,
|
||||
activeUpliftsRow,
|
||||
handleOpenSlideOver: slideOver.open,
|
||||
handleOpenSlideOver,
|
||||
handleCloseSlideOver,
|
||||
handleConfirmCancel,
|
||||
handleConfirmComplete,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue