import { Freight } from "@edr/types"; import type { ColumnFormat, FormFieldDef } from "@/pages/ruleEngine/config/resources"; import { vehiclesConfig, VEHICLE_TYPE_OPTIONS, FUEL_TYPE_OPTIONS, VEHICLE_STATUS_OPTIONS } from "./vehicles"; import { driversConfig, DRIVER_STATUS_OPTIONS } from "./drivers"; // Re-export options for backward compatibility export { VEHICLE_TYPE_OPTIONS, FUEL_TYPE_OPTIONS, VEHICLE_STATUS_OPTIONS, DRIVER_STATUS_OPTIONS }; export type FleetResourceSlug = | "locomotives" | "trains" | "wagons" | "containers" | "cargoes" | "vehicles" | "drivers"; export const FLEET_SELECT_NONE = "__none__"; import type { WagonListFilters } from "@/services/wagon.service"; export type FleetListFilters = WagonListFilters; export type FleetDynamicOptions = | "wagonTypes" | "containerTypes" | "cargoTypes" | "wagons" | "containers" | "yards"; export interface FleetResourceColumn { id: string; header: string; accessorKey: string; format?: ColumnFormat | "statusBadge"; size?: number; } export interface FleetFormFieldDef extends FormFieldDef { dynamicOptions?: FleetDynamicOptions; noneOption?: boolean; } export interface FleetListFilterDef { key: "status" | "currentYardId" | "wagonTypeId" | "trainId"; label: string; options?: Array<{ value: string; label: string }>; allLabel?: string; dynamicOptions?: FleetDynamicOptions; } export interface FleetResourceConfig { slug: FleetResourceSlug; label: string; subtitle: string; basePath: string; addLabel: string; entityLabel: string; searchPlaceholder: string; supportsSearch: boolean; /** Server-side list filters (e.g. wagon status / readiness). */ listFilters?: FleetListFilterDef[]; columns: FleetResourceColumn[]; formFields: FleetFormFieldDef[]; emptyValues: Record; removeAction: "delete" | "decommission"; removeActionLabel?: string; removeConfirmMessage?: string; removeSuccessMessage?: string; detailPath?: string; cardTitleKey?: string; cardCodeKey?: string; cardSubtitleKey?: string; searchKeys: string[]; } export const FLEET_BASE_PATH_BY_SLUG: Record = { locomotives: "/dashboard/locomotives", trains: "/dashboard/trains", wagons: "/dashboard/wagons", containers: "/dashboard/containers", cargoes: "/dashboard/cargoes", vehicles: "/dashboard/vehicles", drivers: "/dashboard/drivers", }; const LOCOMOTIVE_TYPE_OPTIONS = [ { label: "Diesel", value: "DIESEL" }, { label: "Electric", value: "ELECTRIC" }, ]; const LOCOMOTIVE_STATUS_OPTIONS = [ { label: "Available", value: "AVAILABLE" }, { label: "Maintenance", value: "MAINTENANCE" }, { label: "Assigned", value: "ASSIGNED" }, { label: "Out of service", value: "OUT_OF_SERVICE" }, ]; const WAGON_STATUS_OPTIONS = [ { label: "Available", value: Freight.WagonStatus.Available }, { label: "Assigned", value: Freight.WagonStatus.Assigned }, { label: "Maintenance", value: Freight.WagonStatus.Maintenance }, { label: "Retired", value: Freight.WagonStatus.Retired }, ]; export const FLEET_RESOURCES: FleetResourceConfig[] = [ { slug: "locomotives", label: "Locomotives", subtitle: "Manage locomotive master data used by train scheduling and fleet operations", basePath: "/dashboard/locomotives", addLabel: "Add Locomotive", entityLabel: "Locomotive", searchPlaceholder: "Search locomotives…", supportsSearch: true, removeAction: "decommission", removeActionLabel: "Decommission", removeConfirmMessage: "Decommission this locomotive?", removeSuccessMessage: "Locomotive decommissioned", cardTitleKey: "name", cardCodeKey: "code", listFilters: [ { key: "status", label: "Status", allLabel: "All statuses", options: LOCOMOTIVE_STATUS_OPTIONS, }, { key: "currentYardId", label: "Current Yard", allLabel: "All yards", dynamicOptions: "yards", }, ], cardSubtitleKey: "currentYard", searchKeys: ["code", "name", "locomotiveType", "status", "currentYardId"], columns: [ { id: "code", header: "Code", accessorKey: "code", format: "code" }, { id: "name", header: "Name", accessorKey: "name" }, { id: "locomotiveType", header: "Type", accessorKey: "locomotiveType" }, { id: "currentYard", header: "Current Yard", accessorKey: "currentYard", format: "entityLabel" }, { id: "status", header: "Status", accessorKey: "status", format: "statusBadge" }, { id: "maxPullWeightTons", header: "Max pull (tons)", accessorKey: "maxPullWeightTons", format: "number" }, { id: "maxTrainLengthMeters", header: "Max length (m)", accessorKey: "maxTrainLengthMeters", format: "number" }, ], // Code is auto-generated server-side (LOCO-NNN) — omitted from the form. formFields: [ { name: "name", label: "Name", type: "text" }, { name: "locomotiveType", label: "Locomotive type", type: "select", required: true, options: LOCOMOTIVE_TYPE_OPTIONS }, { name: "status", label: "Status", type: "select", required: true, options: LOCOMOTIVE_STATUS_OPTIONS }, { name: "currentYardId", label: "Current Yard", type: "select", dynamicOptions: "yards" }, { name: "maxPullWeightTons", label: "Max pulling weight (tons)", type: "number", required: true }, { name: "maxTrainLengthMeters", label: "Max train length (meters)", type: "number", required: true }, { name: "powerKw", label: "Power (kW)", type: "number" }, { name: "tractionForceKn", label: "Traction force (kN)", type: "number" }, { name: "maxSpeedKmh", label: "Max speed (km/h)", type: "number" }, ], emptyValues: { name: "", locomotiveType: "DIESEL", status: "AVAILABLE", currentYardId: "", maxPullWeightTons: 2500, maxTrainLengthMeters: 760, powerKw: "", tractionForceKn: "", maxSpeedKmh: "", }, }, { slug: "trains", label: "Trains", subtitle: "Manage train master data independently from train scheduling", basePath: "/dashboard/trains", addLabel: "Add Train", entityLabel: "Train", searchPlaceholder: "Search trains…", supportsSearch: true, removeAction: "delete", detailPath: "/dashboard/trains/:id", cardTitleKey: "trainName", cardCodeKey: "code", cardSubtitleKey: "trainNumber", searchKeys: ["code", "trainNumber", "trainName", "status"], columns: [ { id: "code", header: "Code", accessorKey: "code", format: "code" }, { id: "trainNumber", header: "Number", accessorKey: "trainNumber" }, { id: "trainName", header: "Name", accessorKey: "trainName" }, { id: "capacityTons", header: "Capacity (tons)", accessorKey: "capacityTons", format: "number" }, { id: "status", header: "Status", accessorKey: "status", format: "statusBadge" }, ], formFields: [ { name: "code", label: "Code", type: "text", required: true }, { name: "capacityTons", label: "Capacity (tons)", type: "number", required: true }, { name: "trainNumber", label: "Train number", type: "text" }, { name: "trainName", label: "Train name", type: "text" }, { name: "locomotiveNumber", label: "Locomotive number", type: "text" }, { name: "status", label: "Status", type: "text" }, { name: "notes", label: "Notes", type: "textarea" }, { name: "remarks", label: "Remarks", type: "textarea" }, ], emptyValues: { code: "", capacityTons: 0, trainNumber: "", trainName: "", locomotiveNumber: "", status: "AVAILABLE", notes: "", remarks: "", }, }, { slug: "wagons", label: "Wagons", subtitle: "Manage wagon master data. Operational scheduling uses train schedules separately", basePath: "/dashboard/wagons", addLabel: "Add Wagon", entityLabel: "Wagon", searchPlaceholder: "Search wagons…", supportsSearch: true, removeAction: "delete", listFilters: [ { key: "status", label: "Status", allLabel: "All statuses", options: WAGON_STATUS_OPTIONS, }, { key: "currentYardId", label: "Current Yard", allLabel: "All yards", dynamicOptions: "yards", }, ], cardTitleKey: "wagonNumber", cardSubtitleKey: "currentYard", searchKeys: ["wagonNumber", "wagonTypeId", "trainId", "status", "currentYardId"], columns: [ { id: "wagonNumber", header: "Number", accessorKey: "wagonNumber", format: "code" }, { id: "wagonTypeId", header: "Type", accessorKey: "wagonTypeId", format: "entityLabel" }, { id: "maxPayloadWeight", header: "Max payload", accessorKey: "maxPayloadWeight", format: "number" }, { id: "currentYard", header: "Current Yard", accessorKey: "currentYard", format: "entityLabel" }, { id: "status", header: "Status", accessorKey: "status", format: "statusBadge" }, ], formFields: [ { name: "wagonNumber", label: "Wagon number", type: "text", required: true }, { name: "wagonTypeId", label: "Wagon type", type: "select", required: true, dynamicOptions: "wagonTypes" }, { name: "tareWeight", label: "Tare weight", type: "number", required: true }, { name: "maxPayloadWeight", label: "Max payload weight", type: "number", required: true }, { name: "currentYardId", label: "Current Yard", type: "select", dynamicOptions: "yards" }, { name: "status", label: "Status", type: "select", required: true, options: WAGON_STATUS_OPTIONS }, { name: "notes", label: "Notes", type: "textarea" }, ], emptyValues: { wagonNumber: "", wagonTypeId: "", tareWeight: 0, maxPayloadWeight: 0, currentYardId: "", status: Freight.WagonStatus.Available, notes: "", }, }, { slug: "containers", label: "Containers", subtitle: "Manage container master data and wagon assignments", basePath: "/dashboard/containers", addLabel: "Add Container", entityLabel: "Container", searchPlaceholder: "Search containers…", supportsSearch: true, removeAction: "delete", cardTitleKey: "containerNumber", cardSubtitleKey: "status", searchKeys: ["containerNumber", "containerTypeId", "wagonId", "status"], columns: [ { id: "containerNumber", header: "Number", accessorKey: "containerNumber", format: "code" }, { id: "containerTypeId", header: "Type", accessorKey: "containerTypeId", format: "entityLabel" }, { id: "wagonId", header: "Wagon", accessorKey: "wagonId", format: "entityLabel" }, { id: "maxGrossWeight", header: "Max gross", accessorKey: "maxGrossWeight", format: "number" }, { id: "status", header: "Status", accessorKey: "status", format: "statusBadge" }, ], formFields: [ { name: "containerNumber", label: "Container number", type: "text", required: true }, { name: "containerTypeId", label: "Container type", type: "select", required: true, dynamicOptions: "containerTypes" }, { name: "wagonId", label: "Wagon", type: "select", dynamicOptions: "wagons", noneOption: true }, { name: "position", label: "Position", type: "number" }, { name: "tareWeight", label: "Tare weight", type: "number", required: true }, { name: "maxGrossWeight", label: "Max gross weight", type: "number", required: true }, { name: "sealNumber", label: "Seal number", type: "text" }, { name: "status", label: "Status", type: "text" }, ], emptyValues: { containerNumber: "", containerTypeId: "", wagonId: "", position: "", tareWeight: 0, maxGrossWeight: 0, sealNumber: "", status: "AVAILABLE", }, }, { slug: "cargoes", label: "Cargoes", subtitle: "Manage cargo records linked to containers", basePath: "/dashboard/cargoes", addLabel: "Add Cargo", entityLabel: "Cargo", searchPlaceholder: "Search cargoes…", supportsSearch: true, removeAction: "delete", cardTitleKey: "cargoReference", cardSubtitleKey: "status", searchKeys: ["cargoReference", "description", "containerId", "status"], columns: [ { id: "cargoReference", header: "Reference", accessorKey: "cargoReference", format: "code" }, { id: "cargoTypeId", header: "Cargo type", accessorKey: "cargoTypeId", format: "entityLabel" }, { id: "containerId", header: "Container", accessorKey: "containerId", format: "entityLabel" }, { id: "quantity", header: "Quantity", accessorKey: "quantity", format: "number" }, { id: "weight", header: "Weight", accessorKey: "weight", format: "number" }, { id: "status", header: "Status", accessorKey: "status", format: "statusBadge" }, ], formFields: [ { name: "cargoReference", label: "Cargo reference", type: "text", required: true }, { name: "shipmentId", label: "Shipment ID", type: "text", required: true }, { name: "containerId", label: "Container", type: "select", required: true, dynamicOptions: "containers" }, { name: "cargoTypeId", label: "Cargo type", type: "select", dynamicOptions: "cargoTypes", noneOption: true }, { name: "description", label: "Description", type: "textarea" }, { name: "quantity", label: "Quantity", type: "number", required: true }, { name: "weight", label: "Weight", type: "number", required: true }, { name: "volume", label: "Volume", type: "number" }, { name: "status", label: "Status", type: "text" }, ], emptyValues: { cargoReference: "", shipmentId: "", containerId: "", cargoTypeId: "", description: "", quantity: 0, weight: 0, volume: "", status: "PENDING", }, }, vehiclesConfig, driversConfig, ]; export const getFleetResource = (slug: string): FleetResourceConfig | undefined => FLEET_RESOURCES.find((resource) => resource.slug === slug); export const getFleetSlugFromPath = (pathname: string): FleetResourceSlug | undefined => { const normalized = pathname.toLowerCase(); return FLEET_RESOURCES.find((resource) => normalized === resource.basePath.toLowerCase())?.slug; }; export const getFleetRouteMeta = () => FLEET_RESOURCES.map((resource) => ({ prefix: resource.basePath, meta: { title: resource.label, subtitle: resource.subtitle }, }));