UsersListPage.tsx
2.98 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 { useEffect, useState, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { Alert, Button, Space } from 'antd';
import { usersApi } from '../../api/users';
import type { UserListItem, UsersListQuery } from '../../api/users';
import { BizError, isBizError } from '../../api/errors';
import { ERROR_MESSAGES } from './usersConstants';
import UsersToolbar from './UsersToolbar';
import UsersFilterBar from './UsersFilterBar';
import type { UsersFilterValues } from './UsersFilterBar';
import UsersTable from './UsersTable';
export default function UsersListPage() {
const navigate = useNavigate();
const [query, setQuery] = useState<UsersListQuery>({
page: 1,
size: 20,
sortField: 'tCreateDate',
sortOrder: 'desc',
});
const [records, setRecords] = useState<UserListItem[]>([]);
const [total, setTotal] = useState(0);
const [loading, setLoading] = useState(false);
const [errorMessage, setErrorMessage] = useState<string | null>(null);
const fetchList = useCallback(async (q: UsersListQuery) => {
setLoading(true);
setErrorMessage(null);
try {
const result = await usersApi.list(q);
setRecords(result.records);
setTotal(result.total);
} catch (e) {
if (isBizError(e)) {
if (e.code === -1) setErrorMessage(ERROR_MESSAGES.NETWORK as string);
else setErrorMessage(e.message || (ERROR_MESSAGES.UNKNOWN as string));
} else {
setErrorMessage(ERROR_MESSAGES.UNKNOWN as string);
}
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
fetchList(query);
}, [query, fetchList]);
const handleSearch = (filterValues: UsersFilterValues) => {
setQuery((prev) => ({
...prev,
page: 1,
queryField: filterValues.queryField,
matchMode: filterValues.matchMode,
queryValue: filterValues.queryValue,
}));
};
const handleReset = () => {
setQuery({ page: 1, size: query.size });
};
const handleRefresh = () => fetchList(query);
return (
<div data-testid="users-list-page" style={{ padding: 16, background: 'var(--color-bg-page)' }}>
<UsersToolbar onRefresh={handleRefresh} onAdd={() => navigate('/users/new')} />
<UsersFilterBar onSearch={handleSearch} onReset={handleReset} disabled={loading} />
{errorMessage && (
<Alert
type="error"
message={errorMessage}
showIcon
style={{ margin: '12px 0' }}
action={
<Space>
<Button size="small" onClick={handleRefresh}>
重试
</Button>
</Space>
}
data-testid="users-list-error"
/>
)}
<UsersTable
records={records}
loading={loading}
total={total}
page={query.page ?? 1}
size={query.size ?? 20}
onRowClick={(row) => navigate(`/users/${row.userId}`)}
onPageChange={(page, size) => setQuery((prev) => ({ ...prev, page, size }))}
/>
</div>
);
}