mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-01 15:53:27 +00:00
fix issue
This commit is contained in:
@@ -39,11 +39,6 @@ interface InteractiveTrainConsistProps {
|
||||
onMoveLoad?: (move: WagonLoadMove) => void;
|
||||
}
|
||||
|
||||
const wagonItems = (wagon: Wagon) =>
|
||||
(wagon.allocations ?? [])
|
||||
.flatMap((a) => a.containerItems ?? [])
|
||||
.sort((a, b) => (a.positionOnWagon ?? 99) - (b.positionOnWagon ?? 99));
|
||||
|
||||
const CONTAINER_GRADIENTS = [
|
||||
"linear-gradient(180deg, var(--mantine-color-cyan-5), var(--mantine-color-cyan-7))",
|
||||
"linear-gradient(180deg, var(--mantine-color-blue-5), var(--mantine-color-blue-7))",
|
||||
@@ -192,7 +187,31 @@ function WagonCar({
|
||||
}) {
|
||||
const [dropHover, setDropHover] = useState(false);
|
||||
const wagon = slots[0]!;
|
||||
const loaded = slots.filter((s) => (s.allocations?.length ?? 0) > 0);
|
||||
const loadedSlots = slots.filter((s) => (s.allocations?.length ?? 0) > 0);
|
||||
// One drawn row per LOAD, not per slot. A wagon reused across disjoint legs
|
||||
// (containers to Dire Dawa, bulk onward) is ONE slot holding two allocations
|
||||
// with different corridors — counting slots drew that as a single row and
|
||||
// hid the second load entirely. Group the slot's allocations by their own
|
||||
// booking corridor so each load gets its own row, stacked top/bottom.
|
||||
const loaded = loadedSlots.flatMap((slot) => {
|
||||
const allocations = slot.allocations ?? [];
|
||||
const byCorridor = new Map<string, typeof allocations>();
|
||||
for (const allocation of allocations) {
|
||||
const key =
|
||||
allocation.originYardId && allocation.destinationYardId
|
||||
? `${allocation.originYardId}->${allocation.destinationYardId}`
|
||||
: "whole-route";
|
||||
byCorridor.set(key, [...(byCorridor.get(key) ?? []), allocation]);
|
||||
}
|
||||
if (byCorridor.size < 2) {
|
||||
return [{ slot, allocations, corridorKey: null as string | null }];
|
||||
}
|
||||
return [...byCorridor.entries()].map(([key, group]) => ({
|
||||
slot,
|
||||
allocations: group,
|
||||
corridorKey: key as string | null,
|
||||
}));
|
||||
});
|
||||
const shared = loaded.length > 1;
|
||||
const isEmpty = !loaded.length;
|
||||
const isBulk = loaded.some((s) =>
|
||||
@@ -201,12 +220,15 @@ function WagonCar({
|
||||
// GROSS on both sides: cargo across every slot + tare (counted ONCE — the
|
||||
// slots share the same physical wagon) vs rated payload + tare.
|
||||
const tare = wagon.tareWeightTons ?? 0;
|
||||
// Heaviest single load, not the sum: rows on disjoint legs never ride at the
|
||||
// same time, so summing them would over-report what the wagon carries.
|
||||
const cargo = loaded.reduce(
|
||||
(sum, s) =>
|
||||
sum +
|
||||
((s.allocations ?? []).reduce((a, al) => a + (al.allocatedWeightTons ?? 0), 0) ||
|
||||
s.assignedWeightTons ||
|
||||
0),
|
||||
(max, row) =>
|
||||
Math.max(
|
||||
max,
|
||||
row.allocations.reduce((a, al) => a + (al.allocatedWeightTons ?? 0), 0) ||
|
||||
(loaded.length === 1 ? row.slot.assignedWeightTons || 0 : 0),
|
||||
),
|
||||
0,
|
||||
);
|
||||
const assigned = cargo + tare;
|
||||
@@ -249,7 +271,7 @@ function WagonCar({
|
||||
<HoverCard width={280} shadow="lg" radius="md" position="top" withArrow openDelay={120}>
|
||||
<HoverCard.Target>
|
||||
<Box
|
||||
onClick={() => onSelectSlot(loaded[0] ?? wagon)}
|
||||
onClick={() => onSelectSlot(loaded[0]?.slot ?? wagon)}
|
||||
style={{ width: 148, flexShrink: 0, cursor: "pointer" }}
|
||||
>
|
||||
<Box
|
||||
@@ -389,16 +411,25 @@ function WagonCar({
|
||||
// two side by side. A shared wagon stacks its slots top/bottom
|
||||
// (intercity above, export below); each row selects ITS slot.
|
||||
<Stack gap={3} style={{ width: "100%" }}>
|
||||
{loaded.map((slot, r) => {
|
||||
const rowBulk = (slot.allocations ?? []).some((a) =>
|
||||
{loaded.map((row, r) => {
|
||||
const slot = row.slot;
|
||||
const rowBulk = row.allocations.some((a) =>
|
||||
(a.loadType ?? "").toUpperCase().includes("BULK"),
|
||||
);
|
||||
const rowBlocks = wagonItems(slot).slice(0, 2);
|
||||
// Container blocks of THIS row's allocations only, so a
|
||||
// leg-shared wagon shows each leg's own boxes.
|
||||
const rowBlocks = row.allocations
|
||||
.flatMap((a) => a.containerItems ?? [])
|
||||
.slice()
|
||||
.sort(
|
||||
(a, b) => (a.positionOnWagon ?? 0) - (b.positionOnWagon ?? 0),
|
||||
)
|
||||
.slice(0, 2);
|
||||
const rowSelected = shared && slot.id === selectedWagonId;
|
||||
const rowHeight = shared ? 20 : 26;
|
||||
return (
|
||||
<Group
|
||||
key={slot.id}
|
||||
key={`${slot.id}-${row.corridorKey ?? "all"}`}
|
||||
gap={3}
|
||||
justify="center"
|
||||
wrap="nowrap"
|
||||
@@ -549,15 +580,18 @@ function WagonCar({
|
||||
</Text>
|
||||
) : (
|
||||
<Stack gap={6}>
|
||||
{loaded.map((slot) => {
|
||||
const slotAllocation = slot.allocations?.[0];
|
||||
{loaded.map((row) => {
|
||||
const slot = row.slot;
|
||||
const slotAllocation = row.allocations[0];
|
||||
const slotCompany = getCompany(slotAllocation?.bookingId);
|
||||
const slotContainers = wagonItems(slot).map(
|
||||
(c) => c.containerNumber?.trim() || "—",
|
||||
);
|
||||
// This row's own containers, so a leg-shared wagon lists each
|
||||
// leg's boxes under its own load rather than all of them twice.
|
||||
const slotContainers = row.allocations
|
||||
.flatMap((a) => a.containerItems ?? [])
|
||||
.map((c) => c.containerNumber?.trim() || "—");
|
||||
return (
|
||||
<Stack
|
||||
key={slot.id}
|
||||
key={`${slot.id}-${row.corridorKey ?? "all"}`}
|
||||
gap={4}
|
||||
style={
|
||||
shared
|
||||
|
||||
Reference in New Issue
Block a user