Skip to content

Commit e19fcce

Browse files
committed
feat: explain modeled components in the All in Measured boundary option
中文:在“整体实测功耗”边界选项中说明未实测组件由模型估算
1 parent 8196cea commit e19fcce

4 files changed

Lines changed: 41 additions & 40 deletions

File tree

‎docs/powerx-permanent-view.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ control change to the nearest registered key. Consequences:
6969
the Measured row should call.
7070

7171
The Boundary select tracks `inference_power_basis_changed { basis, family }` in addition to the
72-
existing `inference_y_axis_metric_selected` fired by `ChartControls`.
72+
existing `inference_y_axis_metric_selected` fired by `ChartControls`. Its All in Measured option
73+
carries the (i) help `ALL_IN_MEASURED_NOTE` (unmeasured components are modeled); the chart
74+
caption states the same boundary, so the controls row has no separate footnote.
7375

7476
## Missing values
7577

‎packages/app/cypress/component/inference-chart-controls.cy.tsx‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,16 @@ describe('Inference ChartControls grouped measured metrics', () => {
436436
);
437437
});
438438

439+
it('explains in the Boundary menu that All in Measured models unmeasured components', () => {
440+
mountMeasuredControls();
441+
cy.get('[data-testid="measured-power-basis"]').click();
442+
cy.get('[data-testid="option-help-utility-modeled"]').click();
443+
cy.get('[data-testid="option-help-content-utility-modeled"]').should(
444+
'contain.text',
445+
'unmeasured components are modeled',
446+
);
447+
});
448+
439449
it('resets a fleet percentile to role average and only enables TDP for the whole-fleet average', () => {
440450
mountMeasuredControls('y_measuredP75Power');
441451
selectMeasuredSetting('power-scope', 'prefill');

‎packages/app/cypress/component/measured-metric-controls.cy.tsx‎

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function Controls() {
1515

1616
describe('Power boundary labels', () => {
1717
for (const locale of ['en', 'zh'] as const) {
18-
it(`keeps metric selection and the modeled-component note clear (${locale})`, () => {
18+
it(`keeps boundary selection clear (${locale})`, () => {
1919
const width = locale === 'en' ? 1280 : 390;
2020
cy.viewport(width, 720);
2121
cy.mount(
@@ -32,40 +32,32 @@ describe('Power boundary labels', () => {
3232
'All in Measured',
3333
]
3434
: ['GPU 实测功耗', 'GPU 额定功耗(TDP)', '整体预配功耗', '整体实测功耗'];
35-
cy.get('[data-testid="all-in-measured-note"]').should('not.exist');
3635
cy.get('[data-testid="measured-power-basis"]').click();
37-
cy.get('[role="option"]').should(($options) => {
36+
cy.get('[data-select-option]').should(($options) => {
3837
expect([...$options].map((option) => option.textContent?.trim())).to.deep.equal(labels);
3938
});
40-
cy.get('[role="option"][data-value="gpu-provisioned"]').click();
39+
cy.get('[data-select-option][data-value="gpu-provisioned"]').click();
4140
cy.get('[data-testid="selected-metric"]').should('have.text', 'y_gpuProvisionedWatts');
4241
cy.get('[data-testid="measured-power-basis"]').click();
43-
cy.get('[role="option"][data-value="utility-provisioned"]').click();
42+
cy.get('[data-select-option][data-value="utility-provisioned"]').click();
4443
cy.get('[data-testid="selected-metric"]').should('have.text', 'y_utilityProvisionedWatts');
4544
cy.get('[data-testid="measured-power-basis"]').click();
46-
cy.get('[role="option"][data-value="utility-modeled"]').click();
47-
cy.get('[role="option"]').should('not.exist');
45+
cy.get('[data-select-option][data-value="utility-modeled"]').click();
46+
cy.get('[data-select-option]').should('not.exist');
4847
cy.get('[data-testid="selected-metric"]').should('have.text', 'y_utilityModeledWatts');
49-
cy.get('[data-testid="all-in-measured-note"]')
50-
.should('be.visible')
51-
.and(
52-
'contain',
53-
locale === 'en' ? 'unmeasured components are modeled' : '未实测的组件功耗由模型估算',
54-
);
5548
cy.get('[data-testid="measured-metric-controls"]').should(($controls) => {
5649
const box = $controls[0].getBoundingClientRect();
5750
expect(box.left).to.be.at.least(0);
5851
expect(box.right).to.be.at.most(width);
5952
expect($controls[0].scrollWidth).to.be.at.most($controls[0].clientWidth);
6053
});
61-
cy.screenshot(`power-boundary-note-${locale}`, { overwrite: true });
54+
cy.screenshot(`power-boundary-selected-${locale}`, { overwrite: true });
6255
cy.get('[data-testid="measured-power-basis"]').click();
63-
cy.get('[role="option"][data-value="gpu-measured"]').click();
56+
cy.get('[data-select-option][data-value="gpu-measured"]').click();
6457
cy.get('[data-testid="selected-metric"]').should('have.text', 'y_measuredAvgPower');
65-
cy.get('[data-testid="all-in-measured-note"]').should('not.exist');
66-
// Finish selection assertions before a screenshot can dismiss the open Radix menu.
58+
// Finish selection assertions before a screenshot can dismiss the open menu.
6759
cy.get('[data-testid="measured-power-basis"]').click();
68-
cy.get('[role="option"]').should('be.visible');
60+
cy.get('[data-select-option]').should('be.visible');
6961
cy.screenshot(`power-boundary-options-${locale}`, { overwrite: true });
7062
});
7163
}

‎packages/app/src/components/inference/ui/MeasuredMetricControls.tsx‎

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { LabelWithTooltip } from '@/components/ui/label-with-tooltip';
2+
import { SearchableSelect } from '@/components/ui/searchable-select';
23
import { SegmentedToggle } from '@/components/ui/segmented-toggle';
34
import {
45
Select,
@@ -135,25 +136,29 @@ export function MeasuredMetricControls({
135136
>
136137
<div className="flex min-w-0 flex-col gap-1.5">
137138
<LabelWithTooltip htmlFor={basisId} label={t.basis} tooltip={t.basisHelp} />
138-
<Select
139+
<SearchableSelect
139140
value={config.basis}
141+
triggerId={basisId}
142+
triggerTestId={basisId}
143+
placeholder={t.basis}
144+
searchable={false}
140145
onValueChange={(value) => {
141146
const basis = value as PowerBasis;
142147
track('inference_power_basis_changed', { basis, family: config.family });
143148
change({ basis });
144149
}}
145-
>
146-
<SelectTrigger id={basisId} data-testid={basisId} className="w-full">
147-
<SelectValue />
148-
</SelectTrigger>
149-
<SelectContent portalled={false}>
150-
{POWER_BASES.map((basis) => (
151-
<SelectItem key={basis} value={basis} data-value={basis}>
152-
{POWER_BASIS_LABELS[basis][locale]}
153-
</SelectItem>
154-
))}
155-
</SelectContent>
156-
</Select>
150+
groups={[
151+
{
152+
label: '',
153+
options: POWER_BASES.map((basis) => ({
154+
value: basis,
155+
label: POWER_BASIS_LABELS[basis][locale],
156+
help:
157+
basis === 'utility-modeled' ? <p>{ALL_IN_MEASURED_NOTE[locale]}</p> : undefined,
158+
})),
159+
},
160+
]}
161+
/>
157162
</div>
158163
{config.family === 'energy' && (
159164
<div className="flex min-w-0 flex-col gap-1.5">
@@ -339,14 +344,6 @@ export function MeasuredMetricControls({
339344
</Select>
340345
</div>
341346
)}
342-
{(config.basis === 'utility-modeled' || compare === 'boundaries') && (
343-
<p
344-
className="col-span-full text-xs text-muted-foreground"
345-
data-testid="all-in-measured-note"
346-
>
347-
{ALL_IN_MEASURED_NOTE[locale]}
348-
</p>
349-
)}
350347
</div>
351348
);
352349
}

0 commit comments

Comments
 (0)