import { useEffect, useState } from '@wordpress/element'; import { useQuery } from '@tanstack/react-query'; import { Spinner } from '../spinner/Spinner'; import { Alert, Button, Dialog, DialogActions, DialogContent, DialogTitle, Paper, Table, TableBody, TableCell, TableContainer, TableFooter, TableHead, TablePagination, TableRow, } from '@mui/material'; import { renderBadge } from '../../shared/renderBadge'; import { renderTimestamp } from '../../shared/renderTimestamp'; import type { Dictionary } from '../../models/dictionary'; import { Params } from '../../models/params'; import { useParams, useSearchParams } from 'react-router-dom'; import { renderNumber } from '../../shared/renderNumber'; interface Details { value: Dictionary; messages?: string[]; failures?: string[]; id: number; row: number; } interface DialogProps { details: Details; open: boolean; onClose: () => void; } interface Props { queryKey: string; queryFn: (id: number | string, params: Params) => Promise; setBreadcrumbs: React.Dispatch< React.SetStateAction< { label: string; href?: string; to?: string; }[] > >; } const UploadDetailsDialog = (props: DialogProps) => { const { details, onClose, open } = props; const handleClose = () => { onClose(); }; return ( {details ? ( <> Row {details.row} details Header Value {Object.entries(details.value).map((row) => ( {row[0]} {row[1]} ))}
) : null}
); }; export const UploadShow = (props: Props) => { const DEFAULT_PAGE = 1; const DEFAULT_PER_PAGE = 10; const { queryFn, queryKey, setBreadcrumbs } = props; const [searchParams, setSearchParams] = useSearchParams({ page: DEFAULT_PAGE.toString(), perPage: DEFAULT_PER_PAGE.toString(), }); const { id } = useParams(); const page = searchParams.get('page'); const perPage = searchParams.get('perPage'); const [details, setDetails] = useState
(); const [open, setOpen] = useState(false); const [hasResolved, setResolved] = useState(false); const handleClickOpen = (value: Details) => { setDetails(value); setOpen(true); }; const handleClose = () => { setOpen(false); }; const handlePageChange = ( event: React.MouseEvent | null, newPage: number ) => { setSearchParams({ page: (newPage + 1).toString(), perPage, }); }; const handleRowsPerPageChange = ( event: React.ChangeEvent ) => { setSearchParams({ page, perPage: event.target.value, }); }; const { data, isLoading, isSuccess, isError, error } = useQuery({ queryKey: [queryKey, page, perPage], queryFn: () => queryFn(id, { page, perPage }), }); // Set hasResolved once so that the breadcrumbs can be updated only once after the data loads. useEffect(() => { if (data && !hasResolved) { setResolved(true); } }, [data]); // Update the breadcrumbs once the query has resolved, useEffect(() => { if (hasResolved) { setBreadcrumbs((prev) => [ ...prev, { label: data.filename, href: location.href, }, ]); } }, [hasResolved]); return ( <> {isLoading && } {isError && ( {`An error has occurred: ${error.message}`} )} {isSuccess && ( <>

{data.filename}

ID Filename Status Rows* Processed Uploaded Started Completed {data.id} {data.filename} {renderBadge(data.status)} {renderNumber(data.total_records)} {renderNumber(data.processed_records)} {renderTimestamp(data.uploaded_at)} {renderTimestamp(data.started_at)} {renderTimestamp(data.finished_at)}

*Empty rows are included in this count.

{data.success.data.length ? ( <>

Processed

Row Messages Details {data.success.data.map( (row: Details) => ( {row.row} {row.messages.join(' ')} ) )} {data.success.total ? ( ) : null}
) : null} {data.failures.data.length ? ( <>

Failures

Row Messages Details {data.failures.data.map( (row: Details) => ( {row.row} {row.failures.join(' ')} ) )} {data.failures.total ? ( ) : null}
) : null} {JSON.stringify} )} ); };