feat: suite filter narrows visible suite rows within each band
When a suite filter is active, the per-band view now shows only the selected suite rows instead of all suites in the band. Category total strips (Devlogic/Sysops) are hidden during suite filtering since they aggregate over all suites and would be misleading for cross-band comparison. Clearing the suite filter restores all suite rows and totals.
This commit is contained in:
parent
700bdae959
commit
4f34fd419d
2 changed files with 88 additions and 4 deletions
|
|
@ -247,11 +247,16 @@ class="cursor-pointer"
|
||||||
@php
|
@php
|
||||||
$devlogicSuites = ['softbench', 'prosebench', 'psychbench', 'depthsweep'];
|
$devlogicSuites = ['softbench', 'prosebench', 'psychbench', 'depthsweep'];
|
||||||
$sysopsSuites = ['infrabench', 'scenariobench'];
|
$sysopsSuites = ['infrabench', 'scenariobench'];
|
||||||
$devlogicRows = $session->suites->filter(fn ($r) => in_array($r->suite, $devlogicSuites));
|
$suiteFilterActive = ! empty($this->filters['suite']);
|
||||||
$sysopsRows = $session->suites->filter(fn ($r) => in_array($r->suite, $sysopsSuites));
|
$visibleSuites = $suiteFilterActive
|
||||||
|
? $session->suites->filter(fn ($r) => in_array($r->suite, $this->filters['suite'], true))
|
||||||
|
: $session->suites;
|
||||||
|
$devlogicRows = $visibleSuites->filter(fn ($r) => in_array($r->suite, $devlogicSuites));
|
||||||
|
$sysopsRows = $visibleSuites->filter(fn ($r) => in_array($r->suite, $sysopsSuites));
|
||||||
@endphp
|
@endphp
|
||||||
{{-- Devlogic section: total strip + column headers + suite rows --}}
|
{{-- Devlogic section: total strip + column headers + suite rows --}}
|
||||||
@if ($devlogicRows->isNotEmpty() && $session->band->devlogic_tps !== null)
|
@if ($devlogicRows->isNotEmpty() && ($suiteFilterActive || $session->band->devlogic_tps !== null))
|
||||||
|
@unless ($suiteFilterActive)
|
||||||
<div class="flex flex-wrap items-center gap-x-4 gap-y-1 border-l-2 border-sky-400 bg-sky-50/50 px-4 py-2 dark:border-sky-500 dark:bg-sky-950/20">
|
<div class="flex flex-wrap items-center gap-x-4 gap-y-1 border-l-2 border-sky-400 bg-sky-50/50 px-4 py-2 dark:border-sky-500 dark:bg-sky-950/20">
|
||||||
<span class="text-xs font-semibold uppercase tracking-wider text-sky-600 dark:text-sky-400">{{ __('Devlogic total') }}</span>
|
<span class="text-xs font-semibold uppercase tracking-wider text-sky-600 dark:text-sky-400">{{ __('Devlogic total') }}</span>
|
||||||
<span class="text-sm">
|
<span class="text-sm">
|
||||||
|
|
@ -267,6 +272,7 @@ class="cursor-pointer"
|
||||||
<flux:badge size="xs" color="{{ $session->band->devlogic_failed > 0 ? 'rose' : 'zinc' }}">✘ {{ $session->band->devlogic_failed }}</flux:badge>
|
<flux:badge size="xs" color="{{ $session->band->devlogic_failed > 0 ? 'rose' : 'zinc' }}">✘ {{ $session->band->devlogic_failed }}</flux:badge>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@endunless
|
||||||
<div class="hidden px-4 pt-2 md:grid md:grid-cols-[7.5rem_4.5rem_7rem_15rem_6rem_1fr] md:gap-x-4 md:items-center">
|
<div class="hidden px-4 pt-2 md:grid md:grid-cols-[7.5rem_4.5rem_7rem_15rem_6rem_1fr] md:gap-x-4 md:items-center">
|
||||||
<span class="text-[10px] font-semibold uppercase tracking-wider text-zinc-400">{{ __('Benchmark') }}</span>
|
<span class="text-[10px] font-semibold uppercase tracking-wider text-zinc-400">{{ __('Benchmark') }}</span>
|
||||||
<span class="text-[10px] font-semibold uppercase tracking-wider text-zinc-400">{{ __('Thinking') }}</span>
|
<span class="text-[10px] font-semibold uppercase tracking-wider text-zinc-400">{{ __('Thinking') }}</span>
|
||||||
|
|
@ -308,7 +314,8 @@ class="flex flex-wrap items-center gap-x-4 gap-y-1 px-4 py-2.5 hover:bg-zinc-50
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
{{-- Sysops section: total strip + column headers + suite rows --}}
|
{{-- Sysops section: total strip + column headers + suite rows --}}
|
||||||
@if ($sysopsRows->isNotEmpty() && $session->band->sysops_tps !== null)
|
@if ($sysopsRows->isNotEmpty() && ($suiteFilterActive || $session->band->sysops_tps !== null))
|
||||||
|
@unless ($suiteFilterActive)
|
||||||
<div class="flex flex-wrap items-center gap-x-4 gap-y-1 border-l-2 border-amber-400 bg-amber-50/50 px-4 py-2 dark:border-amber-500 dark:bg-amber-950/20">
|
<div class="flex flex-wrap items-center gap-x-4 gap-y-1 border-l-2 border-amber-400 bg-amber-50/50 px-4 py-2 dark:border-amber-500 dark:bg-amber-950/20">
|
||||||
<span class="text-xs font-semibold uppercase tracking-wider text-amber-600 dark:text-amber-400">{{ __('Sysops total') }}</span>
|
<span class="text-xs font-semibold uppercase tracking-wider text-amber-600 dark:text-amber-400">{{ __('Sysops total') }}</span>
|
||||||
<span class="text-sm">
|
<span class="text-sm">
|
||||||
|
|
@ -324,6 +331,7 @@ class="flex flex-wrap items-center gap-x-4 gap-y-1 px-4 py-2.5 hover:bg-zinc-50
|
||||||
<flux:badge size="xs" color="{{ $session->band->sysops_failed > 0 ? 'rose' : 'zinc' }}">✘ {{ $session->band->sysops_failed }}</flux:badge>
|
<flux:badge size="xs" color="{{ $session->band->sysops_failed > 0 ? 'rose' : 'zinc' }}">✘ {{ $session->band->sysops_failed }}</flux:badge>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@endunless
|
||||||
<div class="hidden px-4 pt-2 md:grid md:grid-cols-[7.5rem_4.5rem_7rem_15rem_6rem_1fr] md:gap-x-4 md:items-center">
|
<div class="hidden px-4 pt-2 md:grid md:grid-cols-[7.5rem_4.5rem_7rem_15rem_6rem_1fr] md:gap-x-4 md:items-center">
|
||||||
<span class="text-[10px] font-semibold uppercase tracking-wider text-zinc-400">{{ __('Benchmark') }}</span>
|
<span class="text-[10px] font-semibold uppercase tracking-wider text-zinc-400">{{ __('Benchmark') }}</span>
|
||||||
<span class="text-[10px] font-semibold uppercase tracking-wider text-zinc-400">{{ __('Thinking') }}</span>
|
<span class="text-[10px] font-semibold uppercase tracking-wider text-zinc-400">{{ __('Thinking') }}</span>
|
||||||
|
|
|
||||||
|
|
@ -278,3 +278,79 @@
|
||||||
$component->call('toggleFilter', 'suite', 'infrabench')
|
$component->call('toggleFilter', 'suite', 'infrabench')
|
||||||
->assertSet('filters.suite', []);
|
->assertSet('filters.suite', []);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('suite filter hides non-selected suite rows and category totals within matching bands', function () {
|
||||||
|
$me = User::factory()->create();
|
||||||
|
|
||||||
|
// One band containing both softbench (devlogic) and infrabench (sysops).
|
||||||
|
$soft = BenchmarkRun::factory()->create([
|
||||||
|
'run_id' => 'RUN-SOFT-001',
|
||||||
|
'suite' => 'softbench', 'label' => 'mixed-band', 'model_id' => 'm', 'model_quant' => 'Q5_K_M',
|
||||||
|
'gpu' => 'GPU1', 'gpu_count' => 1, 'engine' => 'llama.cpp', 'user_id' => $me->id, 'visibility' => 'public',
|
||||||
|
'ran_at' => '2026-09-03 12:00:00',
|
||||||
|
]);
|
||||||
|
SoftbenchResult::factory()->create(['benchmark_run_id' => $soft->id, 'ok' => true, 'user_tps' => 50.0, 'total' => 100, 'level' => 'off']);
|
||||||
|
|
||||||
|
$infra = BenchmarkRun::factory()->create([
|
||||||
|
'run_id' => 'RUN-INFRA-001',
|
||||||
|
'suite' => 'infrabench', 'label' => 'mixed-band', 'model_id' => 'm', 'model_quant' => 'Q5_K_M',
|
||||||
|
'gpu' => 'GPU1', 'gpu_count' => 1, 'engine' => 'llama.cpp', 'user_id' => $me->id, 'visibility' => 'public',
|
||||||
|
'ran_at' => '2026-09-03 12:05:00',
|
||||||
|
]);
|
||||||
|
InfrabenchResult::factory()->create(['benchmark_run_id' => $infra->id, 'ok' => true, 'user_tps' => 30.0, 'total' => 100, 'level' => 'low']);
|
||||||
|
|
||||||
|
Artisan::call('festbench:summary');
|
||||||
|
|
||||||
|
// No suite filter: both suite rows and both category totals visible.
|
||||||
|
Volt::test('summary.index')
|
||||||
|
->assertSee('mixed-band')
|
||||||
|
->assertSee('RUN-SOFT-001')
|
||||||
|
->assertSee('RUN-INFRA-001')
|
||||||
|
->assertSee('Devlogic total')
|
||||||
|
->assertSee('Sysops total');
|
||||||
|
|
||||||
|
// Filter to infrabench: band still shows, but only the infrabench row
|
||||||
|
// is rendered and both category total strips are hidden.
|
||||||
|
Volt::test('summary.index', ['filters' => [
|
||||||
|
'gpu' => [], 'model' => [], 'quant' => [], 'engine' => [], 'suite' => ['infrabench'],
|
||||||
|
]])
|
||||||
|
->assertSee('mixed-band')
|
||||||
|
->assertSee('RUN-INFRA-001')
|
||||||
|
->assertDontSee('RUN-SOFT-001')
|
||||||
|
->assertDontSee('Devlogic total')
|
||||||
|
->assertDontSee('Sysops total');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('clearing the suite filter restores all suite rows and category totals', function () {
|
||||||
|
$me = User::factory()->create();
|
||||||
|
|
||||||
|
$soft = BenchmarkRun::factory()->create([
|
||||||
|
'run_id' => 'RUN-SOFT-002',
|
||||||
|
'suite' => 'softbench', 'label' => 'mixed-band', 'model_id' => 'm', 'model_quant' => 'Q5_K_M',
|
||||||
|
'gpu' => 'GPU1', 'gpu_count' => 1, 'engine' => 'llama.cpp', 'user_id' => $me->id, 'visibility' => 'public',
|
||||||
|
'ran_at' => '2026-09-03 12:00:00',
|
||||||
|
]);
|
||||||
|
SoftbenchResult::factory()->create(['benchmark_run_id' => $soft->id, 'ok' => true, 'user_tps' => 50.0, 'total' => 100, 'level' => 'off']);
|
||||||
|
|
||||||
|
$infra = BenchmarkRun::factory()->create([
|
||||||
|
'run_id' => 'RUN-INFRA-002',
|
||||||
|
'suite' => 'infrabench', 'label' => 'mixed-band', 'model_id' => 'm', 'model_quant' => 'Q5_K_M',
|
||||||
|
'gpu' => 'GPU1', 'gpu_count' => 1, 'engine' => 'llama.cpp', 'user_id' => $me->id, 'visibility' => 'public',
|
||||||
|
'ran_at' => '2026-09-03 12:05:00',
|
||||||
|
]);
|
||||||
|
InfrabenchResult::factory()->create(['benchmark_run_id' => $infra->id, 'ok' => true, 'user_tps' => 30.0, 'total' => 100, 'level' => 'low']);
|
||||||
|
|
||||||
|
Artisan::call('festbench:summary');
|
||||||
|
|
||||||
|
$component = Volt::test('summary.index', ['filters' => [
|
||||||
|
'gpu' => [], 'model' => [], 'quant' => [], 'engine' => [], 'suite' => ['infrabench'],
|
||||||
|
]])
|
||||||
|
->assertSee('RUN-INFRA-002')
|
||||||
|
->assertDontSee('RUN-SOFT-002');
|
||||||
|
|
||||||
|
$component->call('resetFilters')
|
||||||
|
->assertSee('RUN-SOFT-002')
|
||||||
|
->assertSee('RUN-INFRA-002')
|
||||||
|
->assertSee('Devlogic total')
|
||||||
|
->assertSee('Sysops total');
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue