mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-01 14:23:11 +00:00
Comment and mention items open the work order on the Comments tab with the comments they were raised for highlighted; a grouped assignment opens the dispatcher's own open queue; uplift decisions open the work order's uplifts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
92 lines
2.8 KiB
TypeScript
92 lines
2.8 KiB
TypeScript
import { WORK_ORDERS_ROUTE } from "@/domain/dashboard/utils/work-order-drilldown-links";
|
|
|
|
const WORK_ORDER_PARAM = "wo";
|
|
const TAB_PARAM = "tab";
|
|
const SINCE_PARAM = "since";
|
|
const FOCUS_PARAM = "focus";
|
|
const MENTIONS_FOCUS = "mentions";
|
|
const COMMENTS_FOCUS = "comments";
|
|
|
|
export const WORK_ORDER_DEEP_LINK_TABS = [
|
|
"info",
|
|
"comments",
|
|
"audit",
|
|
"completion",
|
|
"extras",
|
|
"uplifts",
|
|
] as const;
|
|
|
|
export type WorkOrderDeepLinkTab = (typeof WORK_ORDER_DEEP_LINK_TABS)[number];
|
|
|
|
/**
|
|
* The comments a notification was raised for: everything by someone else from `since` on,
|
|
* either the ones that mention the user or the ones that do not.
|
|
*/
|
|
export type CommentHighlight = {
|
|
since: string;
|
|
mentions: boolean;
|
|
};
|
|
|
|
export type WorkOrderDeepLink = {
|
|
workOrderId: string;
|
|
tab: WorkOrderDeepLinkTab;
|
|
highlight: CommentHighlight | null;
|
|
};
|
|
|
|
function isDeepLinkTab(value: string | null): value is WorkOrderDeepLinkTab {
|
|
return WORK_ORDER_DEEP_LINK_TABS.some((tab) => tab === value);
|
|
}
|
|
|
|
/**
|
|
* `/workorders?wo=<id>&tab=<tab>` opens that work order's slide-over on the given tab; `uplifts`
|
|
* opens its uplifts dialog. A Comments link can also carry the comments to highlight.
|
|
*/
|
|
export function workOrderDeepLinkUrl(
|
|
workOrderId: string | number,
|
|
tab?: string | null,
|
|
highlight?: CommentHighlight | null,
|
|
): string {
|
|
const search = new URLSearchParams({ [WORK_ORDER_PARAM]: String(workOrderId) });
|
|
if (isDeepLinkTab(tab ?? null)) {
|
|
search.set(TAB_PARAM, String(tab));
|
|
}
|
|
if (tab === "comments" && highlight != null) {
|
|
search.set(SINCE_PARAM, highlight.since);
|
|
search.set(FOCUS_PARAM, highlight.mentions ? MENTIONS_FOCUS : COMMENTS_FOCUS);
|
|
}
|
|
return `${WORK_ORDERS_ROUTE}?${search.toString()}`;
|
|
}
|
|
|
|
function parseHighlight(
|
|
params: URLSearchParams,
|
|
tab: WorkOrderDeepLinkTab,
|
|
): CommentHighlight | null {
|
|
const since = params.get(SINCE_PARAM) ?? "";
|
|
const focus = params.get(FOCUS_PARAM);
|
|
if (tab !== "comments" || Number.isNaN(Date.parse(since))) {
|
|
return null;
|
|
}
|
|
if (focus !== MENTIONS_FOCUS && focus !== COMMENTS_FOCUS) {
|
|
return null;
|
|
}
|
|
return { since, mentions: focus === MENTIONS_FOCUS };
|
|
}
|
|
|
|
export function parseWorkOrderDeepLink(params: URLSearchParams): WorkOrderDeepLink | null {
|
|
const workOrderId = (params.get(WORK_ORDER_PARAM) ?? "").trim();
|
|
if (!/^\d+$/.test(workOrderId)) {
|
|
return null;
|
|
}
|
|
const requested = params.get(TAB_PARAM);
|
|
const tab = isDeepLinkTab(requested) ? requested : "info";
|
|
return { workOrderId, tab, highlight: parseHighlight(params, tab) };
|
|
}
|
|
|
|
export function withoutWorkOrderDeepLink(params: URLSearchParams): URLSearchParams {
|
|
const next = new URLSearchParams(params);
|
|
next.delete(WORK_ORDER_PARAM);
|
|
next.delete(TAB_PARAM);
|
|
next.delete(SINCE_PARAM);
|
|
next.delete(FOCUS_PARAM);
|
|
return next;
|
|
}
|