Merge pull request #588 from Tria-plc/freight_feature/usermanagement

fix issues
This commit is contained in:
marshal
2026-07-09 23:27:02 +03:00
committed by GitHub
29 changed files with 1143 additions and 147 deletions

View File

@@ -16,6 +16,7 @@ type DiagramWagonInput = {
sequenceNo: number;
capacityTons: number;
assignedWeightTons: number;
tareWeightTons?: number | null;
slotLoadType?: string | null;
wagonType?: { code?: string | null } | null;
wagonTypeCode?: string | null;
@@ -33,6 +34,7 @@ type NormalizedWagon = {
sequenceNo: number;
capacityTons: number;
assignedWeightTons: number;
tareWeightTons: number;
wagonTypeCode: string | null;
physicalWagonNumber: string | null;
isEmpty: boolean;
@@ -69,6 +71,7 @@ function normalizeWagon(w: DiagramWagonInput, freightType?: string | null): Norm
sequenceNo: w.sequenceNo,
capacityTons: Number(w.capacityTons) || 0,
assignedWeightTons: Number(w.assignedWeightTons) || 0,
tareWeightTons: Number(w.tareWeightTons) || 0,
wagonTypeCode: w.wagonType?.code ?? w.wagonTypeCode ?? null,
physicalWagonNumber: w.physicalWagonNumber ?? null,
isEmpty: allocations.length === 0,
@@ -278,7 +281,9 @@ function WagonCar({ wagon }: { wagon: NormalizedWagon }) {
wagon.bookingRefs.length ? wagon.bookingRefs.join(", ") : ""
}${
wagon.containerNumbers.length ? `\nContainers: ${wagon.containerNumbers.join(", ")}` : ""
}${wagon.cargoDescription ? `\n${wagon.cargoDescription}` : ""}\nLoad: ${wagon.assignedWeightTons}/${wagon.capacityTons}T (${utilization}%)`;
}${wagon.cargoDescription ? `\n${wagon.cargoDescription}` : ""}\nLoad: ${wagon.assignedWeightTons}/${wagon.capacityTons}T (${utilization}%)${
wagon.tareWeightTons ? `\nTare: ${wagon.tareWeightTons}T` : ""
}`;
// container blocks: one per container number (cap visual at 2 = TEU per wagon)
const blocks = wagon.containerNumbers.slice(0, 2);
@@ -523,15 +528,22 @@ export function TrainCompositionDiagram({
const assigned = normalized.filter((w) => !w.isEmpty).length;
const totalWeight = normalized.reduce((s, w) => s + w.assignedWeightTons, 0);
const totalCapacity = normalized.reduce((s, w) => s + w.capacityTons, 0);
// Every coupled wagon's tare is hauled — empty ones included — so the
// locomotive pull limit is measured against gross (tare + cargo), the same
// ceiling the allocation engine spends from.
const totalTare = normalized.reduce((s, w) => s + w.tareWeightTons, 0);
const grossWeight = totalWeight + totalTare;
return {
total: normalized.length,
assigned,
empty: normalized.length - assigned,
totalWeight: Math.round(totalWeight * 100) / 100,
totalTare: Math.round(totalTare * 100) / 100,
grossWeight: Math.round(grossWeight * 100) / 100,
totalCapacity,
pullUtil:
locomotive?.maxPullWeightTons && locomotive.maxPullWeightTons > 0
? Math.min(100, Math.round((totalWeight / locomotive.maxPullWeightTons) * 100))
? Math.min(100, Math.round((grossWeight / locomotive.maxPullWeightTons) * 100))
: null,
};
}, [normalized, locomotive]);
@@ -598,12 +610,30 @@ export function TrainCompositionDiagram({
}}
>
<Text size="xs" fw={700} c="dark.4">
{stats.totalWeight}T
{stats.totalWeight}T cargo
</Text>
<Text size="xs" c="dimmed">
of {stats.totalCapacity}T capacity
</Text>
</Group>
{stats.totalTare > 0 ? (
<Group
gap={6}
style={{
padding: "4px 12px",
borderRadius: 999,
background: "var(--mantine-color-gray-0)",
border: "1px solid var(--mantine-color-gray-2)",
}}
>
<Text size="xs" fw={700} c="dark.4">
{stats.grossWeight}T gross
</Text>
<Text size="xs" c="dimmed">
incl. {stats.totalTare}T tare
</Text>
</Group>
) : null}
<Group gap="xs">
<LegendDot color="cyan" label="Container" />
<LegendDot color="orange" label="Bulk" />
@@ -626,7 +656,10 @@ export function TrainCompositionDiagram({
<Group gap={6} wrap="nowrap">
<Gauge size={14} color={freightBrand.primary} />
<Text size="xs" fw={700} c="edr-green.8">
Locomotive load · {stats.totalWeight}T of {locomotive?.maxPullWeightTons}T
Locomotive load ·{" "}
{stats.totalTare > 0
? `${stats.grossWeight}T of ${locomotive?.maxPullWeightTons}T (${stats.totalWeight}T cargo + ${stats.totalTare}T tare)`
: `${stats.totalWeight}T of ${locomotive?.maxPullWeightTons}T`}
</Text>
</Group>
<Text size="sm" fw={800} c={stats.pullUtil > 95 ? "red.7" : "edr-green.7"}>