Align frontend with updated OpenAPI schema and PATCH operation #13
@@ -19,7 +19,7 @@ import WarningAmberIcon from "@mui/icons-material/WarningAmber";
|
||||
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
|
||||
import RemoveCircleOutlineIcon from "@mui/icons-material/RemoveCircleOutline";
|
||||
import FiberManualRecordIcon from "@mui/icons-material/FiberManualRecord";
|
||||
import { useResource, useItemSse, DetailFieldRenderer } from "../../react-openapi";
|
||||
import { useResource, useItemSse, useAppContext, DetailFieldRenderer, applyDisplayFormat } from "../../react-openapi";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { RETRY_MAX, formatApiError } from "../features/fetch-requests";
|
||||
import type { FetchRequestStatus, SSEEvent, ProgressMessage } from "../features/fetch-requests";
|
||||
@@ -71,6 +71,7 @@ export default function FetchRequestDetail() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const navigate = useNavigate();
|
||||
const { get, patch, resource } = useResource("fetch-requests");
|
||||
const { resources: allResources } = useAppContext();
|
||||
const [stepStats, setStepStats] = useState<Record<string, number>>({});
|
||||
const [liveParsedCount, setLiveParsedCount] = useState<number | undefined>(undefined);
|
||||
const [retrying, setRetrying] = useState(false);
|
||||
@@ -158,6 +159,29 @@ export default function FetchRequestDetail() {
|
||||
}
|
||||
};
|
||||
|
||||
const req = fetchRequest as any;
|
||||
const retryCount = req?.retry_count ?? 0;
|
||||
const isRetryExhausted = retryCount >= RETRY_MAX;
|
||||
const status = req?.status as FetchRequestStatus | undefined;
|
||||
const detailFields = (resource?.orderedFields ?? []).filter(
|
||||
(f) => f.name !== "source",
|
||||
);
|
||||
|
||||
const displayTitle = useMemo(() => {
|
||||
if (!resource || !req) return "";
|
||||
const resolved = Object.fromEntries(
|
||||
resource.orderedFields.map((field) => {
|
||||
const value = req[field.name];
|
||||
if (field.fk && typeof value === "object" && value != null) {
|
||||
const target = allResources.find((r) => r.name === field.fk!.resource);
|
||||
if (target) return [field.name, applyDisplayFormat(value, target.displayFormat)];
|
||||
}
|
||||
return [field.name, value];
|
||||
}),
|
||||
);
|
||||
return applyDisplayFormat(resolved, resource.displayFormat);
|
||||
}, [resource, req, allResources]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Box sx={{ display: "flex", justifyContent: "center", p: 8 }}>
|
||||
@@ -177,15 +201,6 @@ export default function FetchRequestDetail() {
|
||||
);
|
||||
}
|
||||
|
||||
const req = fetchRequest as any;
|
||||
const retryCount = req.retry_count ?? 0;
|
||||
const isRetryExhausted = retryCount >= RETRY_MAX;
|
||||
const status = req.status as FetchRequestStatus;
|
||||
|
||||
const detailFields = (resource?.orderedFields ?? []).filter(
|
||||
(f) => f.name !== "source",
|
||||
);
|
||||
|
||||
return (
|
||||
<Container sx={{ mt: 4, mb: 4 }}>
|
||||
<Button startIcon={<ArrowBackIcon />} onClick={() => navigate("/fetch-requests")} sx={{ mb: 2 }}>
|
||||
@@ -199,7 +214,7 @@ export default function FetchRequestDetail() {
|
||||
label={status.replace(/_/g, " ")}
|
||||
color={statusColors[status]}
|
||||
/>
|
||||
<Typography variant="h6" fontWeight={600}>{req.account_name}</Typography>
|
||||
<Typography variant="h6" fontWeight={600}>{displayTitle}</Typography>
|
||||
<Chip
|
||||
label={"path" in (req.source ?? {}) ? "File" : "Email"}
|
||||
size="small"
|
||||
@@ -209,14 +224,22 @@ export default function FetchRequestDetail() {
|
||||
</Box>
|
||||
|
||||
<Box sx={{ display: "flex", gap: 4, flexWrap: "wrap", mb: 2 }}>
|
||||
{detailFields.map((field) => (
|
||||
<DetailFieldRenderer
|
||||
key={field.name}
|
||||
field={field}
|
||||
value={req[field.name]}
|
||||
displayFormat={resource?.displayFormat}
|
||||
/>
|
||||
))}
|
||||
{detailFields.map((field) => {
|
||||
const value = req[field.name];
|
||||
let fmt = resource?.displayFormat;
|
||||
if (field.fk && typeof value === "object" && value != null) {
|
||||
const target = allResources.find((r) => r.name === field.fk!.resource);
|
||||
if (target) fmt = target.displayFormat;
|
||||
}
|
||||
return (
|
||||
<DetailFieldRenderer
|
||||
key={field.name}
|
||||
field={field}
|
||||
value={value}
|
||||
displayFormat={fmt}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
||||
|
||||
Reference in New Issue
Block a user