From d0d24c8f6acae91ffd7d51913cf09b258eb6f7ac Mon Sep 17 00:00:00 2001 From: Neko Ayaka Date: Wed, 21 Oct 2026 07:55:30 +0800 Subject: [PATCH] fix(ui): lay out the viewer for phones and narrow cards Co-Authored-By: Claude Opus 5.5 --- .../src/components/CaseMetricsPanel.vue | 5 +- .../ui/client/src/components/InfoButton.vue | 63 +++++++++++++++++++ .../ui/client/src/components/LineChart.vue | 4 +- .../ui/client/src/components/PageHeader.vue | 19 +++--- .../client/src/components/ProgressPanel.vue | 10 ++- .../client/src/components/RunDetails.test.ts | 6 +- .../ui/client/src/components/RunDetails.vue | 46 +++++++------- .../ui/client/src/components/ScoresPanel.vue | 30 ++++++--- .../ui/client/src/pages/ExperimentPage.vue | 39 +++++++----- packages/ui/client/src/pages/ProjectPage.vue | 40 ++++++------ packages/ui/client/src/pages/RunPage.vue | 11 ++-- 11 files changed, 183 insertions(+), 90 deletions(-) create mode 100644 packages/ui/client/src/components/InfoButton.vue diff --git a/packages/ui/client/src/components/CaseMetricsPanel.vue b/packages/ui/client/src/components/CaseMetricsPanel.vue index edee06f..bed388d 100644 --- a/packages/ui/client/src/components/CaseMetricsPanel.vue +++ b/packages/ui/client/src/components/CaseMetricsPanel.vue @@ -521,10 +521,11 @@ const formatOf = (name: string, value: number) => formatColumnValue(value, metri every case against its recorded metrics -
+ +
- + diff --git a/packages/ui/client/src/components/InfoButton.vue b/packages/ui/client/src/components/InfoButton.vue new file mode 100644 index 0000000..3836dd0 --- /dev/null +++ b/packages/ui/client/src/components/InfoButton.vue @@ -0,0 +1,63 @@ + + + diff --git a/packages/ui/client/src/components/LineChart.vue b/packages/ui/client/src/components/LineChart.vue index efe97c3..ef743dc 100644 --- a/packages/ui/client/src/components/LineChart.vue +++ b/packages/ui/client/src/components/LineChart.vue @@ -31,7 +31,9 @@ const bounds = computed(() => { const x = extent(props.points.map(point => point.x)) const y = extent(props.points.map(point => point.y)) const minY = Math.min(0, y.min) - const maxY = Math.max(y.max, minY + 1e-9) + // A constant series (every value 0, say) has no range: one unit above the floor keeps the axis readable (`0`–`1`) + // instead of labelling both ends `0`. + const maxY = y.max > minY ? y.max : minY + 1 return { maxX: x.max, maxY, minX: x.min, minY } }) function sx(x: number) { diff --git a/packages/ui/client/src/components/PageHeader.vue b/packages/ui/client/src/components/PageHeader.vue index 1da00f0..fe9b8ae 100644 --- a/packages/ui/client/src/components/PageHeader.vue +++ b/packages/ui/client/src/components/PageHeader.vue @@ -57,11 +57,12 @@ const siblings = computed(() => { diff --git a/packages/ui/client/src/components/ProgressPanel.vue b/packages/ui/client/src/components/ProgressPanel.vue index c80f079..c2d1f89 100644 --- a/packages/ui/client/src/components/ProgressPanel.vue +++ b/packages/ui/client/src/components/ProgressPanel.vue @@ -5,6 +5,7 @@ import type { LiveConnection } from '../composables/useRunLive' import { useIntervalFn, useTimestamp } from '@vueuse/core' import { computed } from 'vue' +import InfoButton from './InfoButton.vue' import ProgressBar from './ProgressBar.vue' import ProgressChart from './ProgressChart.vue' import StateBadge from './StateBadge.vue' @@ -40,6 +41,8 @@ const basisText = computed(() => ({ 'ended': 'run ended', 'unknown': 'no case finished yet: no estimate', })[progress.value.basis]) +/** How the remaining time is estimated: printed under the numbers on desktop, behind an info button on phones. */ +const etaBasis = computed(() => `ETA basis: ${basisText.value}${live.value && progress.value.lowerBound ? '; auto attempts were seen, so more rounds may follow (lower bound)' : ''}. Rule: elapsed ÷ settled cases × estimated cases − elapsed, and at least as long as the longest running case has run.`) const connectionText = computed(() => ({ closed: 'not connected', connecting: 'connecting…', @@ -122,8 +125,9 @@ const connectionText = computed(() => ({
-
+
{{ live ? 'Estimated remaining' : 'Total duration' }} +

{{ etaBasis }}