R96 U1-U7 精简页面设计与文案
这个提交包含在:
@@ -242,7 +242,7 @@ export function CutoverConsolePage() {
|
||||
onSuccess: async () => {
|
||||
setDryRunFile(null);
|
||||
await refresh();
|
||||
toast.success("dry-run 已完成");
|
||||
toast.success("演练已完成");
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error(resolveErrorMessage(error));
|
||||
@@ -319,32 +319,32 @@ export function CutoverConsolePage() {
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<PageHeader title="切换控制台" subtitle="聚焦范围开关、延迟生效和 dry-run 验证,不改 Cutover 核心模型。" />
|
||||
<PageHeader title="切换控制台" subtitle="范围开关和导入演练。" />
|
||||
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<div className="card-std p-5">
|
||||
<div className="text-sm text-zinc-500">已启用</div>
|
||||
<div className="mt-2 text-3xl font-semibold text-emerald-600">{summary.active}</div>
|
||||
<div className="mt-1 text-xs text-zinc-500">enabled=true 且已到生效时间</div>
|
||||
<div className="mt-1 text-xs text-zinc-500">已到生效时间</div>
|
||||
</div>
|
||||
<div className="card-std p-5">
|
||||
<div className="text-sm text-zinc-500">已禁用</div>
|
||||
<div className="mt-2 text-3xl font-semibold text-zinc-800">{summary.disabled}</div>
|
||||
<div className="mt-1 text-xs text-zinc-500">enabled=false</div>
|
||||
<div className="mt-1 text-xs text-zinc-500">手动关闭</div>
|
||||
</div>
|
||||
<div className="card-std p-5">
|
||||
<div className="text-sm text-zinc-500">待生效</div>
|
||||
<div className="mt-2 text-3xl font-semibold text-amber-600">{summary.pending}</div>
|
||||
<div className="mt-1 text-xs text-zinc-500">enabled=true 且 startsAt > now</div>
|
||||
<div className="mt-1 text-xs text-zinc-500">等待生效时间</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SectionPanel
|
||||
title="切换范围"
|
||||
description="列表视图看当前配置,时间线视图看创建、计划生效与最近更新时间。"
|
||||
description="当前配置和时间线。"
|
||||
actions={
|
||||
<Button type="button" onClick={openCreateDialog}>
|
||||
新增 scope
|
||||
新增范围
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
@@ -368,9 +368,9 @@ export function CutoverConsolePage() {
|
||||
<TableHeader>
|
||||
<tr>
|
||||
<TableHead>类型</TableHead>
|
||||
<TableHead>范围 Key</TableHead>
|
||||
<TableHead>范围标识</TableHead>
|
||||
<TableHead>状态</TableHead>
|
||||
<TableHead>startsAt</TableHead>
|
||||
<TableHead>生效时间</TableHead>
|
||||
<TableHead>倒计时</TableHead>
|
||||
<TableHead>备注</TableHead>
|
||||
<TableHead className="w-40">操作</TableHead>
|
||||
@@ -453,10 +453,10 @@ export function CutoverConsolePage() {
|
||||
</SectionPanel>
|
||||
|
||||
<div className="grid gap-6 xl:grid-cols-[360px,1fr]">
|
||||
<SectionPanel title="上传 dry-run CSV" description="导入 CSV 前先做演练,减少正式迁移时的意外。">
|
||||
<SectionPanel title="上传演练 CSV" description="导入前先演练。">
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label>runType</Label>
|
||||
<Label>演练类型</Label>
|
||||
<select
|
||||
className="select-std"
|
||||
value={dryRunType}
|
||||
@@ -478,12 +478,12 @@ export function CutoverConsolePage() {
|
||||
disabled={dryRunMutation.isPending}
|
||||
onClick={() => dryRunMutation.mutate()}
|
||||
>
|
||||
{dryRunMutation.isPending ? "执行中..." : "执行 dry-run"}
|
||||
{dryRunMutation.isPending ? "执行中..." : "执行演练"}
|
||||
</Button>
|
||||
</div>
|
||||
</SectionPanel>
|
||||
|
||||
<SectionPanel title="最近 dry-run" description="保留最近演练记录,方便核对上传文件与结果。">
|
||||
<SectionPanel title="最近演练" description="核对上传文件和结果。">
|
||||
{runsQuery.isLoading ? <TableSkeleton columns={1} rows={3} /> : null}
|
||||
{runsQuery.isError ? (
|
||||
<p className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-600">
|
||||
@@ -502,7 +502,7 @@ export function CutoverConsolePage() {
|
||||
</div>
|
||||
))}
|
||||
{!runsQuery.data?.items?.length ? (
|
||||
<div className="text-sm text-zinc-500">暂无 dry-run 记录</div>
|
||||
<div className="text-sm text-zinc-500">暂无演练记录</div>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
@@ -552,7 +552,7 @@ export function CutoverConsolePage() {
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label>范围 Key</Label>
|
||||
<Label>范围标识</Label>
|
||||
<Input
|
||||
disabled={Boolean(editingScope)}
|
||||
value={scopeForm.scopeKey}
|
||||
@@ -562,12 +562,12 @@ export function CutoverConsolePage() {
|
||||
scopeKey: event.target.value,
|
||||
}))
|
||||
}
|
||||
placeholder="部门 ID / 法体 ID / domain key"
|
||||
placeholder="部门 ID / 法体 ID / 业务域"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label>startsAt</Label>
|
||||
<Label>生效时间</Label>
|
||||
<Input
|
||||
type="datetime-local"
|
||||
value={scopeForm.startsAt}
|
||||
@@ -607,7 +607,7 @@ export function CutoverConsolePage() {
|
||||
}
|
||||
type="checkbox"
|
||||
/>
|
||||
启用该 scope
|
||||
启用该范围
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户