mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 08:03:13 +00:00
/workorders?ids=101,205,318 opens the board on exactly those work orders through board/search's ids filter. The id set replaces every other drill-down filter, a chip reads "Showing N selected work orders" and clearing it returns to the weekly board. buildWorkOrderIdsHref builds the link for alerts and linked-work-order lists.
130 lines
4.4 KiB
TypeScript
130 lines
4.4 KiB
TypeScript
import type { CompletionDocFilter } from "@/domain/work-orders/types/work-order-advanced-filters";
|
|
import type { WorkOrderAdvancedFilters } from "@/domain/work-orders/types/work-order-advanced-filters";
|
|
import { EMPTY_ADVANCED_FILTERS } from "@/domain/work-orders/types/work-order-advanced-filters";
|
|
import { ALL_WIZARD_STATUSES, WO_TYPES } from "@/domain/work-orders/types/work-order-wizard";
|
|
import type { WizardWOStatus, WOType } from "@/domain/work-orders/types/work-order-wizard";
|
|
import type { UpliftFilterStatus } from "@/domain/work-orders/types/work-order-uplift-filter";
|
|
import { cloneAdvancedFilters } from "@/domain/work-orders/utils/advanced-filters-utils";
|
|
import { parseWorkOrderIdsParam } from "@/domain/work-orders/utils/work-order-ids-filter";
|
|
|
|
const ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
|
|
const COMPLETION_DOC_FILTERS: CompletionDocFilter[] = ["No", "Yes", "NN"];
|
|
|
|
// SH-348: the board region filter (backend#146) accepts these region names.
|
|
const BOARD_REGION_NAMES = ["East", "Central", "West", "California", "Unmapped/Other"];
|
|
|
|
const UPLIFT_FILTER_VALUES: UpliftFilterStatus[] = [
|
|
"pending",
|
|
"approved",
|
|
"auto_approved",
|
|
"rejected",
|
|
];
|
|
|
|
function parseList(raw: string | null): string[] {
|
|
if (!raw) {
|
|
return [];
|
|
}
|
|
|
|
return raw
|
|
.split(",")
|
|
.map((item) => item.trim())
|
|
.filter((item) => item !== "");
|
|
}
|
|
|
|
function parseStatuses(raw: string | null): WizardWOStatus[] {
|
|
const valid = new Set<string>(ALL_WIZARD_STATUSES);
|
|
return [...new Set(parseList(raw))].filter((status): status is WizardWOStatus =>
|
|
valid.has(status),
|
|
);
|
|
}
|
|
|
|
function parseTypes(raw: string | null): WOType[] {
|
|
const valid = new Set<string>(WO_TYPES);
|
|
return [...new Set(parseList(raw))].filter((type): type is WOType => valid.has(type));
|
|
}
|
|
|
|
function parseCompletionDocs(raw: string | null): CompletionDocFilter[] {
|
|
const valid = new Set<string>(COMPLETION_DOC_FILTERS);
|
|
return [...new Set(parseList(raw))].filter((doc): doc is CompletionDocFilter => valid.has(doc));
|
|
}
|
|
|
|
function parseRegions(raw: string | null): string[] {
|
|
const valid = new Set<string>(BOARD_REGION_NAMES);
|
|
return [...new Set(parseList(raw))].filter((region) => valid.has(region));
|
|
}
|
|
|
|
function parseUpliftStatuses(raw: string | null): UpliftFilterStatus[] {
|
|
const valid = new Set<string>(UPLIFT_FILTER_VALUES);
|
|
return [...new Set(parseList(raw))].filter((value): value is UpliftFilterStatus =>
|
|
valid.has(value),
|
|
);
|
|
}
|
|
|
|
export function parseDashboardDrilldownParams(
|
|
params: URLSearchParams,
|
|
): WorkOrderAdvancedFilters | null {
|
|
// An exact id set replaces every other filter: nothing else may hide one of those work orders.
|
|
const workOrderIds = parseWorkOrderIdsParam(params.get("ids"));
|
|
if (workOrderIds.length > 0) {
|
|
return { ...cloneAdvancedFilters(EMPTY_ADVANCED_FILTERS), workOrderIds: new Set(workOrderIds) };
|
|
}
|
|
|
|
const dateFrom = (params.get("dateFrom") ?? "").trim();
|
|
const dateTo = (params.get("dateTo") ?? "").trim();
|
|
const hasDateRange = ISO_DATE_PATTERN.test(dateFrom) && ISO_DATE_PATTERN.test(dateTo);
|
|
const avetaOnly = params.get("aveta") === "1";
|
|
const docs = parseCompletionDocs(params.get("docs"));
|
|
const statuses = parseStatuses(params.get("statuses"));
|
|
const types = parseTypes(params.get("types"));
|
|
const dispatchers = parseList(params.get("dispatchers"));
|
|
const regions = parseRegions(params.get("regions"));
|
|
const upliftStatuses = parseUpliftStatuses(params.get("upliftStatuses"));
|
|
const hasUplift = params.get("hasUplift") === "1";
|
|
|
|
const hasAny = [
|
|
hasDateRange,
|
|
avetaOnly,
|
|
docs.length,
|
|
statuses.length,
|
|
types.length,
|
|
dispatchers.length,
|
|
regions.length,
|
|
upliftStatuses.length,
|
|
hasUplift,
|
|
].some(Boolean);
|
|
|
|
if (!hasAny) {
|
|
return null;
|
|
}
|
|
|
|
const filters = cloneAdvancedFilters(EMPTY_ADVANCED_FILTERS);
|
|
|
|
if (hasDateRange) {
|
|
filters.dateRange = "custom";
|
|
filters.customFrom = dateFrom;
|
|
filters.customTo = dateTo;
|
|
}
|
|
filters.avetaOnly = avetaOnly;
|
|
filters.hasUplift = hasUplift || upliftStatuses.length > 0;
|
|
if (docs.length > 0) {
|
|
filters.docs = new Set(docs);
|
|
}
|
|
if (statuses.length > 0) {
|
|
filters.statuses = new Set(statuses);
|
|
}
|
|
if (types.length > 0) {
|
|
filters.types = new Set(types);
|
|
}
|
|
if (dispatchers.length > 0) {
|
|
filters.dispatchers = new Set(dispatchers);
|
|
}
|
|
if (regions.length > 0) {
|
|
filters.regions = new Set(regions);
|
|
}
|
|
if (upliftStatuses.length > 0) {
|
|
filters.upliftStatuses = new Set(upliftStatuses);
|
|
}
|
|
|
|
return filters;
|
|
}
|