Skip to content

Commit

Permalink
Added deferred loading (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
ramonrietdijk authored Jun 11, 2023
1 parent 3e61ac7 commit 6136807
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 30 deletions.
4 changes: 4 additions & 0 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ export default {
text: 'Configuration',
collapsed: false,
items: [
{
text: 'Defer Loading',
link: '/configuration/defer-loading'
},
{
text: 'Query String',
link: '/configuration/query-string'
Expand Down
9 changes: 9 additions & 0 deletions docs/configuration/defer-loading.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Defer Loading

If the query to fetch your data takes a while, it will delay the page from loading. By default, deferred loading is not enabled.

By enabling this feature the records will be fetched after the page has finished loading.

```php
protected bool $deferLoading = true;
```
1 change: 1 addition & 0 deletions resources/views/livewire/livewire-table.blade.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<div class="flex flex-col gap-3 relative"
wire:init="init"
@if(strlen($polling = $this->polling()) > 0) wire:poll.{{ $polling }} @endif
>
@include('livewire-table::bar.bar')
Expand Down
70 changes: 40 additions & 30 deletions resources/views/table/table.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,42 +24,52 @@
</tr>
</thead>
<tbody>
@forelse($paginator->items() as $item)
<tr class="group">
<td class="p-0"
x-bind:class="~selected.indexOf('{{ $item->getKey() }}')
? 'bg-blue-100 group-odd:bg-blue-100 group-hover:bg-blue-200 dark:bg-blue-900 dark:group-odd:bg-blue-900 dark:group-hover:bg-blue-800'
: 'bg-neutral-100 group-odd:bg-white group-hover:bg-neutral-200 dark:bg-neutral-800 dark:group-odd:bg-neutral-900 dark:group-hover:bg-neutral-700'">
<div class="mx-3">
<input type="checkbox" wire:model="selected" value="{{ $item->getKey() }}" class="h-4 w-4">
</div>
</td>
@foreach($table['columns'] as $column)
@continue(! in_array($column->code(), $this->columns))
<td class="p-0"
@if($column->isClickable())
@if(($link = $this->link($item)) !== null)
x-on:click.prevent="window.location.href = '{{ $link }}'"
@else
x-on:click="$wire.selectItem('{{ $item->getKey() }}')"
@endif
@endif
x-bind:class="~selected.indexOf('{{ $item->getKey() }}')
? 'select-none cursor-pointer bg-blue-100 group-odd:bg-blue-100 group-hover:bg-blue-200 dark:bg-blue-900 dark:group-odd:bg-blue-900 dark:group-hover:bg-blue-800'
: 'select-none cursor-pointer bg-neutral-100 group-odd:bg-white group-hover:bg-neutral-200 dark:bg-neutral-800 dark:group-odd:bg-neutral-900 dark:group-hover:bg-neutral-700'">
{{ $column->render($item) }}
</td>
@endforeach
</tr>
@empty
@if($this->deferLoading && ! $this->initialized)
<tr class="group">
<td class="p-0" colspan="{{ $table['columns']->count() + 1 }}">
<span class="block text-lg text-center py-20 bg-white text-black dark:bg-neutral-900 dark:text-white">
@lang('No results')
@lang('Fetching records...')
</span>
</td>
</tr>
@endforelse
@else
@forelse($paginator->items() as $item)
<tr class="group">
<td class="p-0"
x-bind:class="~selected.indexOf('{{ $item->getKey() }}')
? 'bg-blue-100 group-odd:bg-blue-100 group-hover:bg-blue-200 dark:bg-blue-900 dark:group-odd:bg-blue-900 dark:group-hover:bg-blue-800'
: 'bg-neutral-100 group-odd:bg-white group-hover:bg-neutral-200 dark:bg-neutral-800 dark:group-odd:bg-neutral-900 dark:group-hover:bg-neutral-700'">
<div class="mx-3">
<input type="checkbox" wire:model="selected" value="{{ $item->getKey() }}" class="h-4 w-4">
</div>
</td>
@foreach($table['columns'] as $column)
@continue(! in_array($column->code(), $this->columns))
<td class="p-0"
@if($column->isClickable())
@if(($link = $this->link($item)) !== null)
x-on:click.prevent="window.location.href = '{{ $link }}'"
@else
x-on:click="$wire.selectItem('{{ $item->getKey() }}')"
@endif
@endif
x-bind:class="~selected.indexOf('{{ $item->getKey() }}')
? 'select-none cursor-pointer bg-blue-100 group-odd:bg-blue-100 group-hover:bg-blue-200 dark:bg-blue-900 dark:group-odd:bg-blue-900 dark:group-hover:bg-blue-800'
: 'select-none cursor-pointer bg-neutral-100 group-odd:bg-white group-hover:bg-neutral-200 dark:bg-neutral-800 dark:group-odd:bg-neutral-900 dark:group-hover:bg-neutral-700'">
{{ $column->render($item) }}
</td>
@endforeach
</tr>
@empty
<tr class="group">
<td class="p-0" colspan="{{ $table['columns']->count() + 1 }}">
<span class="block text-lg text-center py-20 bg-white text-black dark:bg-neutral-900 dark:text-white">
@lang('No results')
</span>
</td>
</tr>
@endforelse
@endif
</tbody>
<tfoot class="border-t border-neutral-200 dark:border-neutral-700">
<tr class="group">
Expand Down
8 changes: 8 additions & 0 deletions src/Concerns/HasDeferredLoading.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace RamonRietdijk\LivewireTables\Concerns;

trait HasDeferredLoading
{
protected bool $deferLoading = false;
}
13 changes: 13 additions & 0 deletions src/Concerns/HasInitialization.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace RamonRietdijk\LivewireTables\Concerns;

trait HasInitialization
{
public bool $initialized = false;

public function init(): void
{
$this->initialized = true;
}
}
9 changes: 9 additions & 0 deletions src/Http/Livewire/LivewireTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\LengthAwarePaginator as ConcreteLengthAwarePaginator;
use Livewire\Component;
use Livewire\WithPagination;
use RamonRietdijk\LivewireTables\Columns\BaseColumn;
use RamonRietdijk\LivewireTables\Concerns\HasActions;
use RamonRietdijk\LivewireTables\Concerns\HasColumns;
use RamonRietdijk\LivewireTables\Concerns\HasDeferredLoading;
use RamonRietdijk\LivewireTables\Concerns\HasFilters;
use RamonRietdijk\LivewireTables\Concerns\HasInitialization;
use RamonRietdijk\LivewireTables\Concerns\HasPagination;
use RamonRietdijk\LivewireTables\Concerns\HasPolling;
use RamonRietdijk\LivewireTables\Concerns\HasQueryString;
Expand All @@ -27,7 +30,9 @@ class LivewireTable extends Component
use WithPagination;
use HasActions;
use HasColumns;
use HasDeferredLoading;
use HasFilters;
use HasInitialization;
use HasPagination;
use HasPolling;
use HasQueryString;
Expand Down Expand Up @@ -99,6 +104,10 @@ protected function appliedQuery(): Builder
/** @return LengthAwarePaginator<Model> */
protected function paginate(): LengthAwarePaginator
{
if ($this->deferLoading && ! $this->initialized) {
return new ConcreteLengthAwarePaginator([], 0, $this->perPage());
}

return $this->appliedQuery()->paginate($this->perPage());
}

Expand Down
13 changes: 13 additions & 0 deletions tests/Fakes/Http/Livewire/DeferredLoadingBlogLivewireTable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace RamonRietdijk\LivewireTables\Tests\Fakes\Http\Livewire;

use RamonRietdijk\LivewireTables\Http\Livewire\LivewireTable;
use RamonRietdijk\LivewireTables\Tests\Fakes\Models\Blog;

class DeferredLoadingBlogLivewireTable extends LivewireTable
{
protected string $model = Blog::class;

protected bool $deferLoading = true;
}
19 changes: 19 additions & 0 deletions tests/Integration/Concerns/HasDeferredLoadingTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace RamonRietdijk\LivewireTables\Tests\Integration\Concerns;

use Livewire\Livewire;
use RamonRietdijk\LivewireTables\Tests\Fakes\Http\Livewire\DeferredLoadingBlogLivewireTable;
use RamonRietdijk\LivewireTables\Tests\TestCase;

class HasDeferredLoadingTest extends TestCase
{
/** @test */
public function it_can_defer_loading(): void
{
Livewire::test(DeferredLoadingBlogLivewireTable::class)
->assertSee('Fetching records...')
->call('init')
->assertDontSee('Fetching records...');
}
}
19 changes: 19 additions & 0 deletions tests/Integration/Concerns/HasInitializationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace RamonRietdijk\LivewireTables\Tests\Integration\Concerns;

use Livewire\Livewire;
use RamonRietdijk\LivewireTables\Tests\Fakes\Http\Livewire\BlogLivewireTable;
use RamonRietdijk\LivewireTables\Tests\TestCase;

class HasInitializationTest extends TestCase
{
/** @test */
public function it_can_be_initialized(): void
{
Livewire::test(BlogLivewireTable::class)
->assertSet('initialized', false)
->call('init')
->assertSet('initialized', true);
}
}

0 comments on commit 6136807

Please sign in to comment.