diff --git a/frontend/src/pages/SourceMaintenanceDialog.tsx b/frontend/src/pages/SourceMaintenanceDialog.tsx index 4a051770..350e8c0e 100644 --- a/frontend/src/pages/SourceMaintenanceDialog.tsx +++ b/frontend/src/pages/SourceMaintenanceDialog.tsx @@ -222,7 +222,7 @@ export function SourceMaintenanceDialog({ source, onClose, onSaved }: { {schedule && { onClose() navigate(`/data/catalog/${encodeURIComponent(source.id)}?pjob=${encodeURIComponent(id)}`) - }} onClose={onClose} />} + }} />} {extra > 0 &&

{T.extra(extra)}

} )} @@ -231,8 +231,8 @@ export function SourceMaintenanceDialog({ source, onClose, onSaved }: { } /** 已经有维护定时:下一次什么时候、最近一次建了哪些任务、哪几步没执行和原因(触发记录的 inputs),到定时任务页看全部触发 */ -function LastRun({ schedule: s, onOpenProfileJob, onClose }: { - schedule: MaintenanceSchedule; onOpenProfileJob: (id: string) => void; onClose: () => void +function LastRun({ schedule: s, onOpenProfileJob }: { + schedule: MaintenanceSchedule; onOpenProfileJob: (id: string) => void }) { const fire = s.last_fire const inputs = fire?.inputs ?? {} @@ -260,10 +260,10 @@ function LastRun({ schedule: s, onOpenProfileJob, onClose }: {
  • {T.lastJob(j.step.split('+').map((x) => T.step[x as MaintenanceStep] ?? x).join('、'), T.lastJobKind[j.kind] ?? j.kind, j.id, j.tables ?? null)} - {j.kind === 'profile' - ? - // 探查任务的进度就在这张数据源卡片上:关上对话框就看得到 - : } + {/* 剖析任务点得进进度和结果(数据目录页的剖析对话框);探查任务进行中时进度就在这张数据源卡片上,没有另外的页面 */} + {j.kind === 'profile' && ( + + )}
  • ))} diff --git a/frontend/src/pages/catalog/CatalogPage.tsx b/frontend/src/pages/catalog/CatalogPage.tsx index aefc25b7..59148def 100644 --- a/frontend/src/pages/catalog/CatalogPage.tsx +++ b/frontend/src/pages/catalog/CatalogPage.tsx @@ -397,6 +397,19 @@ export function CatalogPage() { useOnReconnect(loadChangeCounts) const actionCount = changeCounts?.src === sourceId ? changeCounts.counts.by_severity.action : 0 const onChangeCounts = useCallback((counts: SourceChangeCounts) => setChangeCounts({ src: sourceId, counts }), [sourceId]) + // 队列里有任务走了(结束了):探查读到了新的结构、剖析做了取值观察,都可能记下新的变化;探查改了表结构,清单也要重取 + // (起草、剖析结束时页面跟着的任务自己会重取清单) + const queuedIds = useRef<{ src: string; ids: Map }>({ src: '', ids: new Map() }) + useEffect(() => { + const now = new Map(sourceJobs.items.map((i) => [i.id, i.kind])) + const prev = queuedIds.current.src === sourceId ? queuedIds.current.ids : new Map() + queuedIds.current = { src: sourceId, ids: now } + const gone = [...prev].filter(([id]) => !now.has(id)).map(([, kind]) => kind) + if (!gone.length) return + loadChangeCounts() + setChangesSeq((n) => n + 1) + if (gone.includes('introspect')) void load() + }, [sourceJobs.items, sourceId, loadChangeCounts, load]) const tableProfile: TableProfileProps = useMemo(() => ({ job: profileJob, onStart: profileTable, onShowActive: profile.showActive, onSettings: () => setProfileSettingsOpen(true), diff --git a/scripts/check-catalog-changes.mjs b/scripts/check-catalog-changes.mjs index c7daabe5..0228d2cd 100644 --- a/scripts/check-catalog-changes.mjs +++ b/scripts/check-catalog-changes.mjs @@ -642,6 +642,7 @@ await section('定时维护:缺省关、建一条维护定时、改频率和 check('……哪几步没执行、原因照服务端', (await textOf(dlg.locator('[data-maintenance-skipped="profile_needed"]'))).startsWith('剖析需要的表没有执行:') && (await textOf(dlg.locator('[data-maintenance-skipped="observe"]'))).includes('未开启数据剖析')) check('……链到定时任务页的触发记录', (await dlg.locator('[data-maintenance-history]').getAttribute('href')) === '/schedules/check-sched-1') + check('……探查任务没有另外的进度页,不给点了没用的「查看进度」', await dlg.locator('[data-maintenance-job="check-ijob-7"] [data-maintenance-job-open]').count() === 0) // 改频率:PATCH 只带改了的和版本 await page.locator('#maint-time').fill('02:30') await until(async () => (await textOf(page.locator('[data-maintenance-preview]'))).includes('每天 02:30')) @@ -669,6 +670,17 @@ await section('定时维护:缺省关、建一条维护定时、改频率和 await page.getByRole('button', { name: '放弃修改', exact: true }).click() await until(async () => (await page.locator('[data-maintenance-dialog]').count()) === 0) check('卡片上的标签照实写已暂停', await until(async () => (await textOf(card.locator('[data-maintenance-chip]'))) === '定时维护 · 已暂停')) + // 最近一次建了剖析任务:「查看进度」到数据目录页打开那个剖析任务(地址里的 pjob 用过就去掉) + state.profileJobs['check-pjob-1'] = profileJob('running', 1) + state.maintenance.schedules[0].last_fire = { ...state.maintenance.schedules[0].last_fire, inputs: { steps: ['introspect', 'profile_needed'], + jobs: [{ step: 'introspect', kind: 'introspect', id: 'check-ijob-8', tables: 12 }, { step: 'profile_needed', kind: 'profile', id: 'check-pjob-1', tables: 8 }], + skipped: [] } } + await card.locator('[data-maintenance-open]').click() + await dlg.waitFor() + await dlg.locator('[data-maintenance-job="check-pjob-1"] [data-maintenance-job-open]').click() + check('剖析任务的「查看进度」:到数据目录页打开那个剖析任务', await until(async () => new URL(page.url()).pathname === `/data/catalog/${S1}` + && (await page.locator('[data-profile-dialog]').count()) === 1) && await until(async () => !new URL(page.url()).searchParams.has('pjob')), + page.url()) check('没有拦下的写请求、没有原生对话框、没有运行时报错', blocked(sent).length === 0 && natives.length === 0 && errors.length === 0, [...blocked(sent).map((s) => s.key), ...natives, ...errors].join(' | ')) })