Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 1 addition & 35 deletions packages/app/src/components/inference/ui/ChartControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
} from '@/components/ui/chart-selectors';
import { DateRangePicker } from '@/components/ui/date-range-picker';
import { LabelWithTooltip } from '@/components/ui/label-with-tooltip';
import { MultiDatePicker } from '@/components/ui/multi-date-picker';
import { MultiSelect } from '@/components/ui/multi-select';
import {
Select,
Expand Down Expand Up @@ -76,14 +75,9 @@ const GROUPED_Y_AXIS_OPTIONS = METRIC_GROUPS.map((group) => ({
interface ChartControlsProps {
/** Hide GPU Config selector and related date pickers (used by Historical Trends tab) */
hideGpuComparison?: boolean;
/** Intermediate dates within the comparison range that have changelog entries */
intermediateDates?: string[];
}

export default function ChartControls({
hideGpuComparison = false,
intermediateDates = [],
}: ChartControlsProps) {
export default function ChartControls({ hideGpuComparison = false }: ChartControlsProps) {
const {
selectedModel,
setSelectedModel,
Expand All @@ -99,8 +93,6 @@ export default function ChartControls({
availableGPUs,
selectedDateRange,
setSelectedDateRange,
selectedDates,
setSelectedDates,
dateRangeAvailableDates,
isCheckingAvailableDates,
availablePrecisions,
Expand Down Expand Up @@ -345,32 +337,6 @@ export default function ChartControls({
/>
</div>
)}

{!hideGpuComparison &&
selectedGPUs.length > 0 &&
selectedDateRange.startDate &&
selectedDateRange.endDate &&
intermediateDates.length > 0 && (
<div className="flex flex-col space-y-1.5 lg:col-span-2">
<LabelWithTooltip
htmlFor="intermediate-dates-select"
label="Intermediate Dates"
tooltip="Select up to 2 additional intermediate dates with config changelog entries. These dates will be added to the chart for comparison alongside the start and end dates."
/>
<MultiDatePicker
dates={selectedDates}
onChange={(value) => {
setSelectedDates(value);
track('inference_intermediate_dates_selected', {
dates: value.join(','),
});
}}
availableDates={intermediateDates}
maxDates={2}
placeholder="Select intermediate dates"
/>
</div>
)}
</div>
</div>
</TooltipProvider>
Expand Down
20 changes: 18 additions & 2 deletions packages/app/src/components/inference/ui/ChartDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ export default function ChartDisplay() {
selectedE2eXAxisMetric,
selectedGPUs,
selectedPrecisions,
selectedDates,
setSelectedDates,
selectedDateRange,
dateRangeAvailableDates,
selectedModel,
Expand All @@ -127,7 +129,6 @@ export default function ChartDisplay() {

const {
changelogs,
intermediateDates,
loading: changelogsLoading,
totalDatesQueried,
} = useComparisonChangelogs(selectedGPUs, selectedDateRange, dateRangeAvailableDates);
Expand Down Expand Up @@ -677,7 +678,7 @@ export default function ChartDisplay() {
</div>
</div>
</div>
<ChartControls intermediateDates={intermediateDates} />
<ChartControls />
<ModelArchitectureDiagram model={selectedModel} />
{selectedGPUs.length === 0 && <WorkflowInfoDisplay workflowInfo={workflowInfo} />}
{selectedGPUs.length > 0 && (
Expand All @@ -687,6 +688,21 @@ export default function ChartDisplay() {
selectedPrecisions={selectedPrecisions}
loading={changelogsLoading}
totalDatesQueried={totalDatesQueried}
selectedDates={selectedDates}
selectedDateRange={selectedDateRange}
onAddDate={(date) => {
if (!selectedDates.includes(date)) {
setSelectedDates([...selectedDates, date]);
}
}}
onRemoveDate={(date) => {
setSelectedDates(selectedDates.filter((d) => d !== date));
}}
onAddAllDates={(dates) => {
const merged = [...new Set([...selectedDates, ...dates])];
setSelectedDates(merged);
}}
firstAvailableDate={dateRangeAvailableDates[0]}
/>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { describe, expect, it } from 'vitest';

/**
* Tests for the "add to chart" logic used in ComparisonChangelog.
* Verifies date filtering: which dates are on chart, which are addable.
*/

interface MockChangelog {
date: string;
entries: { config_keys: string[]; description: string; pr_link: string | null }[];
}

function computeDatesOnChart(
selectedDates: string[],
selectedDateRange: { startDate: string; endDate: string },
): Set<string> {
const set = new Set(selectedDates);
if (selectedDateRange.startDate) set.add(selectedDateRange.startDate);
if (selectedDateRange.endDate) set.add(selectedDateRange.endDate);
return set;
}

function computeAddableDates(
filteredChangelogs: MockChangelog[],
datesOnChart: Set<string>,
): string[] {
return filteredChangelogs.map((c) => c.date).filter((d) => !datesOnChart.has(d));
}

const changelogs: MockChangelog[] = [
{
date: '2026-01-15',
entries: [{ config_keys: ['dsr1-fp8-h200-sglang'], description: 'Update', pr_link: null }],
},
{
date: '2026-01-20',
entries: [{ config_keys: ['dsr1-fp8-h200-sglang'], description: 'Bump', pr_link: null }],
},
{
date: '2026-01-25',
entries: [{ config_keys: ['dsr1-fp8-h200-sglang'], description: 'Tweak', pr_link: null }],
},
];

describe('ComparisonChangelog add-to-chart logic', () => {
it('all dates are addable when none are selected', () => {
const onChart = computeDatesOnChart([], { startDate: '', endDate: '' });
const addable = computeAddableDates(changelogs, onChart);
expect(addable).toEqual(['2026-01-15', '2026-01-20', '2026-01-25']);
});

it('dates in selectedDates are marked as on chart', () => {
const onChart = computeDatesOnChart(['2026-01-15', '2026-01-20'], {
startDate: '',
endDate: '',
});
expect(onChart.has('2026-01-15')).toBe(true);
expect(onChart.has('2026-01-20')).toBe(true);
expect(onChart.has('2026-01-25')).toBe(false);
const addable = computeAddableDates(changelogs, onChart);
expect(addable).toEqual(['2026-01-25']);
});

it('range endpoints are marked as on chart', () => {
const onChart = computeDatesOnChart([], {
startDate: '2026-01-15',
endDate: '2026-01-25',
});
expect(onChart.has('2026-01-15')).toBe(true);
expect(onChart.has('2026-01-25')).toBe(true);
const addable = computeAddableDates(changelogs, onChart);
expect(addable).toEqual(['2026-01-20']);
});

it('addable excludes both selectedDates and range endpoints', () => {
const onChart = computeDatesOnChart(['2026-01-20'], {
startDate: '2026-01-15',
endDate: '2026-01-25',
});
const addable = computeAddableDates(changelogs, onChart);
expect(addable).toEqual([]);
});

it('returns empty addable when all dates are already on chart', () => {
const onChart = computeDatesOnChart(['2026-01-15', '2026-01-20', '2026-01-25'], {
startDate: '',
endDate: '',
});
const addable = computeAddableDates(changelogs, onChart);
expect(addable).toEqual([]);
});
});
Loading
Loading