mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 23:28:11 +00:00
split export
This commit is contained in:
@@ -15,10 +15,23 @@ import {
|
||||
} from "./cookies";
|
||||
import type { AuthTokens } from "./types";
|
||||
|
||||
declare module "axios" {
|
||||
export interface AxiosRequestConfig {
|
||||
/**
|
||||
* When true, the response interceptor does NOT raise the global error modal
|
||||
* for this request's failure. For calls the caller handles itself — e.g. a
|
||||
* probe that is expected to 404 before falling back (GL clearance detail
|
||||
* tries /contracts/:id then /bookings/:id). The rejection still propagates.
|
||||
*/
|
||||
suppressErrorModal?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
type RetriableRequest = {
|
||||
_retry?: boolean;
|
||||
headers?: Record<string, string>;
|
||||
url?: string;
|
||||
suppressErrorModal?: boolean;
|
||||
};
|
||||
|
||||
const api = axios.create({
|
||||
@@ -100,8 +113,13 @@ api.interceptors.response.use(
|
||||
originalRequest.url?.includes("/auth/refresh-token")
|
||||
) {
|
||||
// Surface the server's actual error message in the global error modal
|
||||
// (401s are handled by the session-refresh flow, so skip them).
|
||||
if (error.response && error.response.status !== 401) {
|
||||
// (401s are handled by the session-refresh flow, so skip them). A request
|
||||
// may opt out via `suppressErrorModal` when it handles the failure itself.
|
||||
if (
|
||||
error.response &&
|
||||
error.response.status !== 401 &&
|
||||
!originalRequest?.suppressErrorModal
|
||||
) {
|
||||
const payload = extractApiErrorPayload(error);
|
||||
if (payload) emitApiError(payload);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useParams } from "react-router-dom";
|
||||
import {
|
||||
Alert,
|
||||
Badge,
|
||||
@@ -18,7 +18,6 @@ import {
|
||||
AlertCircle,
|
||||
ClipboardList,
|
||||
FileText,
|
||||
PackagePlus,
|
||||
Upload,
|
||||
} from "lucide-react";
|
||||
import type { Freight } from "@edr/types";
|
||||
@@ -61,9 +60,12 @@ type GlClearanceDetail =
|
||||
|
||||
async function loadGlClearanceDetail(id: string): Promise<GlClearanceDetail> {
|
||||
try {
|
||||
// Probe the contract endpoints first; a booking-id row 404s here by design
|
||||
// and falls back to the booking lookup below. Suppress the global error
|
||||
// modal so that expected 404 never surfaces to the user.
|
||||
const [clearance, contract] = await Promise.all([
|
||||
contractsService.getClearance(id),
|
||||
contractsService.getById(id),
|
||||
contractsService.getClearance(id, { suppressErrorModal: true }),
|
||||
contractsService.getById(id, { suppressErrorModal: true }),
|
||||
]);
|
||||
return {
|
||||
kind: "contract",
|
||||
@@ -89,7 +91,6 @@ async function loadGlClearanceDetail(id: string): Promise<GlClearanceDetail> {
|
||||
/** Djibouti GL clearance detail — RO/DO upload and read-only upstream context. */
|
||||
export default function GlClearanceDetailPage() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const navigate = useNavigate();
|
||||
const { user } = useAuth();
|
||||
const { view, viewer } = useFileViewer();
|
||||
const [uploadKind, setUploadKind] = useState<GlClearanceUploadKind | null>(null);
|
||||
@@ -197,19 +198,6 @@ export default function GlClearanceDetailPage() {
|
||||
{hasRo ? "Replace RO" : "Upload RO"}
|
||||
</Button>
|
||||
)}
|
||||
{canCompleteBooking && shipmentBooking ? (
|
||||
<Button
|
||||
color="edr-green"
|
||||
leftSection={<PackagePlus size={16} />}
|
||||
onClick={() =>
|
||||
navigate(
|
||||
`/dashboard/contracts/${shipmentBooking.contractId}/bookings/${id}/complete`,
|
||||
)
|
||||
}
|
||||
>
|
||||
Create booking
|
||||
</Button>
|
||||
) : null}
|
||||
</Group>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -164,8 +164,11 @@ export const contractsService = {
|
||||
};
|
||||
},
|
||||
|
||||
getById: async (id: string): Promise<Freight.IContract> => {
|
||||
const response = await client.get<Freight.IContract>(C.BY_ID(id));
|
||||
getById: async (
|
||||
id: string,
|
||||
opts?: { suppressErrorModal?: boolean },
|
||||
): Promise<Freight.IContract> => {
|
||||
const response = await client.get<Freight.IContract>(C.BY_ID(id), opts);
|
||||
return unwrap(response.data) as Freight.IContract;
|
||||
},
|
||||
|
||||
@@ -258,8 +261,11 @@ export const contractsService = {
|
||||
};
|
||||
},
|
||||
|
||||
getClearance: async (id: string): Promise<Freight.ContractClearanceView> => {
|
||||
const response = await client.get(C.CLEARANCE(id));
|
||||
getClearance: async (
|
||||
id: string,
|
||||
opts?: { suppressErrorModal?: boolean },
|
||||
): Promise<Freight.ContractClearanceView> => {
|
||||
const response = await client.get(C.CLEARANCE(id), opts);
|
||||
return unwrap(response.data) as Freight.ContractClearanceView;
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user