mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 10:40:58 +00:00
Train scheduling API,Routes and UI
This commit is contained in:
@@ -36,21 +36,12 @@ import RuleEngineLegacyRedirect from "./pages/ruleEngine/RuleEngineLegacyRedirec
|
||||
import RuleEngineResourcePage from "./pages/ruleEngine/RuleEngineResourcePage";
|
||||
import TrainsPage from "./pages/trains/TrainsPage";
|
||||
import {
|
||||
<<<<<<< HEAD
|
||||
CargoesCrudPage,
|
||||
ContainersCrudPage,
|
||||
TrainMasterDataPage,
|
||||
WagonTypesCrudPage,
|
||||
WagonsCrudPage,
|
||||
} from "./pages/fleet/FleetCrudPages";
|
||||
=======
|
||||
CargoesCrudPage,
|
||||
ContainersCrudPage,
|
||||
LocomotivesCrudPage,
|
||||
TrainMasterDataPage,
|
||||
WagonsCrudPage,
|
||||
} from "./pages/fleet/FleetCrudPages";
|
||||
>>>>>>> b9cfce70fe17b5066ae5320cfcc595bf3c253467
|
||||
import { getCategorySidebarChildren } from "./pages/ruleEngine/config/resources";
|
||||
import TrainDetailPage from "./pages/trains/TrainDetailPage";
|
||||
import RoutesPage from "./pages/fleet/RoutesPage";
|
||||
@@ -101,15 +92,15 @@ const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[] => [
|
||||
href: "/dashboard/trains",
|
||||
icon: <Train />,
|
||||
},
|
||||
{
|
||||
label: "Wagon types",
|
||||
href: "/dashboard/wagon-types",
|
||||
icon: <Boxes />,
|
||||
},
|
||||
{
|
||||
label: "Wagons",
|
||||
href: "/dashboard/wagons",
|
||||
icon: <Truck />,
|
||||
{
|
||||
label: "Wagon types",
|
||||
href: "/dashboard/wagon-types",
|
||||
icon: <Boxes />,
|
||||
},
|
||||
{
|
||||
label: "Wagons",
|
||||
href: "/dashboard/wagons",
|
||||
icon: <Truck />,
|
||||
},
|
||||
{
|
||||
label: "Containers",
|
||||
@@ -255,12 +246,6 @@ const App = () => {
|
||||
element={<BookingContractPage />}
|
||||
/>
|
||||
<Route path="operations/train-scheduling" element={<TrainsPage />} />
|
||||
<<<<<<< HEAD
|
||||
<Route path="trains" element={<TrainMasterDataPage />} />
|
||||
<Route path="trains/:id" element={<TrainDetailPage />} />
|
||||
<Route path="wagon-types" element={<WagonTypesCrudPage />} />
|
||||
<Route path="wagons" element={<WagonsCrudPage />} />
|
||||
=======
|
||||
<Route path="trains" element={<TrainMasterDataPage />} />
|
||||
<Route path="operations/train-scheduling" element={<TrainsPage />} />
|
||||
<Route path="routes" element={<RoutesPage />} />
|
||||
@@ -268,7 +253,6 @@ const App = () => {
|
||||
<Route path="trains" element={<TrainMasterDataPage />} />
|
||||
<Route path="trains/:id" element={<TrainDetailPage />} />
|
||||
<Route path="wagons" element={<WagonsCrudPage />} />
|
||||
>>>>>>> b9cfce70fe17b5066ae5320cfcc595bf3c253467
|
||||
<Route path="containers" element={<ContainersCrudPage />} />
|
||||
<Route path="cargoes" element={<CargoesCrudPage />} />
|
||||
|
||||
|
||||
@@ -127,6 +127,8 @@ export const URL_CONSTANTS = {
|
||||
SCHEDULE_BY_ID: (id: string) => `/train-scheduling/container/schedules/${id}`,
|
||||
CANCEL_SCHEDULE: (id: string) =>
|
||||
`/train-scheduling/container/schedules/${id}/cancel`,
|
||||
PUBLISH_SCHEDULE: (id: string) =>
|
||||
`/train-scheduling/container/schedules/${id}/publish`,
|
||||
},
|
||||
|
||||
RULE_ENGINE: {
|
||||
|
||||
@@ -50,6 +50,7 @@ import {
|
||||
useUpdateContainer,
|
||||
} from '@/hooks/useContainers';
|
||||
import { useCreateTrain, useDeleteTrain, useTrains, useUpdateTrain } from '@/hooks/useTrains';
|
||||
import { useRouteYards } from '@/hooks/useRoutes';
|
||||
import { useCreateWagon, useDeleteWagon, useUpdateWagon, useWagons } from '@/hooks/useWagons';
|
||||
import {
|
||||
useCreateLocomotive,
|
||||
@@ -892,10 +893,15 @@ export function WagonTypesCrudPage() {
|
||||
export function WagonsCrudPage() {
|
||||
const query = useWagons();
|
||||
const { data: wagonTypes = [] } = useWagonTypes();
|
||||
const { data: yards = [] } = useRouteYards();
|
||||
const wagonTypeOptions = wagonTypes.map((type: any) => ({
|
||||
value: type.id,
|
||||
label: `${type.code} - ${type.name}`,
|
||||
}));
|
||||
const yardOptions = yards.map((yard: any) => ({
|
||||
value: yard.id,
|
||||
label: `${yard.label ?? yard.code} (${yard.country ?? '-'})`,
|
||||
}));
|
||||
return (
|
||||
<FleetCrudPage<Wagon>
|
||||
title="Wagons"
|
||||
@@ -906,10 +912,26 @@ export function WagonsCrudPage() {
|
||||
create={useCreateWagon()}
|
||||
update={useUpdateWagon()}
|
||||
remove={useDeleteWagon()}
|
||||
searchText={(wagon) => [wagon.wagonNumber, wagon.wagonTypeId, wagon.trainId, wagon.status].join(' ')}
|
||||
searchText={(wagon) => [
|
||||
wagon.wagonNumber,
|
||||
wagon.wagonTypeId,
|
||||
wagon.trainId,
|
||||
wagon.status,
|
||||
wagon.currentLocationYard?.label,
|
||||
wagon.currentLocationYard?.code,
|
||||
wagon.currentLocationYard?.country,
|
||||
].join(' ')}
|
||||
columns={[
|
||||
{ key: 'wagonNumber', label: 'Number' },
|
||||
{ key: 'wagonTypeId', label: 'Type', render: (wagon) => optionLabel(wagonTypeOptions, wagon.wagonTypeId) },
|
||||
{
|
||||
key: 'currentLocationYardId',
|
||||
label: 'Location',
|
||||
render: (wagon) =>
|
||||
wagon.currentLocationYard
|
||||
? `${wagon.currentLocationYard.label ?? wagon.currentLocationYard.code} (${wagon.currentLocationYard.country ?? '-'})`
|
||||
: '-',
|
||||
},
|
||||
{ key: 'maxPayloadWeight', label: 'Max payload' },
|
||||
{ key: 'status', label: 'Status', render: (wagon) => statusBadge(wagon.status) },
|
||||
]}
|
||||
@@ -927,12 +949,31 @@ export function WagonsCrudPage() {
|
||||
return { maxPayloadWeight: Number(selectedType.capacityTons) };
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'currentLocationYardId',
|
||||
label: 'Wagon location',
|
||||
type: 'select',
|
||||
required: true,
|
||||
options: yardOptions,
|
||||
},
|
||||
{ key: 'tareWeight', label: 'Tare weight', type: 'number', required: true },
|
||||
{ key: 'maxPayloadWeight', label: 'Max payload weight', type: 'number', required: true },
|
||||
{ key: 'status', label: 'Status' },
|
||||
{
|
||||
key: 'status',
|
||||
label: 'Status',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: 'AVAILABLE', label: 'Available' },
|
||||
{ value: 'IMPORT_READY', label: 'Import ready' },
|
||||
{ value: 'EXPORT_READY', label: 'Export ready' },
|
||||
{ value: 'ASSIGNED', label: 'Assigned' },
|
||||
{ value: 'MAINTENANCE', label: 'Maintenance' },
|
||||
{ value: 'RETIRED', label: 'Retired' },
|
||||
],
|
||||
},
|
||||
{ key: 'notes', label: 'Notes' },
|
||||
]}
|
||||
emptyValues={{ wagonNumber: '', wagonTypeId: '', tareWeight: 0, maxPayloadWeight: 0, status: 'AVAILABLE', notes: '' }}
|
||||
emptyValues={{ wagonNumber: '', wagonTypeId: '', currentLocationYardId: '', tareWeight: 0, maxPayloadWeight: 0, status: 'AVAILABLE', notes: '' }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,9 @@ import { URL_CONSTANTS } from '@/constants/URLS';
|
||||
export type LocomotiveType = 'DIESEL' | 'ELECTRIC';
|
||||
export type LocomotiveStatus =
|
||||
| 'AVAILABLE'
|
||||
| 'UNAVAILABLE'
|
||||
| 'IMPORT_READY'
|
||||
| 'EXPORT_READY'
|
||||
| 'MAINTENANCE'
|
||||
| 'ASSIGNED'
|
||||
| 'OUT_OF_SERVICE';
|
||||
|
||||
@@ -70,6 +70,14 @@ export const trainSchedulingService = {
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
publishSchedule: async (id: string): Promise<TrainScheduleDetail> => {
|
||||
const response = await client.post<TrainScheduleDetail>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.PUBLISH_SCHEDULE(id),
|
||||
{},
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
getAvailableLocomotives: async (): Promise<LocomotiveRecord[]> => {
|
||||
const response = await client.get<LocomotiveRecord[]>(URL_CONSTANTS.LOCOMOTIVES.BASE, {
|
||||
params: { status: 'AVAILABLE' },
|
||||
|
||||
@@ -6,6 +6,19 @@ export interface Wagon {
|
||||
wagonTypeId: string;
|
||||
trainId: string | null;
|
||||
sequenceNumber: number | null;
|
||||
currentLocationYardId: string | null;
|
||||
currentLocationYard?: {
|
||||
id: string;
|
||||
code: string;
|
||||
label: string;
|
||||
country?: string;
|
||||
} | null;
|
||||
wagonType?: {
|
||||
id: string;
|
||||
code: string;
|
||||
name: string;
|
||||
supportedLoadTypes?: string[];
|
||||
} | null;
|
||||
tareWeight: number;
|
||||
maxPayloadWeight: number;
|
||||
status: string;
|
||||
|
||||
@@ -6,6 +6,9 @@ export const BOOKING_STATUSES = [
|
||||
"PENDING_APPROVAL",
|
||||
"APPROVED_PENDING_SIGNATURE",
|
||||
"APPROVED",
|
||||
"READY_FOR_ASSIGNMENT",
|
||||
"WAGON_ASSIGNED",
|
||||
"INVOICED",
|
||||
"CONTRACT_READY",
|
||||
"SIGNED_CUSTOMER",
|
||||
"FULLY_EXECUTED",
|
||||
|
||||
@@ -23,6 +23,9 @@ export interface EligibleContainerBookingsResponse {
|
||||
items: EligibleContainerBooking[];
|
||||
}
|
||||
|
||||
export type AssignmentType = "CONTAINER" | "BULK";
|
||||
export type TradeDirection = "IMPORT" | "EXPORT" | "DOMESTIC";
|
||||
|
||||
export interface WagonPlanAllocation {
|
||||
bookingId: string;
|
||||
bookingReference: string;
|
||||
@@ -57,7 +60,14 @@ export interface LocomotiveRecord {
|
||||
name?: string | null;
|
||||
maxPullWeightTons: number;
|
||||
maxTrainLengthMeters: number;
|
||||
status: 'AVAILABLE' | 'ASSIGNED' | 'MAINTENANCE' | 'OUT_OF_SERVICE';
|
||||
status:
|
||||
| 'AVAILABLE'
|
||||
| 'UNAVAILABLE'
|
||||
| 'IMPORT_READY'
|
||||
| 'EXPORT_READY'
|
||||
| 'ASSIGNED'
|
||||
| 'MAINTENANCE'
|
||||
| 'OUT_OF_SERVICE';
|
||||
locomotiveType?: 'DIESEL' | 'ELECTRIC';
|
||||
}
|
||||
|
||||
@@ -125,6 +135,11 @@ export interface TrainScheduleDetail {
|
||||
code: string;
|
||||
name: string;
|
||||
} | null;
|
||||
physicalWagon?: {
|
||||
id: string;
|
||||
wagonNumber: string;
|
||||
status: string;
|
||||
} | null;
|
||||
allocations: Array<{
|
||||
id: string;
|
||||
bookingId: string;
|
||||
@@ -146,6 +161,8 @@ export interface TrainScheduleFilters {
|
||||
originStationId?: string;
|
||||
destinationStationId?: string;
|
||||
scheduleDate?: string;
|
||||
assignmentType?: AssignmentType;
|
||||
tradeDirection?: TradeDirection;
|
||||
}
|
||||
|
||||
export interface TrainSchedulePreviewPayload {
|
||||
@@ -153,10 +170,15 @@ export interface TrainSchedulePreviewPayload {
|
||||
scheduleDate: string;
|
||||
originStationId: string;
|
||||
destinationStationId: string;
|
||||
assignmentType?: AssignmentType;
|
||||
}
|
||||
|
||||
export interface CreateTrainSchedulePayload {
|
||||
routeId: string;
|
||||
scheduleDate: string;
|
||||
arrivalDate?: string;
|
||||
locomotiveId: string;
|
||||
assignmentType?: AssignmentType;
|
||||
bookingIds: string[];
|
||||
wagonIds?: string[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user