mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 22:18:12 +00:00
- Added parameter to and for server-side free-text search on contract reference, company name, and booking details. - Introduced new validation errors in for container clashes and space issues when creating bookings. - Implemented paginated dropdown settings retrieval in . - Updated to fetch active yards using a new method that handles pagination. - Enhanced with a method to fetch all records by walking through pages. - Refactored to support filtering and pagination in schedule listings. - Improved to return a paginated list of facilities. - Updated UI components in and to utilize debounced search inputs for better performance. - Added alerts in to inform users about booking constraints related to splits and capacity. - Enhanced to display notifications for split bookings and capacity usage.
94 lines
3.2 KiB
TypeScript
94 lines
3.2 KiB
TypeScript
import { api as apiClient } from '../auth/http';
|
|
|
|
import { URL_CONSTANTS } from '@/constants/URLS';
|
|
import { ruleEngineService } from './ruleEngine/ruleEngine.service';
|
|
|
|
export type RouteStatus = 'AVAILABLE' | 'MAINTENANCE' | 'DAMAGED' | 'STOP_WORKING';
|
|
|
|
/** Frozen from yard countries: ET→DJ EXPORT, DJ→ET IMPORT, same country DOMESTIC (intercity, disabled). */
|
|
export type RouteDirection = 'IMPORT' | 'EXPORT' | 'DOMESTIC';
|
|
|
|
export interface YardRef {
|
|
id: string;
|
|
code: string;
|
|
label: string;
|
|
country?: string;
|
|
}
|
|
|
|
export interface RouteMilestone {
|
|
id: string;
|
|
routeId: string;
|
|
yardId: string;
|
|
sequenceNo: number;
|
|
distanceKm?: number | null;
|
|
yard?: YardRef | null;
|
|
}
|
|
|
|
export interface RouteRecord {
|
|
id: string;
|
|
status: RouteStatus;
|
|
direction?: RouteDirection;
|
|
originYardId: string;
|
|
destinationYardId: string;
|
|
originYard?: YardRef | null;
|
|
destinationYard?: YardRef | null;
|
|
milestones?: RouteMilestone[];
|
|
}
|
|
|
|
export interface SaveRoutePayload {
|
|
milestones: Array<{ yardId: string; distanceKm?: number }>;
|
|
status?: RouteStatus;
|
|
}
|
|
|
|
/**
|
|
* Human-readable route label: yard names, not yard codes. Staff read
|
|
* "Addis Ababa → Dire Dawa", not "ADDIS_ABABA → DIRE_DAWA". Falls back to the
|
|
* code only when a yard has no label.
|
|
*
|
|
* When milestones are present they ARE the full ordered corridor (origin first,
|
|
* destination last), so the label shows every stop:
|
|
* "Addis Ababa → Adama → Dire Dawa".
|
|
*/
|
|
export function formatRouteLabel(route: RouteRecord): string {
|
|
const stops = [...(route.milestones ?? [])]
|
|
.sort((a, b) => a.sequenceNo - b.sequenceNo)
|
|
.map((m) => m.yard?.label ?? m.yard?.code)
|
|
.filter((name): name is string => Boolean(name));
|
|
if (stops.length >= 2) return stops.join(' → ');
|
|
|
|
const origin =
|
|
route.originYard?.label ?? route.originYard?.code ?? 'Origin';
|
|
const dest =
|
|
route.destinationYard?.label ?? route.destinationYard?.code ?? 'Destination';
|
|
return `${origin} → ${dest}`;
|
|
}
|
|
|
|
export function totalRouteDistanceKm(route: RouteRecord): number {
|
|
return (route.milestones ?? []).reduce(
|
|
(sum, m) => sum + Number(m.distanceKm ?? 0),
|
|
0,
|
|
);
|
|
}
|
|
|
|
export const ROUTE_STATUS_OPTIONS: Array<{ value: RouteStatus; label: string }> = [
|
|
{ value: 'AVAILABLE', label: 'Available' },
|
|
{ value: 'MAINTENANCE', label: 'Maintenance' },
|
|
{ value: 'DAMAGED', label: 'Damaged' },
|
|
{ value: 'STOP_WORKING', label: 'Stop working' },
|
|
];
|
|
|
|
export const routesService = {
|
|
getAll: (params?: { status?: RouteStatus; search?: string }) =>
|
|
apiClient.get<RouteRecord[]>(URL_CONSTANTS.ROUTES.BASE, { params }),
|
|
getById: (id: string) => apiClient.get<RouteRecord>(URL_CONSTANTS.ROUTES.BY_ID(id)),
|
|
create: (data: SaveRoutePayload) => apiClient.post(URL_CONSTANTS.ROUTES.BASE, data),
|
|
update: (id: string, data: Partial<SaveRoutePayload>) =>
|
|
apiClient.patch(URL_CONSTANTS.ROUTES.BY_ID(id), data),
|
|
deactivate: (id: string) => apiClient.delete(URL_CONSTANTS.ROUTES.BY_ID(id)),
|
|
/** All active yards (page-walked — the yards list API caps pageSize at 100). */
|
|
getYards: async (): Promise<YardRef[]> => {
|
|
const rows = await ruleEngineService.listAll("yards", { isActive: true });
|
|
return rows as unknown as YardRef[];
|
|
},
|
|
};
|