festbench-web/resources/views/livewire/my-runs/index.blade.php

125 lines
No EOL
5.2 KiB
PHP

<?php
use App\Models\BenchmarkRun;
use Flux\Flux;
use Illuminate\Pagination\LengthAwarePaginator;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Layout;
use Livewire\Component;
use Livewire\WithPagination;
new #[Layout('components.layouts.app')] class extends Component {
use WithPagination;
public array $filters = [
'search' => null,
];
public function toggleVisibility(int $id): void
{
$run = BenchmarkRun::where('user_id', auth()->id())->findOrFail($id);
$run->fill([
'visibility' => $run->visibility === BenchmarkRun::VISIBILITY_PUBLIC
? BenchmarkRun::VISIBILITY_PRIVATE
: BenchmarkRun::VISIBILITY_PUBLIC,
])->save();
Flux::toast(variant: 'success', text: __('Visibility updated.'));
}
public function resetFilters(): void
{
$this->filters = ['search' => null];
$this->resetPage();
}
#[Computed]
public function runs(): LengthAwarePaginator
{
return BenchmarkRun::query()
->where('user_id', auth()->id())
->withCount([
'results',
'results as passed_count' => fn ($q) => $q->where('ok', true),
])
->when($this->filters['search'], fn ($q, $search) => $q->where(function ($q) use ($search) {
$q->where('run_id', 'like', "%{$search}%")
->orWhere('model_id', 'like', "%{$search}%")
->orWhere('label', 'like', "%{$search}%");
}))
->orderByDesc('ran_at')
->orderByDesc('id')
->paginate(25);
}
};
?>
<div class="flex flex-col gap-6">
<div class="flex items-center justify-between">
<div>
<flux:heading size="xl">{{ __('My Runs') }}</flux:heading>
<flux:subheading>{{ __('Runs attributed to you. Toggle visibility or add notes from a run page.') }}</flux:subheading>
</div>
<flux:button variant="ghost" icon="arrow-left" href="{{ route('home') }}" wire:navigate>{{ __('All results') }}</flux:button>
</div>
<flux:input
wire:model.live.debounce.300ms="filters.search"
:label="__('Search')"
:placeholder="__('Run, model or label…')"
size="sm"
class="w-72"
clearable
/>
@if ($this->runs->count() > 0)
<flux:table :paginate="$this->runs">
<flux:table.columns>
<flux:table.column>{{ __('Date') }}</flux:table.column>
<flux:table.column>{{ __('Run') }}</flux:table.column>
<flux:table.column>{{ __('Model') }}</flux:table.column>
<flux:table.column>{{ __('Suite') }}</flux:table.column>
<flux:table.column class="text-right">{{ __('Tasks') }}</flux:table.column>
<flux:table.column class="text-right">{{ __('Passed') }}</flux:table.column>
<flux:table.column>{{ __('Visibility') }}</flux:table.column>
<flux:table.column></flux:table.column>
</flux:table.columns>
<flux:table.rows>
@foreach ($this->runs as $run)
<flux:table.row :key="$run->id">
<flux:table.cell>{{ optional($run->ran_at)->format('Y-m-d') }}</flux:table.cell>
<flux:table.cell>
<a href="{{ route('runs.show', $run->run_id) }}" class="font-mono text-xs hover:underline" wire:navigate>{{ $run->run_id }}</a>
</flux:table.cell>
<flux:table.cell>{{ $run->model_id }}</flux:table.cell>
<flux:table.cell><flux:badge size="xs">{{ $run->suite }}</flux:badge></flux:table.cell>
<flux:table.cell class="text-right font-mono text-sm">{{ $run->results_count }}</flux:table.cell>
<flux:table.cell class="text-right font-mono text-sm">{{ $run->passed_count }}</flux:table.cell>
<flux:table.cell>
<flux:badge size="xs" color="{{ $run->visibility === 'public' ? 'emerald' : 'rose' }}">
{{ __($run->visibility) }}
</flux:badge>
</flux:table.cell>
<flux:table.cell>
<flux:button
size="xs"
variant="ghost"
wire:click="toggleVisibility({{ $run->id }})"
icon="{{ $run->visibility === 'public' ? 'lock-closed' : 'lock-open' }}"
>
{{ $run->visibility === 'public' ? __('Make private') : __('Make public') }}
</flux:button>
</flux:table.cell>
</flux:table.row>
@endforeach
</flux:table.rows>
</flux:table>
@else
<flux:callout variant="brand">
<flux:callout.heading>{{ __('No runs yet') }}</flux:callout.heading>
<flux:callout.text>{{ __('Runs you import or submit will appear here.') }}</flux:callout.text>
</flux:callout>
@endif
</div>