mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
feat(tables): show loading state while a server-side sort runs
This commit is contained in:
@@ -5,7 +5,8 @@
|
||||
Alpine tables set `model` (the sort variable in the enclosing x-data scope) and an
|
||||
optional `then` expression that runs after the change (for example `page = 1`).
|
||||
Livewire tables set `action` (a component method that takes the sort value) and
|
||||
`current` (the current server-side sort value).
|
||||
`current` (the current server-side sort value). While that request runs, the
|
||||
clicked header shows a spinner.
|
||||
|
||||
@param string $label
|
||||
@param string $asc sort value for ascending order
|
||||
@@ -37,15 +38,22 @@
|
||||
default => null,
|
||||
};
|
||||
$nextValue = $current === $firstValue ? $otherValue : $firstValue;
|
||||
$call = $action.'('.\Illuminate\Support\Js::from($nextValue).')';
|
||||
@endphp
|
||||
<button type="button" wire:click="{{ $action }}(@js($nextValue))"
|
||||
<button type="button" wire:click="{{ $call }}" wire:loading.attr="aria-busy" wire:target="{{ $call }}"
|
||||
aria-label="{{ $ariaBase }}{{ $direction ? ', sorted '.($direction === 'asc' ? 'ascending' : 'descending') : '' }}"
|
||||
{{ $attributes->class(['table-sort-header group', 'is-sorted' => $direction]) }}>
|
||||
<span class="truncate">{{ $label }}</span>
|
||||
<svg @class(['table-sort-header-icon', 'rotate-180' => $direction === 'desc', 'is-visible' => $direction]) viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true">
|
||||
fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"
|
||||
wire:loading.remove wire:target="{{ $call }}">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 15l6-6 6 6" />
|
||||
</svg>
|
||||
<svg class="size-3 shrink-0 animate-spin" viewBox="0 0 24 24" fill="none" aria-hidden="true"
|
||||
wire:loading wire:target="{{ $call }}">
|
||||
<circle class="opacity-20" cx="12" cy="12" r="9" stroke="currentColor" stroke-width="3" />
|
||||
<path d="M21 12a9 9 0 0 0-9-9" stroke="currentColor" stroke-width="3" stroke-linecap="round" />
|
||||
</svg>
|
||||
</button>
|
||||
@else
|
||||
<button type="button"
|
||||
|
||||
@@ -160,7 +160,8 @@
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div x-show="viewMode === 'table'" class="{{ $tableShell }}">
|
||||
<div x-show="viewMode === 'table'" class="{{ $tableShell }} transition-opacity" wire:loading.class="opacity-50 pointer-events-none"
|
||||
wire:target="setProjectSort">
|
||||
<div class="grid grid-cols-[minmax(0,1fr)_7rem_4rem] gap-4 @2xl:min-w-[560px] @2xl:grid-cols-[minmax(0,1.2fr)_7rem_minmax(0,1.5fr)_4rem] {{ $tableHead }}">
|
||||
<x-table.sort-header label="Project" asc="name-asc" desc="name-desc"
|
||||
action="setProjectSort" :current="$projectSort" />
|
||||
@@ -344,7 +345,8 @@
|
||||
? 'grid-cols-[minmax(0,1fr)_9.5rem] @xl:grid-cols-[minmax(0,1fr)_9rem_9.5rem] @2xl:grid-cols-[minmax(0,1fr)_minmax(0,1.5fr)_9rem_9.5rem]'
|
||||
: 'grid-cols-[minmax(0,1fr)_9.5rem] @2xl:grid-cols-[minmax(0,1fr)_minmax(0,1.5fr)_9.5rem]';
|
||||
@endphp
|
||||
<div x-show="viewMode === 'table'" class="{{ $tableShell }}">
|
||||
<div x-show="viewMode === 'table'" class="{{ $tableShell }} transition-opacity" wire:loading.class="opacity-50 pointer-events-none"
|
||||
wire:target="setServerSort">
|
||||
<div class="grid {{ $serverTableColumns }} gap-4 @2xl:min-w-[480px] {{ $tableHead }}">
|
||||
<x-table.sort-header label="Server" asc="name-asc" desc="name-desc"
|
||||
action="setServerSort" :current="$serverSort" />
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
@if ($deployments->isNotEmpty())
|
||||
<div class="data-table relative w-full transition-opacity"
|
||||
wire:loading.class="opacity-50 pointer-events-none"
|
||||
wire:target="goToPage,previousPage,nextPage,toggleDeploymentFilter,clearFilter,setPullRequestFilter">
|
||||
wire:target="goToPage,previousPage,nextPage,toggleDeploymentFilter,clearFilter,setPullRequestFilter,setDeploymentSort">
|
||||
<x-table.loading id="deployment-table-filter-loading"
|
||||
target="toggleDeploymentFilter,clearFilter,setPullRequestFilter"
|
||||
text="Filtering deployments..." class="rounded-lg" />
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
: 'Images pulled or built on this server will appear here.'" icon-name="layers" />
|
||||
</div>
|
||||
@else
|
||||
<div class="data-table">
|
||||
<div class="data-table transition-opacity" wire:loading.class="opacity-50 pointer-events-none" wire:target="setSort">
|
||||
<div class="data-table-header server-images-table-grid">
|
||||
<x-table.sort-header label="Repository" asc="repository_asc" desc="repository_desc"
|
||||
action="setSort" :current="$sort" />
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
wire:loading.attr="inert" wire:target="search">
|
||||
@if ($activeTab === 'managed')
|
||||
@if ($resources->total() > 0)
|
||||
<div class="data-table">
|
||||
<div class="data-table transition-opacity" wire:loading.class="opacity-50 pointer-events-none" wire:target="setSort">
|
||||
<div class="data-table-header server-resources-managed-table-grid">
|
||||
<x-table.sort-header label="Name" asc="name_asc" desc="name_desc" action="setSort" :current="$sort" />
|
||||
<x-table.sort-header label="Project" asc="project_asc" desc="project_desc" action="setSort" :current="$sort" />
|
||||
@@ -107,7 +107,7 @@
|
||||
@endif
|
||||
@else
|
||||
@if ($resources->total() > 0)
|
||||
<div class="data-table">
|
||||
<div class="data-table transition-opacity" wire:loading.class="opacity-50 pointer-events-none" wire:target="setSort">
|
||||
<div class="data-table-header server-resources-unmanaged-table-grid">
|
||||
<x-table.sort-header label="Name" asc="name_asc" desc="name_desc" action="setSort" :current="$sort" />
|
||||
<x-table.sort-header label="Image" asc="image_asc" desc="image_desc" action="setSort" :current="$sort" />
|
||||
|
||||
@@ -418,7 +418,8 @@
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
|
||||
<div wire:poll="getDeployments" class="overflow-x-auto">
|
||||
<div wire:poll="getDeployments" class="overflow-x-auto transition-opacity" wire:loading.class="opacity-50 pointer-events-none"
|
||||
wire:target="setDeploymentSort">
|
||||
@if (count($deploymentsPerTagPerServer ?? []) === 0)
|
||||
<div class="p-3">
|
||||
<x-empty title="No active deployments"
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
<x-application.settings-section title="Pending invitations"
|
||||
description="Invitation links that have not been accepted yet." flush>
|
||||
<div class="overflow-x-auto">
|
||||
<div class="data-table min-w-[760px]">
|
||||
<div class="data-table min-w-[760px] transition-opacity" wire:loading.class="opacity-50 pointer-events-none"
|
||||
wire:target="setSort">
|
||||
<div
|
||||
class="data-table-header grid-cols-[minmax(13rem,1.2fr)_7rem_7rem_minmax(15rem,1.5fr)_6rem]">
|
||||
<x-table.sort-header label="Email" asc="email-asc" desc="email-desc" action="setSort"
|
||||
|
||||
Reference in New Issue
Block a user