feat: unify governance evidence workbenches
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { IconChevronDown, IconChevronRight, IconClose, IconDownload, IconMore, IconRefresh, IconSave, IconSearch, IconSetting } from '@douyinfe/semi-icons';
|
||||
import { Button, Card, CardGroup, Collapse, Descriptions, Dropdown, Empty, Input, Select, SideSheet, Spin, Table, Tag, Typography } from '@douyinfe/semi-ui';
|
||||
import { Button, Card, CardGroup, Collapse, Descriptions, Dropdown, Empty, Input, Select, Spin, Table, Tag, Typography } from '@douyinfe/semi-ui';
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { FormEvent, KeyboardEvent, memo, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Link, useSearchParams } from 'react-router-dom';
|
||||
@@ -15,6 +15,7 @@ import { WorkspaceCommandBar } from '../shared/WorkspaceCommandBar';
|
||||
import { WorkspaceDetailSideSheet } from '../shared/WorkspaceDetailSideSheet';
|
||||
import { WorkspaceFilterPanel } from '../shared/WorkspaceFilterPanel';
|
||||
import { WorkspacePanelHeader } from '../shared/WorkspacePanelHeader';
|
||||
import { WorkspaceSideSheet } from '../shared/WorkspaceSideSheet';
|
||||
import { detailTriggerRow } from '../shared/detailTriggerRow';
|
||||
import { usePlatformSession } from '../auth/AuthGate';
|
||||
import { canAdminister } from '../auth/session';
|
||||
@@ -356,7 +357,6 @@ export default function AccessPage() {
|
||||
}, [mobileLayout]);
|
||||
const rows = vehiclesQuery.data?.items ?? []; const selected = rows.find((row) => row.vin === selectedVIN);
|
||||
const mobileFiltersOpen = mobileLayout && !filtersCollapsed;
|
||||
useSideSheetA11y(editable && governanceOpen, '.v2-access-governance-sidesheet', 'v2-access-governance', '接入治理配置', '关闭接入治理配置');
|
||||
useSideSheetA11y(mobileFiltersOpen, '.v2-access-mobile-filter-sidesheet', 'v2-access-mobile-filters', '接入车辆筛选', '关闭接入车辆筛选');
|
||||
const syncURL = (filters: Filters) => { const next = new URLSearchParams(); Object.entries(filters).forEach(([key, value]) => { if (value) next.set(key, value); }); setSearchParams(next, { replace: true }); };
|
||||
const apply = (next: Filters) => { setDraft(next); setCriteria(next); setOffset(0); setSelectedVIN(''); syncURL(next); };
|
||||
@@ -505,28 +505,49 @@ export default function AccessPage() {
|
||||
>
|
||||
{selected ? <VehicleInspector key={selected.vin} row={selected} onClose={() => setSelectedVIN('')} sheet mobile={mobileLayout} /> : null}
|
||||
</WorkspaceDetailSideSheet>
|
||||
{editable ? <SideSheet
|
||||
{editable ? <WorkspaceSideSheet
|
||||
className="v2-access-governance-sidesheet"
|
||||
variant="config"
|
||||
visible={governanceOpen}
|
||||
aria-label="接入治理配置"
|
||||
ariaLabel="接入治理配置"
|
||||
closeLabel="关闭接入治理配置"
|
||||
placement={mobileLayout ? 'bottom' : 'right'}
|
||||
width={mobileLayout ? undefined : 560}
|
||||
height={mobileLayout ? 'min(86dvh, 760px)' : undefined}
|
||||
title={<div className="v2-access-sheet-title"><strong>接入治理</strong><span>集中处理待绑定来源与在线判定阈值</span></div>}
|
||||
height={mobileLayout ? 'min(88dvh, 780px)' : undefined}
|
||||
title="接入治理工作台"
|
||||
description="核对待绑定来源,统一维护协议在线判定阈值"
|
||||
badge={(unresolvedQuery.data?.total ?? 0) > 0 ? `${unresolvedQuery.data?.total.toLocaleString('zh-CN')} 项待办` : '治理正常'}
|
||||
badgeColor={(unresolvedQuery.data?.total ?? 0) > 0 ? 'orange' : 'green'}
|
||||
summaryItems={[
|
||||
{
|
||||
label: '待绑定来源',
|
||||
value: (unresolvedQuery.data?.total ?? 0).toLocaleString('zh-CN'),
|
||||
detail: (unresolvedQuery.data?.total ?? 0) > 0 ? '需要核对权威 VIN' : '当前没有身份待办',
|
||||
tone: (unresolvedQuery.data?.total ?? 0) > 0 ? 'warning' : 'success'
|
||||
},
|
||||
{
|
||||
label: '阈值版本',
|
||||
value: `v${thresholdQuery.data?.version ?? '—'}`,
|
||||
detail: '在线与延迟统一口径',
|
||||
tone: 'primary'
|
||||
},
|
||||
{
|
||||
label: '主车辆口径',
|
||||
value: (summary?.totalVehicles ?? 0).toLocaleString('zh-CN'),
|
||||
detail: '仅统计权威主车辆',
|
||||
tone: 'neutral'
|
||||
}
|
||||
]}
|
||||
footerNote="阈值保存后即时生效;关闭工作台不会丢失已保存配置"
|
||||
primaryAction={{ label: '完成', onClick: () => setGovernanceOpen(false) }}
|
||||
onCancel={() => setGovernanceOpen(false)}
|
||||
footer={<Button theme="solid" onClick={() => setGovernanceOpen(false)}>完成</Button>}
|
||||
>
|
||||
{governanceOpen ? <div className="v2-access-governance">
|
||||
<Card className="v2-access-governance-summary" bodyStyle={{ padding: 0 }}>
|
||||
<div className={(unresolvedQuery.data?.total ?? 0) > 0 ? 'is-attention' : ''}><small>待绑定来源</small><strong>{(unresolvedQuery.data?.total ?? 0).toLocaleString('zh-CN')}</strong><span>{(unresolvedQuery.data?.total ?? 0) > 0 ? '优先处理' : '暂无待办'}</span></div>
|
||||
<div><small>阈值版本</small><strong>v{thresholdQuery.data?.version ?? '—'}</strong></div>
|
||||
<div><small>主车辆口径</small><strong>{(summary?.totalVehicles ?? 0).toLocaleString('zh-CN')}</strong></div>
|
||||
</Card>
|
||||
{unresolvedQuery.isError ? <InlineError message={unresolvedQuery.error instanceof Error ? unresolvedQuery.error.message : '待绑定身份读取失败'} onRetry={() => unresolvedQuery.refetch()} /> : null}
|
||||
<IdentityQueue items={unresolvedQuery.data?.items ?? []} total={unresolvedQuery.data?.total ?? 0} />
|
||||
{thresholdQuery.isError ? <InlineError message={thresholdQuery.error instanceof Error ? thresholdQuery.error.message : '接入阈值读取失败'} onRetry={() => thresholdQuery.refetch()} /> : null}
|
||||
<ThresholdSettings config={thresholdQuery.data} draft={thresholdDraft} editable saving={updateThreshold.isPending} error={updateThreshold.error instanceof Error ? updateThreshold.error.message : undefined} onChange={setThresholdDraft} onSave={() => thresholdDraft && updateThreshold.mutate(thresholdDraft)} />
|
||||
</div> : null}
|
||||
</SideSheet> : null}
|
||||
</WorkspaceSideSheet> : null}
|
||||
</div>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user