From 7f5e8349dad0ec18704ae2277ae8e2b7aff0ff1d Mon Sep 17 00:00:00 2001 From: Hagernesh Date: Sat, 22 Aug 2026 09:16:17 +0000 Subject: [PATCH] Intercity andd import export gating --- .../IntercityRideAlongPanel.tsx | 23 ++++++- .../trainScheduling/LogPassYardWorkModal.tsx | 18 ++++-- .../ScheduleWorkspacePanel.tsx | 40 ++++++++---- .../warehouses/ReceiveInventoryModal.tsx | 64 +++++++++++-------- .../backoffice/src/lib/permissions.ts | 3 + .../src/pages/warehouses/IntercityPage.tsx | 57 ++++++++++------- 6 files changed, 134 insertions(+), 71 deletions(-) diff --git a/apps/edr-freight-web/backoffice/src/components/trainScheduling/IntercityRideAlongPanel.tsx b/apps/edr-freight-web/backoffice/src/components/trainScheduling/IntercityRideAlongPanel.tsx index 1636cfa6d..0342b9ae9 100644 --- a/apps/edr-freight-web/backoffice/src/components/trainScheduling/IntercityRideAlongPanel.tsx +++ b/apps/edr-freight-web/backoffice/src/components/trainScheduling/IntercityRideAlongPanel.tsx @@ -15,6 +15,8 @@ import { import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { AlertCircle, ArrowRight, PackageCheck, PackageOpen, TrainFront } from "lucide-react"; +import { useAuth } from "@/auth/useAuth"; +import { FREIGHT_PERMS, hasPermission as hasFreightPermission } from "@/lib/permissions"; import { api } from "@/services/api"; import { useToast } from "@/hooks/use-toast"; import type { @@ -130,6 +132,9 @@ export function IntercityRideAlongPanel({ direction: string | null | undefined; }) { const { toast } = useToast(); + const { user } = useAuth(); + const canLoad = hasFreightPermission(user, FREIGHT_PERMS.trainScheduling.load); + const canUnload = hasFreightPermission(user, FREIGHT_PERMS.trainScheduling.unload); const queryClient = useQueryClient(); const [selected, setSelected] = useState([]); @@ -378,12 +383,19 @@ export function IntercityRideAlongPanel({ {row.status === "PAID" && ( - + + + + void; }) { const { toast } = useToast(); + const { user } = useAuth(); + const canUnload = hasFreightPermission(user, FREIGHT_PERMS.warehouseInventory.unload); const { data: trains = [], isLoading } = useQuery( api.warehouses.importArriveQueue.queryOptions({ enabled }), ); @@ -2489,23 +2497,25 @@ export function ImportArriveQueueTab({ > Open - + + + diff --git a/apps/edr-freight-web/backoffice/src/lib/permissions.ts b/apps/edr-freight-web/backoffice/src/lib/permissions.ts index 177976b28..d8ef47f35 100644 --- a/apps/edr-freight-web/backoffice/src/lib/permissions.ts +++ b/apps/edr-freight-web/backoffice/src/lib/permissions.ts @@ -104,6 +104,9 @@ export const FREIGHT_PERMS = { view: "edr_freight_app:train_scheduling:view", create: "edr_freight_app:train_scheduling:create", update: "edr_freight_app:train_scheduling:update", + /** Confirm cargo loaded/unloaded at a yard — import, export, and intercity alike. */ + load: "edr_freight_app:train_scheduling:load", + unload: "edr_freight_app:train_scheduling:unload", cancel: "edr_freight_app:train_scheduling:cancel", reschedule: "edr_freight_app:train_scheduling:reschedule", rulesManage: "edr_freight_app:train_scheduling:rules_manage", diff --git a/apps/edr-freight-web/backoffice/src/pages/warehouses/IntercityPage.tsx b/apps/edr-freight-web/backoffice/src/pages/warehouses/IntercityPage.tsx index cfda31629..f756af834 100644 --- a/apps/edr-freight-web/backoffice/src/pages/warehouses/IntercityPage.tsx +++ b/apps/edr-freight-web/backoffice/src/pages/warehouses/IntercityPage.tsx @@ -17,6 +17,8 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { AlertTriangle, PackageCheck, PackageOpen, TrainFront, Warehouse } from "lucide-react"; import { PageContainer, PageHeader } from "@/components/page"; +import { useAuth } from "@/auth/useAuth"; +import { FREIGHT_PERMS, hasPermission as hasFreightPermission } from "@/lib/permissions"; import ListControls from "@/components/common/ListControls"; // Generic list footer — already shared by the fleet and train-scheduling lists // despite the ruleEngine path. @@ -93,6 +95,9 @@ const apiErrorMessage = (error: unknown) => { function Rows({ rows }: { rows: IntercityRideAlongRow[] }) { const { toast } = useToast(); + const { user } = useAuth(); + const canLoad = hasFreightPermission(user, FREIGHT_PERMS.trainScheduling.load); + const canUnload = hasFreightPermission(user, FREIGHT_PERMS.trainScheduling.unload); const queryClient = useQueryClient(); const refresh = () => queryClient.invalidateQueries({ @@ -201,31 +206,37 @@ function Rows({ rows }: { rows: IntercityRideAlongRow[] }) { {/* Work the cargo right here while the train is at the yard. */} {r.trainScheduleId && atOrigin(r) && isWaiting(r) && r.status === "PAID" && ( - + + + )} {r.trainScheduleId && atDestination(r) && isRiding(r) && ( - + + + )}