feat(admin): add ConfigSync page + close ADMIN-01/02 (AUDIT_TRACKER)
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- ADMIN-01 FIXED: ConfigSync.tsx page with ProTable + pagination - config-sync service calling GET /config/sync-logs - route + nav item + breadcrumb - backend @reserved → @connected - ADMIN-02 FALSE_POSITIVE: Logs.tsx + logs service already exist
This commit is contained in:
111
admin-v2/src/pages/ConfigSync.tsx
Normal file
111
admin-v2/src/pages/ConfigSync.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
// ============================================================
|
||||
// 配置同步日志
|
||||
// ============================================================
|
||||
|
||||
import { useState } from 'react'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { Tag, Typography } from 'antd'
|
||||
import type { ProColumns } from '@ant-design/pro-components'
|
||||
import { ProTable } from '@ant-design/pro-components'
|
||||
import { configSyncService } from '@/services/config-sync'
|
||||
import type { ConfigSyncLog } from '@/types'
|
||||
|
||||
const { Title } = Typography
|
||||
|
||||
const actionLabels: Record<string, string> = {
|
||||
push: '推送',
|
||||
merge: '合并',
|
||||
pull: '拉取',
|
||||
diff: '差异',
|
||||
}
|
||||
|
||||
const actionColors: Record<string, string> = {
|
||||
push: 'blue',
|
||||
merge: 'green',
|
||||
pull: 'cyan',
|
||||
diff: 'orange',
|
||||
}
|
||||
|
||||
export default function ConfigSync() {
|
||||
const [page, setPage] = useState(1)
|
||||
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ['config-sync', page],
|
||||
queryFn: ({ signal }) => configSyncService.list({ page, page_size: 20 }, signal),
|
||||
})
|
||||
|
||||
const columns: ProColumns<ConfigSyncLog>[] = [
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
width: 100,
|
||||
render: (_, r) => (
|
||||
<Tag color={actionColors[r.action] || 'default'}>
|
||||
{actionLabels[r.action] || r.action}
|
||||
</Tag>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '客户端指纹',
|
||||
dataIndex: 'client_fingerprint',
|
||||
width: 160,
|
||||
render: (_, r) => <code>{r.client_fingerprint.substring(0, 16)}...</code>,
|
||||
},
|
||||
{
|
||||
title: '配置键',
|
||||
dataIndex: 'config_keys',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '客户端值',
|
||||
dataIndex: 'client_values',
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
render: (_, r) => r.client_values || '-',
|
||||
},
|
||||
{
|
||||
title: '服务端值',
|
||||
dataIndex: 'saas_values',
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
render: (_, r) => r.saas_values || '-',
|
||||
},
|
||||
{
|
||||
title: '解决方式',
|
||||
dataIndex: 'resolution',
|
||||
width: 120,
|
||||
render: (_, r) => r.resolution || '-',
|
||||
},
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'created_at',
|
||||
width: 180,
|
||||
render: (_, r) => new Date(r.created_at).toLocaleString('zh-CN'),
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ marginBottom: 24 }}>
|
||||
<Title level={4} style={{ margin: 0 }}>配置同步日志</Title>
|
||||
</div>
|
||||
|
||||
<ProTable<ConfigSyncLog>
|
||||
columns={columns}
|
||||
dataSource={data?.items ?? []}
|
||||
loading={isLoading}
|
||||
rowKey="id"
|
||||
search={false}
|
||||
toolBarRender={false}
|
||||
pagination={{
|
||||
total: data?.total ?? 0,
|
||||
pageSize: 20,
|
||||
current: page,
|
||||
onChange: setPage,
|
||||
showSizeChanger: false,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user