W4-d 收尾:队列里的任务结束时重取变化计数和清单;定时维护里不给探查任务点了没用的「查看进度」

- 目录页:后台任务条的队列里有任务走了(结束了)就重取变化的计数、「变化」视图重取一页;走的是探查任务时清单也重取(表结构
  变了)。起草、剖析结束时页面跟着的任务本来就会重取清单。
- 定时维护「最近一次」:剖析任务的「查看进度」到数据目录页打开那个剖析任务(pjob);探查任务没有另外的进度页(进行中时
  进度就在这张数据源卡片上),不再给一个关上对话框就什么也看不到的按钮。check-catalog-changes 补上这两条。
This commit is contained in:
ThearchyHelios
2026-10-16 20:14:12 +08:00
parent 9252e6bb0e
commit e48b258449
3 changed files with 32 additions and 7 deletions
@@ -222,7 +222,7 @@ export function SourceMaintenanceDialog({ source, onClose, onSaved }: {
{schedule && <LastRun schedule={schedule} onOpenProfileJob={(id) => {
onClose()
navigate(`/data/catalog/${encodeURIComponent(source.id)}?pjob=${encodeURIComponent(id)}`)
}} onClose={onClose} />}
}} />}
{extra > 0 && <p className="text-2xs text-faint" data-maintenance-extra={extra}>{T.extra(extra)}</p>}
</div>
)}
@@ -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 }: {
<li key={j.id} className="flex flex-wrap items-center gap-2 text-2xs" data-maintenance-job={j.id} data-maintenance-job-kind={j.kind}>
<span className="mono">{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)}</span>
{j.kind === 'profile'
? <button type="button" className="btn btn-xs" onClick={() => onOpenProfileJob(j.id)} data-maintenance-job-open="">{T.viewJob}</button>
// 探查任务的进度就在这张数据源卡片上:关上对话框就看得到
: <button type="button" className="btn btn-xs" onClick={onClose} data-maintenance-job-open="">{T.viewJob}</button>}
{/* 剖析任务点得进进度和结果(数据目录页的剖析对话框);探查任务进行中时进度就在这张数据源卡片上,没有另外的页面 */}
{j.kind === 'profile' && (
<button type="button" className="btn btn-xs" onClick={() => onOpenProfileJob(j.id)} data-maintenance-job-open="">{T.viewJob}</button>
)}
</li>
))}
</ul>
@@ -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<string, string> }>({ 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<string, string>()
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),
+12
View File
@@ -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(' | '))
})