Skip to content

Commit 6b112ce

Browse files
authored
Merge pull request #220 from rappasoft/develop
v1.1
2 parents 1b3fe44 + b56c7b7 commit 6b112ce

File tree

18 files changed

+445
-33
lines changed

18 files changed

+445
-33
lines changed

CHANGELOG.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@ All notable changes to `laravel-livewire-tables` will be documented in this file
44

55
## [Unreleased]
66

7+
## [1.1.0] - 2021-04-21
8+
9+
### Added
10+
11+
- Added callback to column's sortable() method to customize sorting functionality per column. (https://github.com/rappasoft/laravel-livewire-tables/pull/216)
12+
- Support for polling `keep-alive` and `visible`.
13+
- Start of a test suite (https://github.com/rappasoft/laravel-livewire-tables/pull/218)
14+
15+
### Changed
16+
17+
- Updated Tailwind search clear button (https://github.com/rappasoft/laravel-livewire-tables/pull/217).
18+
- Updated readme
19+
720
## [1.0.4] - 2021-04-18
821

922
### Added
@@ -192,7 +205,8 @@ All notable changes to `laravel-livewire-tables` will be documented in this file
192205

193206
- Initial release
194207

195-
[Unreleased]: https://github.com/rappasoft/laravel-livewire-tables/compare/v1.0.4...development
208+
[Unreleased]: https://github.com/rappasoft/laravel-livewire-tables/compare/v1.1.0...development
209+
[1.1.0]: https://github.com/rappasoft/laravel-livewire-tables/compare/v1.0.4...v1.1.0
196210
[1.0.4]: https://github.com/rappasoft/laravel-livewire-tables/compare/v1.0.3...v1.0.4
197211
[1.0.3]: https://github.com/rappasoft/laravel-livewire-tables/compare/v1.0.2...v1.0.3
198212
[1.0.2]: https://github.com/rappasoft/laravel-livewire-tables/compare/v1.0.1...v1.0.2

README.md

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,9 @@ public function columns(): array
192192
{
193193
return [
194194
Column::make('Type') // Column text and optional column name, column name will be snake case of text if not defined
195-
->sortable() // Whether or not the heading can be clicked to sort
195+
->sortable(), // Whether or not the heading can be clicked to sort
196196
Column::make('Name')
197-
->sortable()
197+
->sortable(),
198198
Column::make('Permissions'),
199199
Column::make('Other', 'my_other_column')
200200
->sortable() // Allows the column to interact with the sorting methods
@@ -204,6 +204,17 @@ public function columns(): array
204204
}
205205
```
206206

207+
#### Customizing Sort Behavior
208+
209+
If you need more control over the sort behavior of a column, you can pass a callback to the sortable() method:
210+
211+
```php
212+
Column::make(__('Address'))
213+
->sortable(function(Builder $query, $direction) {
214+
return $query->orderBy(UserAttribute::select('address')->whereColumn('user_attributes.user_id', 'users.id'), $direction);
215+
})
216+
```
217+
207218
#### Configuring Sort Names
208219

209220
When clicking sortable column headers, the component will use the column name to define the sorting pill in the UI, if you don't like the way the name is rendered, you can overwrite it:
@@ -392,7 +403,7 @@ There are some class level properties you can set:
392403
| $searchFilterDebounce | null | null/int | Adds a debounce of `$searchFilterDebounce` ms to the search input |
393404
| $searchFilterDefer | null | null/bool | Adds `.defer` to the search input |
394405
| $searchFilterLazy | null | null/bool | Adds `.lazy` to the search input |
395-
| $refresh | false | false/int/string | Whether or not to refresh the table at a certain interval. false = off, int = ms, string = functionCall |
406+
| $refresh | false | false/int/string | Whether or not to refresh the table at a certain interval. false = off, int = ms, string = functionCall (if the string is `keep-alive` it will use `wire:poll.keep-alive`, if the string is `visible` it will use `wire:poll.visible`) |
396407
| $offlineIndicator | true | bool | Shows a red banner when there is no internet connection. |
397408

398409
#### Using more than one table on a page
@@ -427,13 +438,6 @@ use Rappasoft\LaravelLivewireTables\Views\Filter;
427438
class UsersTable extends DataTableComponent
428439
{
429440

430-
public array $filters = [
431-
'type' => null,
432-
'active' => null,
433-
'verified' => null,
434-
'2fa' => null,
435-
];
436-
437441
public array $sortNames = [
438442
'email_verified_at' => 'Verified',
439443
'two_factor_secret' => '2FA',
@@ -618,11 +622,18 @@ The final result would look like:
618622

619623
- [x] Bootstrap 4 Template
620624
- [x] Bootstrap 5 Template
621-
- [ ] Sorting By Relationships
622-
- [ ] Test Suite
625+
- [x] Sorting By Relationships
626+
- [ ] Collection/Query Support
627+
- [ ] Test Suite (WIP)
623628
- [ ] Column Search
624629
- [ ] Greater Configurability
625630

631+
## Testing
632+
633+
```bash
634+
composer test
635+
```
636+
626637
## Changelog
627638

628639
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"illuminate/contracts": "^8.0"
2525
},
2626
"require-dev": {
27+
"ext-sqlite3": "*",
2728
"orchestra/testbench": "^6.13",
2829
"phpunit/phpunit": "^9.3",
2930
"spatie/laravel-ray": "^1.9",
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class CreateTestTables extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::create('species', function (Blueprint $table) {
17+
$table->id();
18+
$table->string('name');
19+
});
20+
21+
Schema::create('breeds', function (Blueprint $table) {
22+
$table->id();
23+
$table->string('name');
24+
$table->integer('species_id')->unsigned();
25+
$table->foreign('species_id')->references('id')->on('species');
26+
});
27+
28+
Schema::create('pets', function (Blueprint $table) {
29+
$table->id();
30+
$table->string('name')->index();
31+
$table->string('age')->nullable();
32+
$table->date('last_visit')->nullable();
33+
$table->integer('species_id')->unsigned()->nullable();
34+
$table->integer('breed_id')->unsigned()->nullable();
35+
$table->foreign('species_id')->references('id')->on('species');
36+
$table->foreign('breed_id')->references('id')->on('breeds');
37+
});
38+
}
39+
}

resources/views/bootstrap-4/datatable.blade.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
<div
2-
@if (is_numeric($refresh)) wire:poll.{{ $refresh }}ms @elseif(is_string($refresh)) wire:poll="{{ $refresh }}" @endif
2+
@if (is_numeric($refresh))
3+
wire:poll.{{ $refresh }}ms
4+
@elseif(is_string($refresh))
5+
@if ($refresh === '.keep-alive' || $refresh === 'keep-alive')
6+
wire:poll.keep-alive
7+
@elseif($refresh === '.visible' || $refresh === 'visible')
8+
wire:poll.visible
9+
@else
10+
wire:poll="{{ $refresh }}"
11+
@endif
12+
@endif
313
class="container-fluid"
414
>
515
@include('livewire-tables::bootstrap-4.includes.offline')

resources/views/bootstrap-5/datatable.blade.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
<div
2-
@if (is_numeric($refresh)) wire:poll.{{ $refresh }}ms @elseif(is_string($refresh)) wire:poll="{{ $refresh }}" @endif
2+
@if (is_numeric($refresh))
3+
wire:poll.{{ $refresh }}ms
4+
@elseif(is_string($refresh))
5+
@if ($refresh === '.keep-alive' || $refresh === 'keep-alive')
6+
wire:poll.keep-alive
7+
@elseif($refresh === '.visible' || $refresh === 'visible')
8+
wire:poll.visible
9+
@else
10+
wire:poll="{{ $refresh }}"
11+
@endif
12+
@endif
313
class="container-fluid"
414
>
515
@include('livewire-tables::bootstrap-5.includes.offline')

resources/views/tailwind/datatable.blade.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
<div
2-
@if (is_numeric($refresh)) wire:poll.{{ $refresh }}ms @elseif(is_string($refresh)) wire:poll="{{ $refresh }}" @endif
2+
@if (is_numeric($refresh))
3+
wire:poll.{{ $refresh }}ms
4+
@elseif(is_string($refresh))
5+
@if ($refresh === '.keep-alive' || $refresh === 'keep-alive')
6+
wire:poll.keep-alive
7+
@elseif($refresh === '.visible' || $refresh === 'visible')
8+
wire:poll.visible
9+
@else
10+
wire:poll="{{ $refresh }}"
11+
@endif
12+
@endif
313
>
414
@include('livewire-tables::tailwind.includes.offline')
515

resources/views/tailwind/includes/search.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ class="flex-1 shadow-sm border-cool-gray-300 block w-full transition duration-15
88
/>
99

1010
@if (isset($filters['search']) && strlen($filters['search']))
11-
<span class="inline-flex items-center px-3 rounded-r-md border border-l-0 border-gray-300 bg-gray-50 text-gray-500 sm:text-sm">
12-
<svg wire:click="$set('filters.search', null)" xmlns="http://www.w3.org/2000/svg" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
11+
<span wire:click="$set('filters.search', null)" class="inline-flex items-center px-3 rounded-r-md border border-l-0 border-gray-300 bg-gray-50 text-gray-500 cursor-pointer sm:text-sm">
12+
<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1313
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
1414
</svg>
1515
</span>

src/DataTableComponent.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ abstract class DataTableComponent extends Component
6868
* Whether or not to refresh the table at a certain interval
6969
* false is off
7070
* If it's an integer it will be treated as milliseconds (2000 = refresh every 2 seconds)
71-
* If it's a string it will call that function every 5 seconds.
71+
* If it's a string it will call that function every 5 seconds unless it is 'keep-alive' or 'visible'.
7272
*
7373
* @var bool|string
7474
*/
@@ -190,4 +190,18 @@ public function render()
190190
'rows' => $this->rows,
191191
]);
192192
}
193+
194+
/**
195+
* Get a column object by its field
196+
*
197+
* @param string $column
198+
*
199+
* @return mixed
200+
*/
201+
protected function getColumn(string $column)
202+
{
203+
return collect($this->columns())
204+
->where('column', $column)
205+
->first();
206+
}
193207
}

src/Traits/WithSorting.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ public function sortBy(string $field): ?string
3030
public function applySorting(Builder $query): Builder
3131
{
3232
foreach ($this->sorts as $field => $direction) {
33-
$query->orderBy($field, $direction);
33+
if (optional($this->getColumn($field))->hasSortCallback()) {
34+
$query = app()->call($this->getColumn($field)->getSortCallback(), ['query' => $query, 'direction' => $direction]);
35+
} else {
36+
$query->orderBy($field, $direction);
37+
}
3438
}
3539

3640
return $query;

0 commit comments

Comments
 (0)