mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 17:22:00 +00:00
运行对比页复查修正:互换时不重取运行列表,拆分句的总变化为 0 时写「0」,展开控件只指向在场的明细
- 互换、换了本次之后,新的运行记录还在路上时沿用上一次知道的工作流:下拉不再先退回「正在读取」、再把同一工作流 的运行列表取一遍(能比的两次运行本来就是同一个工作流);check-compare 补这一项 - 口径变了、数值却碰巧没变(两效应正好抵消)时服务端不给变化量的写法,拆分那句话的总变化写「0」,不再写成 「两者之和等于总变化 无变化」 - 指标展开、查看 SQL 的按钮只在明细展开时才带 aria-controls,不指向页面上不存在的元素;参数前后两个值之间的箭头 对读屏补一句「改为」
This commit is contained in:
@@ -2878,6 +2878,8 @@ export const RUN_COMPARE_TEXT = {
|
||||
rowsBase: (base: string) => `基准 ${base}`,
|
||||
rowsTarget: (target: string) => `本次 ${target}`,
|
||||
literals: '变化的参数',
|
||||
/** 参数前后两个值之间的箭头,读屏念这个 */
|
||||
changedTo: '改为',
|
||||
baseSql: '基准的 SQL',
|
||||
targetSql: '本次的 SQL',
|
||||
bothSql: '两次相同的 SQL',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { Link, useLocation, useNavigate, useSearchParams } from 'react-router-dom'
|
||||
import { GitCompareArrows } from 'lucide-react'
|
||||
import { EmptyState, PageHeader, Skeleton, Spinner } from '../../components/ui'
|
||||
@@ -44,7 +44,11 @@ export function ComparePage() {
|
||||
|
||||
const targetRun = useRunRecord(target)
|
||||
const baseRun = useRunRecord(base)
|
||||
const workflowId = targetRun.data?.workflow_id
|
||||
// 换基准的下拉按本次的工作流取。互换、换了本次之后新的运行记录还在路上时沿用上一次知道的工作流:能比的两次运行
|
||||
// 本来就是同一个工作流,不必让下拉先退回「正在读取」、再把同一份列表取一遍
|
||||
const lastWorkflow = useRef<string | null | undefined>(undefined)
|
||||
if (targetRun.state === 'ok') lastWorkflow.current = targetRun.data?.workflow_id ?? null
|
||||
const workflowId = targetRun.state === 'ok' ? targetRun.data?.workflow_id : lastWorkflow.current
|
||||
const candidates = useCandidates(workflowId)
|
||||
const cmp = useComparison(target, base)
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ function MetricRows({ m, k, detailId, open, onToggle }: {
|
||||
<Fragment>
|
||||
<tr className={clsx('border-b align-top last:border-0', open && 'bg-hover')} data-compare-metric={k} data-class={m.classification}>
|
||||
<th scope="row" className={clsx(STICKY, open ? 'bg-hover' : 'bg-panel', 'px-2.5 py-2 text-left font-normal')}>
|
||||
<button type="button" data-compare-expand="" aria-expanded={open} aria-controls={detailId}
|
||||
<button type="button" data-compare-expand="" aria-expanded={open} aria-controls={open ? detailId : undefined}
|
||||
title={open ? T.collapse(m.name) : T.expand(m.name)} onClick={onToggle}
|
||||
className="group flex max-w-[220px] items-start gap-1 rounded-sm text-left focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[color:var(--accent)]">
|
||||
<ChevronRight size={12} aria-hidden
|
||||
@@ -128,7 +128,7 @@ function MetricRows({ m, k, detailId, open, onToggle }: {
|
||||
<td className="px-2.5 py-2"><ClassChip value={m.classification} /></td>
|
||||
<td className="px-2.5 py-2">
|
||||
{m.decomposition ? (
|
||||
<Split d={m.decomposition} total={deltaText(m)} />
|
||||
<Split d={m.decomposition} total={totalText(m)} />
|
||||
) : m.decomposition_note ? (
|
||||
<p className="max-w-[280px] text-2xs leading-relaxed text-dim [overflow-wrap:anywhere]" data-compare-decomp-note="">
|
||||
{m.decomposition_note}
|
||||
@@ -155,6 +155,15 @@ function deltaText(m: RunCompareMetric): string {
|
||||
return m.delta === 0 ? T.noChange : NONE
|
||||
}
|
||||
|
||||
/**
|
||||
* 拆分那句话里的总变化:口径变了、数值却碰巧没变时服务端不给变化量的写法(两效应正好抵消),写「0」,
|
||||
* 不写成「两者之和等于总变化 无变化」
|
||||
*/
|
||||
function totalText(m: RunCompareMetric): string {
|
||||
if (m.delta_rendered) return m.delta_rendered
|
||||
return m.delta === 0 ? '0' : NONE
|
||||
}
|
||||
|
||||
/**
|
||||
* 能严格拆分的:口径效应、数据效应并列,下面一段两截的条形按两者的绝对值分长短。一正一负(互相抵消)时负的那截画
|
||||
* 斜纹:长短只说谁的分量大,方向看数的正负号
|
||||
@@ -205,7 +214,7 @@ function MetricDetail({ m }: { m: RunCompareMetric }) {
|
||||
)}
|
||||
{m.decomposition && (
|
||||
<p className="text-xs leading-relaxed text-fg" data-compare-decomp-sum="">
|
||||
{T.splitSum(m.decomposition.caliber_rendered, m.decomposition.data_rendered, deltaText(m))}
|
||||
{T.splitSum(m.decomposition.caliber_rendered, m.decomposition.data_rendered, totalText(m))}
|
||||
</p>
|
||||
)}
|
||||
<Inputs m={m} />
|
||||
|
||||
@@ -59,7 +59,7 @@ function QueryItem({ q, k, nth }: { q: RunCompareQuery; k: string; nth: number |
|
||||
<span className="tnum text-2xs text-faint" data-compare-rows="">{rows}</span>
|
||||
{foldable && (
|
||||
<button type="button" className="btn btn-xs btn-ghost text-faint" data-compare-sql-toggle=""
|
||||
aria-expanded={showSql} aria-controls={sqlId} onClick={() => setShowSql((v) => !v)}>
|
||||
aria-expanded={showSql} aria-controls={showSql ? sqlId : undefined} onClick={() => setShowSql((v) => !v)}>
|
||||
<ChevronRight size={11} aria-hidden className={clsx('transition-transform', showSql && 'rotate-90')} />
|
||||
{showSql ? T.hideSql : T.showSql}
|
||||
</button>
|
||||
@@ -82,7 +82,9 @@ function QueryItem({ q, k, nth }: { q: RunCompareQuery; k: string; nth: number |
|
||||
{q.literals.map((l, i) => (
|
||||
<li key={i} className="flex min-w-0 flex-wrap items-center gap-1.5">
|
||||
<code className="mono rounded px-1 [overflow-wrap:anywhere]" style={MARK.del}>{valueText(l.base)}</code>
|
||||
{/* 箭头只给眼睛看,读屏念「改为」 */}
|
||||
<span className="text-faint" aria-hidden>→</span>
|
||||
<span className="sr-only">{T.changedTo}</span>
|
||||
<code className="mono rounded px-1 [overflow-wrap:anywhere]" style={MARK.add}>{valueText(l.target)}</code>
|
||||
</li>
|
||||
))}
|
||||
|
||||
@@ -558,6 +558,8 @@ await section('换基准、互换', async () => {
|
||||
check('换基准:重新请求对比', compareHits(log, T, B2) === 1)
|
||||
check('换基准:页面换成新的一份', (await texts(page, '[data-compare-notes] li')).includes(NOTE_B2))
|
||||
check('换基准:基准卡跟着换', (await text(page, '[data-compare-run="base"]')).includes('9/21'))
|
||||
const lists = () => log.filter((k) => k.startsWith('GET /api/runs?') && k.includes(`workflow_id=${WF}`)).length
|
||||
const listsBefore = lists()
|
||||
await page.locator('button[data-compare-swap]').click()
|
||||
await until(async () => new URL(page.url()).searchParams.get('target') === B2)
|
||||
await until(async () => compareHits(log, B2, T) === 1)
|
||||
@@ -566,6 +568,9 @@ await section('换基准、互换', async () => {
|
||||
check('互换:重新请求对比', compareHits(log, B2, T) === 1)
|
||||
await settled(page)
|
||||
check('互换:两张卡跟着对调', (await page.locator('[data-compare-run="target"] a[data-compare-run-link]').getAttribute('href')) === `/runs/${B2}`)
|
||||
check('互换:同一工作流的运行列表不重取,下拉照常可用', lists() === listsBefore
|
||||
&& await page.locator('select[data-compare-base-picker]').isEnabled() && await page.locator('select[data-compare-base-picker]').inputValue() === T,
|
||||
`${listsBefore} → ${lists()}`)
|
||||
})
|
||||
|
||||
await section('过时的答复不盖掉新的', async () => {
|
||||
|
||||
Reference in New Issue
Block a user