Skip to content
Merged
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
8 changes: 8 additions & 0 deletions report-app/src/app/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ <h1>Web Codegen Scorer</h1>
<span class="material-symbols-outlined">arrow_back</span>
</a>

<a
routerLink="/trajectory"
routerLinkActive="active"
class="icon-button"
title="Go to trajectory page">
<span class="material-symbols-outlined">trending_up</span>
</a>

<button class="icon-button" title="Toggle dark mode" (click)="toggleColorMode()">
<span class="material-symbols-outlined">{{colorMode()}}_mode</span>
</button>
Expand Down
5 changes: 5 additions & 0 deletions report-app/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {Routes} from '@angular/router';
import {ReportViewer} from './pages/report-viewer/report-viewer';
import {ComparisonPage} from './pages/comparison/comparison';
import {ReportListComponent} from './pages/report-list/report-list';
import {Trajectory} from './pages/trajectory/trajectory';

export const routes: Routes = [
{
Expand All @@ -16,6 +17,10 @@ export const routes: Routes = [
path: 'comparison',
component: ComparisonPage,
},
{
path: 'trajectory',
component: Trajectory,
},
{
path: '',
redirectTo: 'reports',
Expand Down
35 changes: 2 additions & 33 deletions report-app/src/app/pages/report-list/report-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,7 @@
<message-spinner message="Loading reports"/>
} @else {
<div class="toolbar">
<div class="filter-container">
@if (allFrameworks().length > 1) {
<select (change)="selectedFramework.set($any($event.target).value)">
<option value="">All Frameworks</option>
@for (framework of allFrameworks(); track framework.id) {
<option [value]="framework.id">{{ framework.displayName }}</option>
}
</select>
}
@if (allModels().length > 1) {
<select (change)="selectedModel.set($any($event.target).value)">
<option value="">All Models</option>
@for (model of allModels(); track model.id) {
<option [value]="model.id">{{ model.displayName }}</option>
}
</select>
}
@if (allRunners().length > 1) {
<select (change)="selectedRunner.set($any($event.target).value)">
<option value="">All Runners</option>
@for (runner of allRunners(); track runner.id) {
<option [value]="runner.id">{{ runner.displayName }}</option>
}
</select>
}
@if (allLabels().length > 0) {
<multi-select
[options]="allLabels()"
[(selected)]="selectedLabels"
[label]="selectedLabels().length === 0 ? 'Filter by labels' : `Showing reports with ${selectedLabels().length} label(s)`"/>
}
</div>
<report-filters #filters/>
<div class="button-group">
@if (isCompareMode()) {
<button class="outlined-button" (click)="toggleCompareMode()">Cancel</button>
Expand All @@ -48,7 +17,7 @@
</div>
</div>

@for (group of reportGroups(); track group.id) {
@for (group of filters.filteredGroups(); track group.id) {
<div class="report-item">
<a [routerLink]="['/report', group.id]">
<div class="report-score-container">
Expand Down
53 changes: 0 additions & 53 deletions report-app/src/app/pages/report-list/report-list.scss
Original file line number Diff line number Diff line change
Expand Up @@ -93,65 +93,12 @@ h1, h2 {
flex-shrink: 0;
}

.report-item-container {
display: flex;
align-items: center;
gap: 1rem;
}

.report-checkbox {
appearance: none;
-webkit-appearance: none;
margin: 0;
font: inherit;
color: currentColor;
width: 1.5rem;
height: 1.5rem;
border: 0.15rem solid var(--border-color);
border-radius: 0.35rem;
transform: translateY(-0.075em);
display: grid;
place-content: center;
cursor: pointer;
transition: all 0.1s ease-in-out;
}

.report-checkbox::before {
content: '';
width: 0.75rem;
height: 0.75rem;
transform: scale(0);
transition: 120ms transform ease-in-out;
box-shadow: inset 1em 1em var(--card-bg-color);
// Use a CSS trick to create a checkmark
transform-origin: bottom left;
clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
}

.report-checkbox:checked::before {
transform: scale(1);
}

.report-checkbox:checked {
background: var(--accent-blue);
border-color: var(--accent-blue);
}

.report-checkbox:hover {
border-color: var(--accent-blue);
}

.toolbar {
display: flex;
justify-content: space-between;
align-items: center;
}

.filter-container {
display: flex;
gap: 1rem;
}

.select-for-comparison {
display: flex;
align-items: center;
Expand Down
84 changes: 2 additions & 82 deletions report-app/src/app/pages/report-list/report-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {MessageSpinner} from '../../shared/message-spinner';
import {Score} from '../../shared/score/score';
import {ProviderLabel} from '../../shared/provider-label';
import {bucketToScoreVariable} from '../../shared/scoring';
import {MultiSelect} from '../../shared/multi-select/multi-select';
import {ReportFilters} from '../../shared/report-filters/report-filters';

@Component({
selector: 'app-report-list',
Expand All @@ -22,98 +22,18 @@ import {MultiSelect} from '../../shared/multi-select/multi-select';
MessageSpinner,
Score,
ProviderLabel,
MultiSelect,
ReportFilters,
],
templateUrl: './report-list.html',
styleUrls: ['./report-list.scss'],
})
export class ReportListComponent {
private reportsFetcher = inject(ReportsFetcher);
private router = inject(Router);
private allGroups = this.reportsFetcher.reportGroups;

protected isLoading = this.reportsFetcher.isLoadingReportsList;
protected reportsToCompare = signal<string[]>([]);
protected isServer = isPlatformServer(inject(PLATFORM_ID));

protected selectedFramework = signal<string | null>(null);
protected selectedModel = signal<string | null>(null);
protected selectedRunner = signal<string | null>(null);
protected selectedLabels = signal<string[]>([]);

protected allFrameworks = computed(() => {
const frameworks = new Map<string, string>();
this.allGroups().forEach(group => {
const framework = group.framework.fullStackFramework;
frameworks.set(framework.id, framework.displayName);
});
return Array.from(frameworks.entries()).map(([id, displayName]) => ({
id,
displayName,
}));
});

protected allModels = computed(() => {
const models = new Set(this.allGroups().map(g => g.model));

return Array.from(models).map(model => ({
id: model,
displayName: model,
}));
});

protected allRunners = computed(() => {
const runners = new Map<string, string>();

this.allGroups().forEach(group => {
if (group.runner) {
runners.set(group.runner.id, group.runner.displayName);
}
});

return Array.from(runners.entries()).map(([id, displayName]) => ({
id,
displayName,
}));
});

protected allLabels = computed(() => {
const labels = new Set<string>();

for (const group of this.allGroups()) {
for (const label of group.labels) {
const trimmed = label.trim();

if (trimmed) {
labels.add(trimmed);
}
}
}

return Array.from(labels)
.sort()
.map(label => ({
label,
value: label,
}));
});

protected reportGroups = computed(() => {
const framework = this.selectedFramework();
const model = this.selectedModel();
const runner = this.selectedRunner();
const labels = this.selectedLabels();
const groups = this.allGroups();

return groups.filter(group => {
const frameworkMatch = !framework || group.framework.fullStackFramework.id === framework;
const modelMatch = !model || group.model === model;
const runnerMatch = !runner || group.runner?.id === runner;
const labelsMatch = labels.length === 0 || group.labels.some(l => labels.includes(l.trim()));
return frameworkMatch && modelMatch && runnerMatch && labelsMatch;
});
});

protected isCompareMode = signal(false);

protected handleCompare() {
Expand Down
5 changes: 5 additions & 0 deletions report-app/src/app/pages/trajectory/trajectory.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<report-filters #filters/>

<div class="card">
<score-visualization [groups]="filters.filteredGroups()" />
</div>
7 changes: 7 additions & 0 deletions report-app/src/app/pages/trajectory/trajectory.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
report-filters {
margin-bottom: 1rem;
}

.card {
padding-top: 0.5rem;
}
12 changes: 12 additions & 0 deletions report-app/src/app/pages/trajectory/trajectory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {ScoreVisualization} from '../../shared/visualization/score-visualization';
import {ReportFilters} from '../../shared/report-filters/report-filters';

@Component({
selector: 'trajectory',
templateUrl: './trajectory.html',
styleUrls: ['./trajectory.scss'],
imports: [ScoreVisualization, ReportFilters],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class Trajectory {}
2 changes: 1 addition & 1 deletion report-app/src/app/shared/multi-select/multi-select.scss
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ label {
}

label:hover {
background-color: #eff6ff;
background-color: var(--button-active-bg-color);
border-radius: var(--border-radius);
}
33 changes: 33 additions & 0 deletions report-app/src/app/shared/report-filters/report-filters.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@if (allFrameworks().length > 1) {
<select (change)="selectedFramework.set($any($event.target).value)">
<option value="">All Frameworks</option>
@for (framework of allFrameworks(); track framework.id) {
<option [value]="framework.id">{{ framework.displayName }}</option>
}
</select>
}

@if (allModels().length > 1) {
<select (change)="selectedModel.set($any($event.target).value)">
<option value="">All Models</option>
@for (model of allModels(); track model.id) {
<option [value]="model.id">{{ model.displayName }}</option>
}
</select>
}

@if (allRunners().length > 1) {
<select (change)="selectedRunner.set($any($event.target).value)">
<option value="">All Runners</option>
@for (runner of allRunners(); track runner.id) {
<option [value]="runner.id">{{ runner.displayName }}</option>
}
</select>
}

@if (allLabels().length > 0) {
<multi-select
[options]="allLabels()"
[(selected)]="selectedLabels"
[label]="selectedLabels().length === 0 ? 'Filter by labels' : `${selectedLabels().length} label(s)`"/>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
:host {
display: flex;
gap: 1rem;
}

select,
multi-select {
max-width: 200px;
}
Loading
Loading