mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 11:08:12 +00:00
fix issues
This commit is contained in:
@@ -1159,6 +1159,18 @@ export default function TrainScheduleV2DetailPage() {
|
||||
}
|
||||
/>
|
||||
|
||||
{schedule.status === "CANCELLED" && schedule.cancellationReason ? (
|
||||
<Alert
|
||||
color="red"
|
||||
variant="light"
|
||||
radius="md"
|
||||
icon={<AlertTriangle size={18} />}
|
||||
title="This schedule was cancelled"
|
||||
>
|
||||
{schedule.cancellationReason}
|
||||
</Alert>
|
||||
) : null}
|
||||
|
||||
{/* Ops signage: Train No. / Voyage No. / Direction read at a glance from
|
||||
across the room, so these stay large rather than folding into the
|
||||
numeric KpiStrip below. */}
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
Stack,
|
||||
Switch,
|
||||
Text,
|
||||
Textarea,
|
||||
TextInput,
|
||||
ThemeIcon,
|
||||
} from "@mantine/core";
|
||||
@@ -150,6 +151,9 @@ export default function TrainScheduleV2ListPage() {
|
||||
const [dispatchAt, setDispatchAt] = useState<Date | null>(null);
|
||||
// Cancelling is likewise irreversible — confirmed before the mutation fires.
|
||||
const [cancelTarget, setCancelTarget] = useState<TrainScheduleListItem | null>(null);
|
||||
// Required: the reason is stored on the schedule and shown wherever the
|
||||
// cancelled train appears, so staff downstream know why it died.
|
||||
const [cancelReason, setCancelReason] = useState("");
|
||||
const [editDateSchedule, setEditDateSchedule] = useState<TrainScheduleListItem | null>(null);
|
||||
const [routeId, setRouteId] = useState("");
|
||||
const [scheduleDate, setScheduleDate] = useState("");
|
||||
@@ -823,7 +827,10 @@ export default function TrainScheduleV2ListPage() {
|
||||
confirmed here rather than firing straight from the row menu. */}
|
||||
<Modal
|
||||
opened={cancelTarget != null}
|
||||
onClose={() => setCancelTarget(null)}
|
||||
onClose={() => {
|
||||
setCancelTarget(null);
|
||||
setCancelReason("");
|
||||
}}
|
||||
title="Cancel this schedule?"
|
||||
centered
|
||||
radius="md"
|
||||
@@ -842,23 +849,43 @@ export default function TrainScheduleV2ListPage() {
|
||||
another schedule.
|
||||
</Text>
|
||||
) : null}
|
||||
<Textarea
|
||||
label="Reason for cancelling"
|
||||
placeholder="e.g. locomotive failure, track closure, insufficient cargo"
|
||||
value={cancelReason}
|
||||
onChange={(e) => setCancelReason(e.currentTarget.value)}
|
||||
autosize
|
||||
minRows={2}
|
||||
maxLength={500}
|
||||
required
|
||||
data-autofocus
|
||||
/>
|
||||
<Group justify="flex-end" gap="sm">
|
||||
<Button variant="default" onClick={() => setCancelTarget(null)}>
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={() => {
|
||||
setCancelTarget(null);
|
||||
setCancelReason("");
|
||||
}}
|
||||
>
|
||||
Keep schedule
|
||||
</Button>
|
||||
<Button
|
||||
color="red"
|
||||
leftSection={<Ban size={16} />}
|
||||
loading={cancel.isPending}
|
||||
disabled={!cancelReason.trim()}
|
||||
onClick={async () => {
|
||||
if (!cancelTarget) return;
|
||||
if (!cancelTarget || !cancelReason.trim()) return;
|
||||
try {
|
||||
await cancel.mutateAsync({
|
||||
id: cancelTarget.id,
|
||||
freightType: cancelTarget.freightType ?? "CONTAINER",
|
||||
reason: cancelReason.trim(),
|
||||
});
|
||||
toast({ title: "Schedule cancelled" });
|
||||
setCancelTarget(null);
|
||||
setCancelReason("");
|
||||
void schedulesQuery.refetch();
|
||||
} catch (err) {
|
||||
toast({
|
||||
@@ -929,6 +956,11 @@ function TrainIdentityCell({ schedule }: { schedule: TrainScheduleListItem }) {
|
||||
</Text>
|
||||
<StatusPill status={schedule.status} />
|
||||
</Group>
|
||||
{schedule.status === "CANCELLED" && schedule.cancellationReason ? (
|
||||
<Text size="xs" c="red.7" lh={1.2} truncate title={schedule.cancellationReason}>
|
||||
{schedule.cancellationReason}
|
||||
</Text>
|
||||
) : null}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@@ -1041,6 +1073,15 @@ function ScheduleCard({
|
||||
<MetricChip value={schedule.bookingsCount} label="bkg" />
|
||||
</Group>
|
||||
|
||||
{schedule.status === "CANCELLED" && schedule.cancellationReason ? (
|
||||
<Text size="xs" c="red.7" lineClamp={2}>
|
||||
<Text span fw={600}>
|
||||
Cancelled:
|
||||
</Text>{" "}
|
||||
{schedule.cancellationReason}
|
||||
</Text>
|
||||
) : null}
|
||||
|
||||
<Group gap="xs" wrap="nowrap">
|
||||
<Button
|
||||
variant="light"
|
||||
|
||||
@@ -1043,13 +1043,17 @@ export const api = {
|
||||
),
|
||||
|
||||
cancelSchedule: endpoint<
|
||||
{ id: string; freightType?: FreightType },
|
||||
{ id: string; freightType?: FreightType; reason: string },
|
||||
TrainScheduleDetail
|
||||
>(
|
||||
"train-scheduling",
|
||||
"cancel-schedule",
|
||||
({ id, freightType }) =>
|
||||
trainSchedulingService.cancelSchedule(id, freightType ?? "CONTAINER"),
|
||||
({ id, freightType, reason }) =>
|
||||
trainSchedulingService.cancelSchedule(
|
||||
id,
|
||||
freightType ?? "CONTAINER",
|
||||
reason,
|
||||
),
|
||||
undefined,
|
||||
() => TRAIN_SCHEDULING_INVALIDATIONS,
|
||||
),
|
||||
|
||||
@@ -801,12 +801,13 @@ export const trainSchedulingService = {
|
||||
cancelSchedule: async (
|
||||
id: string,
|
||||
freightType: FreightType = "CONTAINER",
|
||||
reason?: string,
|
||||
): Promise<TrainScheduleDetail> => {
|
||||
const response = await client.post<TrainScheduleDetail>(
|
||||
pathsFor(
|
||||
freightType === "MIXED" ? undefined : freightType,
|
||||
).CANCEL_SCHEDULE(id),
|
||||
{},
|
||||
{ reason },
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
@@ -287,6 +287,9 @@ export interface BookableSchedule {
|
||||
freightType?: FreightType | null;
|
||||
status: TrainScheduleStatus | string;
|
||||
bookingWindowStatus: "OPEN" | "FULL" | "CLOSED" | string;
|
||||
/** Why the schedule was cancelled — null unless status is CANCELLED. */
|
||||
cancellationReason?: string | null;
|
||||
cancelledAt?: string | null;
|
||||
maxWagons: number;
|
||||
remainingWagons: number;
|
||||
locomotive: { id: string; code: string; name?: string | null } | null;
|
||||
@@ -637,6 +640,9 @@ export interface TrainScheduleDetail {
|
||||
id: string;
|
||||
reference?: string | null;
|
||||
status: TrainScheduleStatus | string;
|
||||
/** Why the schedule was cancelled — null unless status is CANCELLED. */
|
||||
cancellationReason?: string | null;
|
||||
cancelledAt?: string | null;
|
||||
deferredBookings?: DeferredBookingRow[];
|
||||
freightType?: FreightType | null;
|
||||
trainNumber?: string | null;
|
||||
|
||||
Reference in New Issue
Block a user