Refactor EmbeddedActiveEquipmentPage to use custom data fetching and remove Authenticated wrapper from App component
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
import { Admin, Authenticated, CustomRoutes, Resource } from 'react-admin';
|
import { Admin, Resource } from 'react-admin';
|
||||||
import { Route } from 'react-router-dom';
|
|
||||||
import { authProvider } from './auth/authProvider';
|
import { authProvider } from './auth/authProvider';
|
||||||
import { dataProvider } from './dataProvider';
|
import { dataProvider } from './dataProvider';
|
||||||
import { EmbeddedActiveEquipmentPage } from './pages/EmbeddedActiveEquipmentPage';
|
import { EmbeddedActiveEquipmentPage } from './pages/EmbeddedActiveEquipmentPage';
|
||||||
@@ -13,18 +12,12 @@ import { EquipmentStatusChangeList } from './resources/equipment-status-change/E
|
|||||||
import { EquipmentStatusChangeShow } from './resources/equipment-status-change/EquipmentStatusChangeShow';
|
import { EquipmentStatusChangeShow } from './resources/equipment-status-change/EquipmentStatusChangeShow';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
if (window.location.pathname === '/embedded/equipment-active') {
|
||||||
|
return <EmbeddedActiveEquipmentPage />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Admin dataProvider={dataProvider} authProvider={authProvider}>
|
<Admin dataProvider={dataProvider} authProvider={authProvider}>
|
||||||
<CustomRoutes noLayout>
|
|
||||||
<Route
|
|
||||||
path="/embedded/equipment-active"
|
|
||||||
element={
|
|
||||||
<Authenticated>
|
|
||||||
<EmbeddedActiveEquipmentPage />
|
|
||||||
</Authenticated>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</CustomRoutes>
|
|
||||||
<Resource
|
<Resource
|
||||||
name="equipment"
|
name="equipment"
|
||||||
list={EquipmentList}
|
list={EquipmentList}
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ import TableContainer from '@mui/material/TableContainer';
|
|||||||
import TableHead from '@mui/material/TableHead';
|
import TableHead from '@mui/material/TableHead';
|
||||||
import TableRow from '@mui/material/TableRow';
|
import TableRow from '@mui/material/TableRow';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import { useGetList } from 'react-admin';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { env } from '../config/env';
|
||||||
|
import { ensureFreshToken, getAccessToken } from '../auth/keycloak';
|
||||||
|
|
||||||
type EquipmentRecord = {
|
type EquipmentRecord = {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -33,12 +35,76 @@ function formatDate(value: string | null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function EmbeddedActiveEquipmentPage() {
|
export function EmbeddedActiveEquipmentPage() {
|
||||||
const { data, total, isPending, error } = useGetList<EquipmentRecord>('equipment', {
|
const [data, setData] = useState<EquipmentRecord[]>([]);
|
||||||
pagination: { page: 1, perPage: 100 },
|
const [total, setTotal] = useState<number | null>(null);
|
||||||
sort: { field: 'name', order: 'ASC' },
|
const [isPending, setIsPending] = useState(true);
|
||||||
filter: { status: ['Active'] },
|
const [error, setError] = useState<Error | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let cancelled = false;
|
||||||
|
|
||||||
|
const load = async () => {
|
||||||
|
setIsPending(true);
|
||||||
|
setError(null);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ensureFreshToken();
|
||||||
|
|
||||||
|
const token = getAccessToken();
|
||||||
|
const headers = new Headers({
|
||||||
|
Accept: 'application/json',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
headers.set('Authorization', `Bearer ${token}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = new URLSearchParams({
|
||||||
|
_start: '0',
|
||||||
|
_end: '100',
|
||||||
|
_sort: 'name',
|
||||||
|
_order: 'ASC',
|
||||||
|
});
|
||||||
|
query.append('status', 'Active');
|
||||||
|
|
||||||
|
const response = await fetch(`${env.apiUrl}/equipment?${query.toString()}`, {
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const requestError = new Error(`Request failed with status ${response.status}`) as Error & {
|
||||||
|
status?: number;
|
||||||
|
};
|
||||||
|
requestError.status = response.status;
|
||||||
|
throw requestError;
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = (await response.json()) as EquipmentRecord[];
|
||||||
|
const contentRange = response.headers.get('Content-Range');
|
||||||
|
const parsedTotal = contentRange?.match(/\/(\d+)$/)?.[1];
|
||||||
|
|
||||||
|
if (!cancelled) {
|
||||||
|
setData(payload);
|
||||||
|
setTotal(parsedTotal ? Number(parsedTotal) : payload.length);
|
||||||
|
}
|
||||||
|
} catch (caughtError) {
|
||||||
|
if (!cancelled) {
|
||||||
|
setError(caughtError instanceof Error ? caughtError : new Error('Unknown error'));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (!cancelled) {
|
||||||
|
setIsPending(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void load();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
cancelled = true;
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ minHeight: '100vh', boxSizing: 'border-box', p: { xs: 2, md: 3 }, bgcolor: '#f3f6fa' }}>
|
<Box sx={{ minHeight: '100vh', boxSizing: 'border-box', p: { xs: 2, md: 3 }, bgcolor: '#f3f6fa' }}>
|
||||||
<Paper elevation={0} sx={{ overflow: 'hidden', borderRadius: 3, border: '1px solid #d7e0ea' }}>
|
<Paper elevation={0} sx={{ overflow: 'hidden', borderRadius: 3, border: '1px solid #d7e0ea' }}>
|
||||||
|
|||||||
Reference in New Issue
Block a user