Merge branch 'dev' into freight/nati-2

# Conflicts:
#	apps/edr-freight-api/src/app.module.ts
#	apps/edr-freight-api/src/seed/freight-permissions.registry.ts
#	apps/edr-freight-web/backoffice/src/components/layout/sidebar-sections.tsx
#	apps/edr-freight-web/backoffice/src/constants/URLS.ts
#	apps/edr-freight-web/backoffice/src/lib/permissions.ts
This commit is contained in:
Nathnael
2026-08-20 11:29:21 +00:00
287 changed files with 25453 additions and 2339 deletions

View File

@@ -290,6 +290,32 @@ const TRAIN_BUILDER_INVALIDATIONS: ReadonlyArray<readonly unknown[]> = [
QUERY_KEYS.FLEET.ROOT,
];
/**
* Coupling/uncoupling wagons moves wagons between the available pool and one
* train — it does not touch locomotives, so those roots stay valid. Trimming
* the set keeps a drag-reorder from refetching the whole fleet.
*/
const TRAIN_BUILDER_WAGON_INVALIDATIONS: ReadonlyArray<readonly unknown[]> = [
QUERY_KEYS.TRAIN_BUILDER.ROOT,
QUERY_KEYS.TRAIN_SCHEDULING.ROOT,
["wagons"],
];
/**
* Every train-builder mutation responds with the train's full, fresh
* composition — write it straight into the detail cache so the workspace
* repaints from the response instead of refetching what it was just handed.
*/
const seedComposition = (
input: { id: string } | string,
data: TrainComposition,
): ReadonlyArray<readonly [readonly unknown[], unknown]> => [
[
QUERY_KEYS.TRAIN_BUILDER.composition(typeof input === "string" ? input : input.id),
data,
],
];
export const api = {
trainScheduling: {
// ── Queries ────────────────────────────────────────────────────────────
@@ -2076,6 +2102,7 @@ export const api = {
trainBuilderService.setLocomotives(id, locomotiveIds).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
seedComposition,
),
setYard: endpoint<{ id: string; currentYardId: string }, TrainComposition>(
@@ -2085,6 +2112,7 @@ export const api = {
trainBuilderService.setYard(id, currentYardId).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
seedComposition,
),
updateDetails: endpoint<
@@ -2097,6 +2125,7 @@ export const api = {
trainBuilderService.updateDetails(id, payload).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
seedComposition,
),
assignWagons: endpoint<{ id: string; wagonIds: string[] }, TrainComposition>(
@@ -2105,7 +2134,21 @@ export const api = {
({ id, wagonIds }) =>
trainBuilderService.assignWagons(id, wagonIds).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
() => TRAIN_BUILDER_WAGON_INVALIDATIONS,
seedComposition,
),
setWagonYard: endpoint<
{ id: string; wagonId: string; currentYardId: string },
TrainComposition
>(
"train-builder",
"setWagonYard",
({ id, wagonId, currentYardId }) =>
trainBuilderService.setWagonYard(id, wagonId, currentYardId).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_WAGON_INVALIDATIONS,
seedComposition,
),
removeWagon: endpoint<{ id: string; wagonId: string }, TrainComposition>(
@@ -2114,7 +2157,8 @@ export const api = {
({ id, wagonId }) =>
trainBuilderService.removeWagon(id, wagonId).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
() => TRAIN_BUILDER_WAGON_INVALIDATIONS,
seedComposition,
),
sendWagonToMaintenance: endpoint<
@@ -2126,7 +2170,8 @@ export const api = {
({ id, wagonId, note }) =>
trainBuilderService.sendWagonToMaintenance(id, wagonId, note).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
() => TRAIN_BUILDER_WAGON_INVALIDATIONS,
seedComposition,
),
reorderWagons: endpoint<{ id: string; wagonIds: string[] }, TrainComposition>(
@@ -2135,7 +2180,8 @@ export const api = {
({ id, wagonIds }) =>
trainBuilderService.reorderWagons(id, wagonIds).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
() => TRAIN_BUILDER_WAGON_INVALIDATIONS,
seedComposition,
),
deactivate: endpoint<string, TrainComposition>(
@@ -2144,6 +2190,7 @@ export const api = {
(id) => trainBuilderService.deactivate(id).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
seedComposition,
),
activate: endpoint<string, TrainComposition>(
@@ -2152,6 +2199,7 @@ export const api = {
(id) => trainBuilderService.activate(id).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
seedComposition,
),
disband: endpoint<string, void>(