feat(admin): 管理端 UI/UX 深度优化——错误/加载/空状态、表单快捷键、移动端适配与无障碍
This commit is contained in:
@@ -7,12 +7,13 @@ import api from '../../api';
|
||||
import PermissionButton from '../../components/PermissionButton';
|
||||
import EditableCell from '../../components/EditableCell';
|
||||
import { message } from '../../ui/app-message';
|
||||
import { RefreshButton } from '../../components/RefreshButton';
|
||||
import { usePermission } from '../../hooks/usePermission';
|
||||
import { useApiMutation } from '../../hooks/useApiMutation';
|
||||
import { validateResponse } from '../../utils/validate';
|
||||
import { organizationsSchema } from '../../api/schemas';
|
||||
import { useDirtyGuard } from '../../hooks/useDirtyGuard';
|
||||
import { QueryEmpty } from '../../components/QueryState';
|
||||
import { QueryEmpty, QueryErrorState } from '../../components/QueryState';
|
||||
|
||||
const PRESET_COLORS = [
|
||||
'#ff7875',
|
||||
@@ -59,21 +60,15 @@ const OrganizationsPage: React.FC = () => {
|
||||
const [searchText, setSearchText] = useState('');
|
||||
const [filterStatus, setFilterStatus] = useState<string>();
|
||||
|
||||
const { data = [], isLoading, isFetching } = useQuery({
|
||||
const { data = [], isLoading, isFetching, isError, refetch } = useQuery({
|
||||
queryKey: ['organizations'],
|
||||
queryFn: async () => {
|
||||
try {
|
||||
return validateResponse<OrganizationItem[]>(
|
||||
organizationsSchema,
|
||||
await api.get<OrganizationItem[]>('/organizations', {
|
||||
params: { includeArchived: true },
|
||||
}),
|
||||
);
|
||||
} catch (error: any) {
|
||||
message.error(error?.message || '机构数据加载失败');
|
||||
return [];
|
||||
}
|
||||
},
|
||||
queryFn: async () =>
|
||||
validateResponse<OrganizationItem[]>(
|
||||
organizationsSchema,
|
||||
await api.get<OrganizationItem[]>('/organizations', {
|
||||
params: { includeArchived: true },
|
||||
}),
|
||||
),
|
||||
});
|
||||
const loading = isLoading || isFetching;
|
||||
|
||||
@@ -385,6 +380,7 @@ const OrganizationsPage: React.FC = () => {
|
||||
]}
|
||||
/>
|
||||
</Space>
|
||||
<RefreshButton loading={isFetching} onRefresh={() => void refetch()} />
|
||||
<PermissionButton
|
||||
permission="organization:create"
|
||||
type="primary"
|
||||
@@ -394,31 +390,39 @@ const OrganizationsPage: React.FC = () => {
|
||||
添加机构
|
||||
</PermissionButton>
|
||||
</div>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={filteredData}
|
||||
rowKey="id"
|
||||
loading={loading}
|
||||
locale={{
|
||||
emptyText: (
|
||||
<QueryEmpty
|
||||
description="暂无机构"
|
||||
action={
|
||||
hasPermission('organization:create')
|
||||
? { label: '添加机构', icon: <PlusOutlined />, onClick: () => openEditor() }
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
scroll={{ x: 1100 }}
|
||||
pagination={{
|
||||
defaultPageSize: 20,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: [20, 50, 100],
|
||||
showTotal: (total) => `共 ${total} 个机构`,
|
||||
}}
|
||||
/>
|
||||
{isError ? (
|
||||
<QueryErrorState
|
||||
title="机构数据加载失败"
|
||||
description="请检查网络后重试。"
|
||||
onRetry={() => void refetch()}
|
||||
/>
|
||||
) : (
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={filteredData}
|
||||
rowKey="id"
|
||||
loading={loading}
|
||||
locale={{
|
||||
emptyText: (
|
||||
<QueryEmpty
|
||||
description="暂无机构"
|
||||
action={
|
||||
hasPermission('organization:create')
|
||||
? { label: '添加机构', icon: <PlusOutlined />, onClick: () => openEditor() }
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
scroll={{ x: 1100 }}
|
||||
pagination={{
|
||||
defaultPageSize: 20,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: [20, 50, 100],
|
||||
showTotal: (total) => `共 ${total} 个机构`,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Modal
|
||||
title={editing ? `编辑机构 · ${editing.name}` : '添加外部机构'}
|
||||
open={modalOpen}
|
||||
|
||||
Reference in New Issue
Block a user