mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
Intercity andd import export gating
This commit is contained in:
@@ -15,6 +15,8 @@ import {
|
|||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { AlertCircle, ArrowRight, PackageCheck, PackageOpen, TrainFront } from "lucide-react";
|
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 { api } from "@/services/api";
|
||||||
import { useToast } from "@/hooks/use-toast";
|
import { useToast } from "@/hooks/use-toast";
|
||||||
import type {
|
import type {
|
||||||
@@ -130,6 +132,9 @@ export function IntercityRideAlongPanel({
|
|||||||
direction: string | null | undefined;
|
direction: string | null | undefined;
|
||||||
}) {
|
}) {
|
||||||
const { toast } = useToast();
|
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 queryClient = useQueryClient();
|
||||||
const [selected, setSelected] = useState<string[]>([]);
|
const [selected, setSelected] = useState<string[]>([]);
|
||||||
|
|
||||||
@@ -378,12 +383,19 @@ export function IntercityRideAlongPanel({
|
|||||||
<Table.Td>
|
<Table.Td>
|
||||||
<Group gap="xs" justify="flex-end">
|
<Group gap="xs" justify="flex-end">
|
||||||
{row.status === "PAID" && (
|
{row.status === "PAID" && (
|
||||||
<Tooltip label="Train must be at the booking's origin yard">
|
<Tooltip
|
||||||
|
label={
|
||||||
|
canLoad
|
||||||
|
? "Train must be at the booking's origin yard"
|
||||||
|
: "You don't have permission to load cargo"
|
||||||
|
}
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
size="compact-xs"
|
size="compact-xs"
|
||||||
variant="light"
|
variant="light"
|
||||||
leftSection={<PackageCheck size={13} />}
|
leftSection={<PackageCheck size={13} />}
|
||||||
loading={load.isPending}
|
loading={load.isPending}
|
||||||
|
disabled={!canLoad}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
load.mutate({ scheduleId, bookingId: row.id })
|
load.mutate({ scheduleId, bookingId: row.id })
|
||||||
}
|
}
|
||||||
@@ -393,13 +405,20 @@ export function IntercityRideAlongPanel({
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
{row.status === "IN_TRANSIT" && (
|
{row.status === "IN_TRANSIT" && (
|
||||||
<Tooltip label="Train must be at the booking's destination yard">
|
<Tooltip
|
||||||
|
label={
|
||||||
|
canUnload
|
||||||
|
? "Train must be at the booking's destination yard"
|
||||||
|
: "You don't have permission to unload cargo"
|
||||||
|
}
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
size="compact-xs"
|
size="compact-xs"
|
||||||
variant="light"
|
variant="light"
|
||||||
color="orange"
|
color="orange"
|
||||||
leftSection={<PackageOpen size={13} />}
|
leftSection={<PackageOpen size={13} />}
|
||||||
loading={unload.isPending}
|
loading={unload.isPending}
|
||||||
|
disabled={!canUnload}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
unload.mutate({ scheduleId, bookingId: row.id })
|
unload.mutate({ scheduleId, bookingId: row.id })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import { useEffect, useState } from "react";
|
|||||||
import { Freight } from "@edr/types";
|
import { Freight } from "@edr/types";
|
||||||
|
|
||||||
import { BookingStatusBadge } from "@/components/bookings/BookingStatusBadge";
|
import { BookingStatusBadge } from "@/components/bookings/BookingStatusBadge";
|
||||||
|
import { useAuth } from "@/auth/useAuth";
|
||||||
|
import { FREIGHT_PERMS, hasPermission as hasFreightPermission } from "@/lib/permissions";
|
||||||
import { useToast } from "@/hooks/use-toast";
|
import { useToast } from "@/hooks/use-toast";
|
||||||
import { api } from "@/services/api";
|
import { api } from "@/services/api";
|
||||||
import type { TrackStation, YardWorkBookingRow } from "@/types/trainScheduling";
|
import type { TrackStation, YardWorkBookingRow } from "@/types/trainScheduling";
|
||||||
@@ -111,6 +113,8 @@ export function LogPassYardWorkModal({
|
|||||||
alreadyLogged: boolean;
|
alreadyLogged: boolean;
|
||||||
}) {
|
}) {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
const { user } = useAuth();
|
||||||
|
const canLoad = hasFreightPermission(user, FREIGHT_PERMS.trainScheduling.load);
|
||||||
const [justLogged, setJustLogged] = useState(false);
|
const [justLogged, setJustLogged] = useState(false);
|
||||||
// When the train was here — defaults to now, past allowed (recorded after the fact).
|
// When the train was here — defaults to now, past allowed (recorded after the fact).
|
||||||
const [passAt, setPassAt] = useState<Date | null>(null);
|
const [passAt, setPassAt] = useState<Date | null>(null);
|
||||||
@@ -353,7 +357,9 @@ export function LogPassYardWorkModal({
|
|||||||
{!row.loadedAt ? (
|
{!row.loadedAt ? (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
label={
|
label={
|
||||||
!logged
|
!canLoad
|
||||||
|
? "You don't have permission to load cargo"
|
||||||
|
: !logged
|
||||||
? "Log the pass first — the train must be at this yard"
|
? "Log the pass first — the train must be at this yard"
|
||||||
: !row.canLoad
|
: !row.canLoad
|
||||||
? "Booking is not ready to load (payment pending)"
|
? "Booking is not ready to load (payment pending)"
|
||||||
@@ -364,7 +370,7 @@ export function LogPassYardWorkModal({
|
|||||||
size="compact-xs"
|
size="compact-xs"
|
||||||
variant="light"
|
variant="light"
|
||||||
leftSection={<PackageCheck size={13} />}
|
leftSection={<PackageCheck size={13} />}
|
||||||
disabled={!logged || !row.canLoad}
|
disabled={!canLoad || !logged || !row.canLoad}
|
||||||
loading={
|
loading={
|
||||||
load.isPending && load.variables?.bookingId === row.id
|
load.isPending && load.variables?.bookingId === row.id
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ import { CountdownTimer } from "@edr/ui-common";
|
|||||||
|
|
||||||
import { BookingStatusBadge } from "@/components/bookings/BookingStatusBadge";
|
import { BookingStatusBadge } from "@/components/bookings/BookingStatusBadge";
|
||||||
import { EntityLink } from "@/components/detail";
|
import { EntityLink } from "@/components/detail";
|
||||||
|
import { useAuth } from "@/auth/useAuth";
|
||||||
|
import { FREIGHT_PERMS, hasPermission as hasFreightPermission } from "@/lib/permissions";
|
||||||
import { api } from "@/services/api";
|
import { api } from "@/services/api";
|
||||||
import { bookingsService } from "@/services/bookings.service";
|
import { bookingsService } from "@/services/bookings.service";
|
||||||
import { useToast } from "@/hooks/use-toast";
|
import { useToast } from "@/hooks/use-toast";
|
||||||
@@ -170,6 +172,9 @@ export function ScheduleWorkspacePanel({
|
|||||||
onChanged,
|
onChanged,
|
||||||
}: ScheduleWorkspacePanelProps) {
|
}: ScheduleWorkspacePanelProps) {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
const { user } = useAuth();
|
||||||
|
const canLoad = hasFreightPermission(user, FREIGHT_PERMS.trainScheduling.load);
|
||||||
|
const canUnload = hasFreightPermission(user, FREIGHT_PERMS.trainScheduling.unload);
|
||||||
|
|
||||||
const freightType: FreightType | undefined =
|
const freightType: FreightType | undefined =
|
||||||
schedule.freightType === "CONTAINER" || schedule.freightType === "BULK"
|
schedule.freightType === "CONTAINER" || schedule.freightType === "BULK"
|
||||||
@@ -773,7 +778,9 @@ export function ScheduleWorkspacePanel({
|
|||||||
{showLoad ? (
|
{showLoad ? (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
label={
|
label={
|
||||||
boardHere
|
!canLoad
|
||||||
|
? "You don't have permission to load cargo"
|
||||||
|
: boardHere
|
||||||
? `Load cargo onto the train at ${group.label}`
|
? `Load cargo onto the train at ${group.label}`
|
||||||
: passed
|
: passed
|
||||||
? `Train already passed ${group.label} — this cargo missed its stop`
|
? `Train already passed ${group.label} — this cargo missed its stop`
|
||||||
@@ -788,7 +795,7 @@ export function ScheduleWorkspacePanel({
|
|||||||
variant="filled"
|
variant="filled"
|
||||||
color="edr-green"
|
color="edr-green"
|
||||||
radius="md"
|
radius="md"
|
||||||
disabled={!boardHere}
|
disabled={!boardHere || !canLoad}
|
||||||
leftSection={<PackageCheck size={13} />}
|
leftSection={<PackageCheck size={13} />}
|
||||||
loading={
|
loading={
|
||||||
loadJourney.isPending &&
|
loadJourney.isPending &&
|
||||||
@@ -802,7 +809,11 @@ export function ScheduleWorkspacePanel({
|
|||||||
) : null}
|
) : null}
|
||||||
{showTruckToTrain ? (
|
{showTruckToTrain ? (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
label="Customer truck loaded straight onto the wagon — no warehouse receipt, no GRN. Sets direct truck-to-train handover and loads."
|
label={
|
||||||
|
canLoad
|
||||||
|
? "Customer truck loaded straight onto the wagon — no warehouse receipt, no GRN. Sets direct truck-to-train handover and loads."
|
||||||
|
: "You don't have permission to load cargo"
|
||||||
|
}
|
||||||
withArrow
|
withArrow
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
@@ -810,6 +821,7 @@ export function ScheduleWorkspacePanel({
|
|||||||
variant="light"
|
variant="light"
|
||||||
color="blue"
|
color="blue"
|
||||||
radius="md"
|
radius="md"
|
||||||
|
disabled={!canLoad}
|
||||||
leftSection={<Truck size={13} />}
|
leftSection={<Truck size={13} />}
|
||||||
loading={truckToTrainPending === b.id}
|
loading={truckToTrainPending === b.id}
|
||||||
onClick={() => doTruckToTrain(b.id, ref)}
|
onClick={() => doTruckToTrain(b.id, ref)}
|
||||||
@@ -821,7 +833,9 @@ export function ScheduleWorkspacePanel({
|
|||||||
{showUnload ? (
|
{showUnload ? (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
label={
|
label={
|
||||||
alightHere
|
!canUnload
|
||||||
|
? "You don't have permission to unload cargo"
|
||||||
|
: alightHere
|
||||||
? "Unload at this yard — stamps the booking's arrival"
|
? "Unload at this yard — stamps the booking's arrival"
|
||||||
: "Unloads when the train reaches its destination yard"
|
: "Unloads when the train reaches its destination yard"
|
||||||
}
|
}
|
||||||
@@ -832,7 +846,7 @@ export function ScheduleWorkspacePanel({
|
|||||||
variant="light"
|
variant="light"
|
||||||
color="orange"
|
color="orange"
|
||||||
radius="md"
|
radius="md"
|
||||||
disabled={!alightHere}
|
disabled={!alightHere || !canUnload}
|
||||||
leftSection={<PackageOpen size={13} />}
|
leftSection={<PackageOpen size={13} />}
|
||||||
loading={
|
loading={
|
||||||
unloadJourney.isPending &&
|
unloadJourney.isPending &&
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ import {
|
|||||||
|
|
||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { useAuth } from '@/auth/useAuth';
|
||||||
|
import { FREIGHT_PERMS, hasPermission as hasFreightPermission } from '@/lib/permissions';
|
||||||
import { api } from '@/services/api';
|
import { api } from '@/services/api';
|
||||||
import { QUERY_KEYS } from '@/constants/QUERY_KEYS';
|
import { QUERY_KEYS } from '@/constants/QUERY_KEYS';
|
||||||
import { useToast } from '@/hooks/use-toast';
|
import { useToast } from '@/hooks/use-toast';
|
||||||
@@ -1566,6 +1568,8 @@ function ExportReceivedTab({ enabled, onChanged }: { enabled: boolean; onChanged
|
|||||||
/** Export items that passed inspection and are queued to be loaded onto a train. */
|
/** Export items that passed inspection and are queued to be loaded onto a train. */
|
||||||
function ReadyToLoadTab({ enabled, onChanged }: { enabled: boolean; onChanged?: () => void }) {
|
function ReadyToLoadTab({ enabled, onChanged }: { enabled: boolean; onChanged?: () => void }) {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
const { user } = useAuth();
|
||||||
|
const canLoad = hasFreightPermission(user, FREIGHT_PERMS.warehouseInventory.load);
|
||||||
const { data: rows = [], isLoading } = useQuery(
|
const { data: rows = [], isLoading } = useQuery(
|
||||||
api.warehouses.readyToLoadExport.queryOptions({ enabled }),
|
api.warehouses.readyToLoadExport.queryOptions({ enabled }),
|
||||||
);
|
);
|
||||||
@@ -1655,16 +1659,18 @@ function ReadyToLoadTab({ enabled, onChanged }: { enabled: boolean; onChanged?:
|
|||||||
<><b>{controls.filteredRows.length}</b> item{controls.filteredRows.length !== 1 ? 's' : ''} ready to load</>
|
<><b>{controls.filteredRows.length}</b> item{controls.filteredRows.length !== 1 ? 's' : ''} ready to load</>
|
||||||
)}
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
|
<Tooltip label={canLoad ? undefined : "You don't have permission to load cargo"} disabled={canLoad} withArrow>
|
||||||
<Button
|
<Button
|
||||||
size="compact-sm"
|
size="compact-sm"
|
||||||
variant="filled"
|
variant="filled"
|
||||||
color="teal"
|
color="teal"
|
||||||
leftSection={<Truck size={14} />}
|
leftSection={<Truck size={14} />}
|
||||||
disabled={rows.length === 0}
|
disabled={rows.length === 0 || !canLoad}
|
||||||
onClick={() => setTrainPickerOpen(true)}
|
onClick={() => setTrainPickerOpen(true)}
|
||||||
>
|
>
|
||||||
{selected.size > 0 ? `Load Selected (${selected.size})` : 'Auto Load Ready Items'}
|
{selected.size > 0 ? `Load Selected (${selected.size})` : 'Auto Load Ready Items'}
|
||||||
</Button>
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
@@ -2305,6 +2311,8 @@ export function ImportArriveQueueTab({
|
|||||||
onChanged?: () => void;
|
onChanged?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
const { user } = useAuth();
|
||||||
|
const canUnload = hasFreightPermission(user, FREIGHT_PERMS.warehouseInventory.unload);
|
||||||
const { data: trains = [], isLoading } = useQuery(
|
const { data: trains = [], isLoading } = useQuery(
|
||||||
api.warehouses.importArriveQueue.queryOptions({ enabled }),
|
api.warehouses.importArriveQueue.queryOptions({ enabled }),
|
||||||
);
|
);
|
||||||
@@ -2489,12 +2497,13 @@ export function ImportArriveQueueTab({
|
|||||||
>
|
>
|
||||||
Open
|
Open
|
||||||
</Button>
|
</Button>
|
||||||
|
<Tooltip label={canUnload ? undefined : "You don't have permission to unload cargo"} disabled={canUnload} withArrow>
|
||||||
<Button
|
<Button
|
||||||
size="compact-xs"
|
size="compact-xs"
|
||||||
color={fullyUnloaded ? 'gray' : 'indigo'}
|
color={fullyUnloaded ? 'gray' : 'indigo'}
|
||||||
leftSection={<Truck size={14} />}
|
leftSection={<Truck size={14} />}
|
||||||
loading={busyId === t.scheduleId}
|
loading={busyId === t.scheduleId}
|
||||||
disabled={fullyUnloaded || t.totalBookings === 0 || !readyBySchedule[t.scheduleId] || warehousesLoading}
|
disabled={fullyUnloaded || t.totalBookings === 0 || !readyBySchedule[t.scheduleId] || warehousesLoading || !canUnload}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setConfirmAction({
|
setConfirmAction({
|
||||||
title: 'Auto unload train',
|
title: 'Auto unload train',
|
||||||
@@ -2506,6 +2515,7 @@ export function ImportArriveQueueTab({
|
|||||||
>
|
>
|
||||||
{fullyUnloaded ? 'Already Unloaded' : 'Auto Unload Arrived Bookings'}
|
{fullyUnloaded ? 'Already Unloaded' : 'Auto Unload Arrived Bookings'}
|
||||||
</Button>
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
</Group>
|
</Group>
|
||||||
</Table.Td>
|
</Table.Td>
|
||||||
</Table.Tr>
|
</Table.Tr>
|
||||||
|
|||||||
@@ -104,6 +104,9 @@ export const FREIGHT_PERMS = {
|
|||||||
view: "edr_freight_app:train_scheduling:view",
|
view: "edr_freight_app:train_scheduling:view",
|
||||||
create: "edr_freight_app:train_scheduling:create",
|
create: "edr_freight_app:train_scheduling:create",
|
||||||
update: "edr_freight_app:train_scheduling:update",
|
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",
|
cancel: "edr_freight_app:train_scheduling:cancel",
|
||||||
reschedule: "edr_freight_app:train_scheduling:reschedule",
|
reschedule: "edr_freight_app:train_scheduling:reschedule",
|
||||||
rulesManage: "edr_freight_app:train_scheduling:rules_manage",
|
rulesManage: "edr_freight_app:train_scheduling:rules_manage",
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|||||||
import { AlertTriangle, PackageCheck, PackageOpen, TrainFront, Warehouse } from "lucide-react";
|
import { AlertTriangle, PackageCheck, PackageOpen, TrainFront, Warehouse } from "lucide-react";
|
||||||
|
|
||||||
import { PageContainer, PageHeader } from "@/components/page";
|
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";
|
import ListControls from "@/components/common/ListControls";
|
||||||
// Generic list footer — already shared by the fleet and train-scheduling lists
|
// Generic list footer — already shared by the fleet and train-scheduling lists
|
||||||
// despite the ruleEngine path.
|
// despite the ruleEngine path.
|
||||||
@@ -93,6 +95,9 @@ const apiErrorMessage = (error: unknown) => {
|
|||||||
|
|
||||||
function Rows({ rows }: { rows: IntercityRideAlongRow[] }) {
|
function Rows({ rows }: { rows: IntercityRideAlongRow[] }) {
|
||||||
const { toast } = useToast();
|
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 queryClient = useQueryClient();
|
||||||
const refresh = () =>
|
const refresh = () =>
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
@@ -201,31 +206,37 @@ function Rows({ rows }: { rows: IntercityRideAlongRow[] }) {
|
|||||||
<Group gap="xs" justify="flex-end" wrap="nowrap">
|
<Group gap="xs" justify="flex-end" wrap="nowrap">
|
||||||
{/* Work the cargo right here while the train is at the yard. */}
|
{/* Work the cargo right here while the train is at the yard. */}
|
||||||
{r.trainScheduleId && atOrigin(r) && isWaiting(r) && r.status === "PAID" && (
|
{r.trainScheduleId && atOrigin(r) && isWaiting(r) && r.status === "PAID" && (
|
||||||
|
<Tooltip label={canLoad ? undefined : "You don't have permission to load cargo"} disabled={canLoad}>
|
||||||
<Button
|
<Button
|
||||||
size="compact-xs"
|
size="compact-xs"
|
||||||
variant="light"
|
variant="light"
|
||||||
leftSection={<PackageCheck size={13} />}
|
leftSection={<PackageCheck size={13} />}
|
||||||
loading={load.isPending}
|
loading={load.isPending}
|
||||||
|
disabled={!canLoad}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
load.mutate({ scheduleId: r.trainScheduleId as string, bookingId: r.bookingId })
|
load.mutate({ scheduleId: r.trainScheduleId as string, bookingId: r.bookingId })
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Load
|
Load
|
||||||
</Button>
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
{r.trainScheduleId && atDestination(r) && isRiding(r) && (
|
{r.trainScheduleId && atDestination(r) && isRiding(r) && (
|
||||||
|
<Tooltip label={canUnload ? undefined : "You don't have permission to unload cargo"} disabled={canUnload}>
|
||||||
<Button
|
<Button
|
||||||
size="compact-xs"
|
size="compact-xs"
|
||||||
variant="light"
|
variant="light"
|
||||||
color="orange"
|
color="orange"
|
||||||
leftSection={<PackageOpen size={13} />}
|
leftSection={<PackageOpen size={13} />}
|
||||||
loading={unload.isPending}
|
loading={unload.isPending}
|
||||||
|
disabled={!canUnload}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
unload.mutate({ scheduleId: r.trainScheduleId as string, bookingId: r.bookingId })
|
unload.mutate({ scheduleId: r.trainScheduleId as string, bookingId: r.bookingId })
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Unload
|
Unload
|
||||||
</Button>
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
</Group>
|
</Group>
|
||||||
</Table.Td>
|
</Table.Td>
|
||||||
|
|||||||
Reference in New Issue
Block a user