-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathadmin_list.tsx
More file actions
96 lines (85 loc) · 3.82 KB
/
admin_list.tsx
File metadata and controls
96 lines (85 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { useBackendAdminClient, useChoicesQuery, useListQuery, useOpenApiSchemaQuery } from "@frontend/common/src/hooks/useAdminAPI";
import { extractQueryParameters } from "@frontend/common/src/utils";
import { Add } from "@mui/icons-material";
import { Box, Button, CircularProgress, Stack, Table, TableBody, TableCell, TableHead, TableRow, Typography } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
import * as React from "react";
import { Link, useNavigate, useSearchParams } from "react-router-dom";
import { AdminListFilter } from "../elements/admin_list_filter";
import { BackendAdminSignInGuard } from "../elements/admin_signin_guard";
import { ErrorFallback } from "../elements/error_fallback";
type AdminListProps = {
app: string;
resource: string;
hideCreatedAt?: boolean;
hideUpdatedAt?: boolean;
hideCreateNew?: boolean;
};
type ListRowType = {
id: string;
str_repr: string;
created_at: string;
updated_at: string;
};
const InnerAdminList: React.FC<AdminListProps> = ErrorBoundary.with(
{ fallback: ErrorFallback },
Suspense.with({ fallback: <CircularProgress /> }, ({ app, resource, hideCreatedAt, hideUpdatedAt, hideCreateNew }) => {
const navigate = useNavigate();
const [searchParams, setSearchParams] = useSearchParams();
const backendAdminClient = useBackendAdminClient();
const filterParams: Record<string, string> = Object.fromEntries(searchParams.entries());
const listQuery = useListQuery<ListRowType>(backendAdminClient, app, resource, filterParams);
const openApiSchemaQuery = useOpenApiSchemaQuery(backendAdminClient);
const queryParameters = React.useMemo(
() => extractQueryParameters(openApiSchemaQuery.data, app, resource),
[openApiSchemaQuery.data, app, resource]
);
const choicesQuery = useChoicesQuery(backendAdminClient, app, resource);
const handleFilterApply = (newParams: Record<string, string>) => setSearchParams(newParams, { replace: true });
return (
<Stack sx={{ flexGrow: 1, width: "100%", minHeight: "100%" }}>
<Typography variant="h5">
{app.toUpperCase()} > {resource.toUpperCase()} > 목록
</Typography>
<br />
<AdminListFilter parameters={queryParameters} values={filterParams} choices={choicesQuery.data} onApply={handleFilterApply} />
<Box>
{!hideCreateNew && (
<Button variant="contained" onClick={() => navigate(`/${app}/${resource}/create`)} startIcon={<Add />}>
새 객체 추가
</Button>
)}
</Box>
<Table>
<TableHead>
<TableRow>
<TableCell sx={{ width: "25%" }}>ID</TableCell>
<TableCell sx={{ width: "40%" }}>이름</TableCell>
{hideCreatedAt === true && <TableCell sx={{ width: "17.5%" }}>생성 시간</TableCell>}
{hideUpdatedAt === true && <TableCell sx={{ width: "17.5%" }}>수정 시간</TableCell>}
</TableRow>
</TableHead>
<TableBody>
{listQuery.data?.map((item) => (
<TableRow key={item.id}>
<TableCell>
<Link to={`/${app}/${resource}/${item.id}`}>{item.id}</Link>
</TableCell>
<TableCell>
<Link to={`/${app}/${resource}/${item.id}`}>{item.str_repr}</Link>
</TableCell>
{!hideCreatedAt && <TableCell>{new Date(item.created_at).toLocaleString()}</TableCell>}
{!hideUpdatedAt && <TableCell>{new Date(item.updated_at).toLocaleString()}</TableCell>}
</TableRow>
))}
</TableBody>
</Table>
</Stack>
);
})
);
export const AdminList: React.FC<AdminListProps> = (props) => (
<BackendAdminSignInGuard>
<InnerAdminList {...props} />
</BackendAdminSignInGuard>
);