shoc-frontend-new/src/domain/work-orders/utils/dashboard-drilldown-params.ts
Alexandre Brandizzi e052dcb37a feat(workorders): filter board to an exact work-order id set
/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.
2026-09-25 11:06:09 -03:00

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;
}