mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 16:28:12 +00:00
Merge pull request #1052 from Tria-plc/freight_feature/usermanagement
fix issue
This commit is contained in:
@@ -72,19 +72,39 @@ function apiErrorMessage(error: unknown, fallback: string): string {
|
||||
*/
|
||||
function phaseCountdown(
|
||||
schedule: TrainScheduleDetail,
|
||||
): { label: string; deadline: string } | null {
|
||||
): { label: string; deadline: string; expiredText: string } | null {
|
||||
switch (schedule.windowPhase) {
|
||||
case "PRE_WINDOW":
|
||||
return schedule.windowOpensAt
|
||||
? {
|
||||
label: "Booking window opens in",
|
||||
deadline: schedule.windowOpensAt,
|
||||
expiredText: "Booking opening now…",
|
||||
}
|
||||
: null;
|
||||
case "OPEN":
|
||||
return schedule.windowClosesAt
|
||||
? { label: "Booking window closes in", deadline: schedule.windowClosesAt }
|
||||
? {
|
||||
label: "Booking window closes in",
|
||||
deadline: schedule.windowClosesAt,
|
||||
expiredText: "Document review starting…",
|
||||
}
|
||||
: null;
|
||||
case "DOC_REVIEW":
|
||||
return schedule.docReviewEndsAt
|
||||
? { label: "Document review ends in", deadline: schedule.docReviewEndsAt }
|
||||
? {
|
||||
label: "Document review ends in",
|
||||
deadline: schedule.docReviewEndsAt,
|
||||
expiredText: "Payment starting…",
|
||||
}
|
||||
: null;
|
||||
case "PAYMENT":
|
||||
return schedule.paymentPhaseEndsAt
|
||||
? { label: "Payment window ends in", deadline: schedule.paymentPhaseEndsAt }
|
||||
? {
|
||||
label: "Payment window ends in",
|
||||
deadline: schedule.paymentPhaseEndsAt,
|
||||
expiredText: "Payment window closing…",
|
||||
}
|
||||
: null;
|
||||
default:
|
||||
return null;
|
||||
@@ -523,7 +543,12 @@ export function ScheduleWorkspacePanel({
|
||||
border: "1px solid var(--mantine-color-blue-2)",
|
||||
}}
|
||||
>
|
||||
<CountdownTimer deadline={cd.deadline} label={cd.label} size="sm" />
|
||||
<CountdownTimer
|
||||
deadline={cd.deadline}
|
||||
label={cd.label}
|
||||
expiredText={cd.expiredText}
|
||||
size="sm"
|
||||
/>
|
||||
</Group>
|
||||
) : null;
|
||||
})()}
|
||||
|
||||
@@ -147,6 +147,12 @@ export function useBookingWindowSocket(enabled: boolean = true) {
|
||||
void qc.invalidateQueries({
|
||||
queryKey: QUERY_KEYS.TRAIN_SCHEDULING.batchBoardDetail(event.scheduleId),
|
||||
});
|
||||
// Same for the schedule detail page (workspace tab countdown reads
|
||||
// windowPhase/paymentPhaseEndsAt from it) — without this the page shows
|
||||
// the OLD phase's expired countdown through the whole import cycle.
|
||||
void qc.invalidateQueries({
|
||||
queryKey: QUERY_KEYS.TRAIN_SCHEDULING.scheduleById(event.scheduleId),
|
||||
});
|
||||
|
||||
// Always refresh the batch board (different shape, not patched). When the
|
||||
// schedule wasn't in any window list either, refresh those too so a newly
|
||||
|
||||
@@ -147,8 +147,12 @@ export default function ContractClearanceDetailPage() {
|
||||
!isDjiboutiGl(user);
|
||||
const canResubmitBooking = bookingNeedsChanges && isGlBookingOwner;
|
||||
const canRebook = bookingExpired && isGlBookingOwner;
|
||||
// Rebook completes the SAME expired booking (it already carries the price and
|
||||
// cargo from its first completion) via the /complete endpoint's EXPIRED
|
||||
// branch — routing it through create-booking instead would create a
|
||||
// duplicate booking on the contract rather than resubmitting the existing one.
|
||||
const rebookHref = linkedBookingId
|
||||
? `${bookingHref}?copyFrom=${linkedBookingId}`
|
||||
? `/dashboard/contracts/${id}/bookings/${linkedBookingId}/complete?copyFrom=${linkedBookingId}`
|
||||
: bookingHref;
|
||||
|
||||
const { data: bookingMilestones, refetch: refetchBookingMilestones } =
|
||||
|
||||
@@ -77,6 +77,7 @@ import { WagonPlanGrid } from "@/components/trainScheduling/WagonPlanGrid";
|
||||
import { WorkflowRail, WorkflowStep } from "@/components/trainScheduling/WorkflowStep";
|
||||
import { openPdfBlob } from "@/components/warehouses/pdf";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import { useBookingWindowSocket } from "@/features/bookingWindows/useBookingWindowSocket";
|
||||
import { api } from "@/services/api";
|
||||
import { trainSchedulingService } from "@/services/trainScheduling.service";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
@@ -121,8 +122,13 @@ export default function TrainScheduleV2DetailPage() {
|
||||
api.trainScheduling.scheduleDetail.queryOptions({
|
||||
input: { id: scheduleId ?? "" },
|
||||
enabled: Boolean(scheduleId),
|
||||
// Live phase updates come from the booking-window socket (PHASE pushes
|
||||
// invalidate this query); 60s is the self-heal net for a missed emit so
|
||||
// the workspace countdown never freezes on an expired phase.
|
||||
refetchInterval: 60_000,
|
||||
}),
|
||||
);
|
||||
useBookingWindowSocket(Boolean(scheduleId));
|
||||
const schedule = detailQuery.data;
|
||||
const freightType: FreightType | undefined = schedule?.freightType as FreightType | undefined;
|
||||
const isDjiboutiPort = (value?: string | null) =>
|
||||
|
||||
Reference in New Issue
Block a user