mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 19:58:11 +00:00
feat: implement wagon transfer management modals and page
- Add TransferFulfillModal for fulfilling wagon transfer requests. - Create TransferRequestFormModal for filing new wagon transfer requests. - Introduce TransferCloseShortModal for closing requests that cannot be fully fulfilled. - Develop WagonTransfersPage to manage and display wagon transfer requests. - Implement utility functions for handling wagon transfer request data and UI components. - Enhance UI with Mantine components for better user experience.
This commit is contained in:
@@ -147,6 +147,7 @@ import {
|
||||
DEFAULT_CONTAINER_WAGON_LENGTH_METERS,
|
||||
DEFAULT_CONTAINER_WAGON_TARE_TONS,
|
||||
} from './booking-batch.constants';
|
||||
import { orderConsistWagons } from './consist-order.util';
|
||||
import {
|
||||
computeExportWindowTimes,
|
||||
computeImportWindowTimes,
|
||||
@@ -6696,6 +6697,18 @@ export class TrainSchedulingService {
|
||||
consistOnly: true,
|
||||
}));
|
||||
|
||||
// The consist is DRAWN in the built train's real coupling order (rawConsistWagons
|
||||
// is already ASC/DESC per reverseWagonOrder), not in slot order — see
|
||||
// consist-order.util. `position` is the drawn place, 1..n; `sequenceNo` stays
|
||||
// the slot's own stored value.
|
||||
const drawConsist = <T extends { sequenceNo: number; physicalWagonId: string | null }>(
|
||||
list: T[],
|
||||
) =>
|
||||
orderConsistWagons(list, {
|
||||
physicalWagonIdsInOrder: rawConsistWagons.map((wagon) => wagon.id),
|
||||
reverseWagonOrder: schedule.reverseWagonOrder,
|
||||
});
|
||||
|
||||
return {
|
||||
id: schedule.id,
|
||||
reference: schedule.reference ?? null,
|
||||
@@ -6785,7 +6798,8 @@ export class TrainSchedulingService {
|
||||
maxPullWeightTons: roundTons(Number(loco.maxPullWeightTons)),
|
||||
maxTrainLengthMeters: roundTons(Number(loco.maxTrainLengthMeters)),
|
||||
})),
|
||||
wagons: (schedule.trainSet.wagons ?? [])
|
||||
wagons: drawConsist(
|
||||
(schedule.trainSet.wagons ?? [])
|
||||
.map((wagon) => {
|
||||
// Frozen schedules read the wagon number + allocations from the
|
||||
// snapshot slot; the immutable slot geometry (capacity/type) still
|
||||
@@ -6875,12 +6889,8 @@ export class TrainSchedulingService {
|
||||
})) ?? [],
|
||||
};
|
||||
})
|
||||
.concat(emptyConsistWagons)
|
||||
.sort((a, b) =>
|
||||
schedule.reverseWagonOrder
|
||||
? b.sequenceNo - a.sequenceNo
|
||||
: a.sequenceNo - b.sequenceNo,
|
||||
),
|
||||
.concat(emptyConsistWagons),
|
||||
),
|
||||
}
|
||||
: null,
|
||||
bookings:
|
||||
@@ -7458,8 +7468,12 @@ export class TrainSchedulingService {
|
||||
];
|
||||
const cargoOf = (allocs: WagonBookingAllocation[]) =>
|
||||
allocs.reduce((sum, a) => sum + Number(a.allocatedWeightTons || 0), 0);
|
||||
const wagonLabel = (slot: { sequenceNo: number } | null, wagon: Wagon | null) =>
|
||||
slot ? `#${slot.sequenceNo}` : (wagon?.wagonNumber ?? 'the target wagon');
|
||||
// Name wagons by their physical number — the consist is drawn in the train's
|
||||
// coupling order, so a slot's sequenceNo is not the position staff can see.
|
||||
const slotLabel = (slot: TrainSetWagon) =>
|
||||
slot.physicalWagon?.wagonNumber ?? `#${slot.sequenceNo}`;
|
||||
const wagonLabel = (slot: TrainSetWagon | null, wagon: Wagon | null) =>
|
||||
slot ? slotLabel(slot) : (wagon?.wagonNumber ?? 'the target wagon');
|
||||
const checkReceives = (
|
||||
allocs: WagonBookingAllocation[],
|
||||
label: string,
|
||||
@@ -7501,7 +7515,7 @@ export class TrainSchedulingService {
|
||||
if (targetAllocs.length) {
|
||||
checkReceives(
|
||||
targetAllocs,
|
||||
`#${source.sequenceNo}`,
|
||||
slotLabel(source),
|
||||
source.wagonType,
|
||||
Number(source.capacityTons),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user