Skip to content

Commit 6de8a14

Browse files
authored
Merge pull request #617 from rappasoft/develop
v1.22.0
2 parents 5ec4a23 + 652005a commit 6de8a14

24 files changed

+369
-222
lines changed

CHANGELOG.md

+213-196
Large diffs are not rendered by default.

docs/bulk-actions/resetting-after-bulk-actions.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ public function myBulkAction()
3434
$this->resetSearch(); // Remove the search query
3535
$this->resetSorts(); // Remove the sorts
3636
$this->resetBulk(); // Clear the selected rows
37-
$this->resetPage(); // Go back to page 1
37+
$this->resetPage($this->pageName()); // Go back to page 1
3838
}
3939
```

docs/filters/creating-filters.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Creating filters is not required, and the filters box will be hidden if none are
77

88
To create filters, you return an array of `Filter` class objects from the `filters()` method.
99

10-
The current types of filters are: `select`, `multiSelect`, and `date`.
10+
The current types of filters are: `select`, `multiSelect`, `date`, and `datetime` (for supported browsers).
1111

1212
There are two steps to making a filter:
1313

@@ -49,7 +49,7 @@ public function filters(): array
4949
'tag2' => 'Tags 2',
5050
'tag3' => 'Tags 3',
5151
'tag4' => 'Tags 4',
52-
]),
52+
]),
5353
];
5454
}
5555
```

docs/rows/clickable-rows.md

+18
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,21 @@ public function redirectToModel(string $name, array $parameters = [], $absolute
5353
```
5454

5555
Now the blank space of the row should have its action, while your links go to their own action.
56+
57+
## Working with `wire:click` on rows
58+
59+
You can add the row-level Livewire clicks by utilizing the following method.
60+
61+
```php
62+
public function getTableRowWireClick($row): ?string
63+
{
64+
return "doSomething(" . $row->id . ")";
65+
}
66+
67+
public function doSomething($id)
68+
{
69+
// ...
70+
}
71+
```
72+
73+
If you state both `getTableRowUrl` & `getTableRowWireClick`, the URL will supersede when a non-null value is supplied.

resources/lang/ar.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
"Bulk Actions": "إجراءات",
66
"Clear": "مسح",
77
"Filters": "التصفيات",
8-
"Remove filter option": "خذف خيار التصفيه",
9-
"Remove sort option": "خذف خيار الترتيب",
8+
"Remove filter option": "حذف خيار التصفية",
9+
"Remove sort option": "حذف خيار الترتيب",
1010
"Search": "بحث",
1111
"Select All": "تحديد الكل",
12-
"Showing": "إستعراض",
12+
"Showing": "استعراض",
1313
"Unselect All": "إلغاء تحديد الكل",
1414
"You are currently selecting all": "أنت الآن تختار الكل",
1515
"You are not connected to the internet.": "أنت غير متصل بالإنترنت.",
@@ -18,5 +18,5 @@
1818
"results": "النتائج",
1919
"rows": "صفوف",
2020
"rows, do you want to select all": "الصفوف ، هل تريد تحديد الكل",
21-
"to": "إلي"
21+
"to": "إلى"
2222
}

resources/lang/es.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
22
"All": "Todo",
33
"Applied Filters": "Filtros Aplicados",
4-
"Applied Sorting": "Ordenamineto Aplicado",
4+
"Applied Sorting": "Ordenamiento Aplicado",
55
"Bulk Actions": "Acciones Masivas",
66
"Clear": "Borrar",
77
"Columns": "Columnas",
8-
"Done Reordering": "Reordenación finalizada",
8+
"Done Reordering": "Reordenamiento finalizado",
99
"Filters": "Filtros",
1010
"Remove filter option": "Remover opción de filtro",
11-
"Remove sort option": "Remover opción de ordenamineto",
11+
"Remove sort option": "Remover opción de ordenamiento",
1212
"Search": "Buscar",
1313
"Select All": "Seleccionar todo",
1414
"Showing": "Mostrando",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<div class="mb-3 mb-md-0 input-group">
2+
<input
3+
wire:model="filters.{{ $key }}"
4+
wire:key="filter-{{ $key }}"
5+
id="filter-{{ $key }}"
6+
type="datetime-local"
7+
@if(isset($filter->options['min']) && strlen($filter->options['min'])) min="{{ $filter->options['min'] }}" @endif
8+
@if(isset($filter->options['max']) && strlen($filter->options['max'])) max="{{ $filter->options['max'] }}" @endif
9+
class="form-control"
10+
/>
11+
</div>

resources/views/bootstrap-4/includes/filters.blade.php

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class="dropdown-menu w-100 mt-md-3"
4242
@include('livewire-tables::bootstrap-4.includes.filter-type-multiselect')
4343
@elseif($filter->isDate())
4444
@include('livewire-tables::bootstrap-4.includes.filter-type-date')
45+
@elseif($filter->isDatetime())
46+
@include('livewire-tables::bootstrap-4.includes.filter-type-datetime')
4547
@endif
4648
</div>
4749
@endforeach

resources/views/bootstrap-4/includes/table.blade.php

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
:reordering="$reordering"
9999
:url="method_exists($this, 'getTableRowUrl') ? $this->getTableRowUrl($row) : ''"
100100
:target="method_exists($this, 'getTableRowUrlTarget') ? $this->getTableRowUrlTarget($row) : '_self'"
101+
:wireclick="method_exists($this, 'getTableRowWireClick') ? $this->getTableRowWireClick($row) : ''"
101102
:class="method_exists($this, 'setTableRowClass') ? ' ' . $this->setTableRowClass($row) : ''"
102103
:id="method_exists($this, 'setTableRowId') ? $this->setTableRowId($row) : ''"
103104
:customAttributes="method_exists($this, 'setTableRowAttributes') ? $this->setTableRowAttributes($row) : []"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<div class="flex rounded-md shadow-sm mt-1">
2+
<input
3+
wire:model="filters.{{ $key }}"
4+
wire:key="filter-{{ $key }}"
5+
id="filter-{{ $key }}"
6+
type="datetime-local"
7+
@if(isset($filter->options['min']) && strlen($filter->options['min'])) min="{{ $filter->options['min'] }}" @endif
8+
@if(isset($filter->options['max']) && strlen($filter->options['max'])) max="{{ $filter->options['max'] }}" @endif
9+
class="form-control"
10+
/>
11+
</div>

resources/views/bootstrap-5/includes/filters.blade.php

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class="dropdown-menu w-100"
4242
@include('livewire-tables::bootstrap-5.includes.filter-type-multiselect')
4343
@elseif($filter->isDate())
4444
@include('livewire-tables::bootstrap-5.includes.filter-type-date')
45+
@elseif($filter->isDatetime())
46+
@include('livewire-tables::bootstrap-5.includes.filter-type-datetime')
4547
@endif
4648
</div>
4749
@endforeach

resources/views/bootstrap-5/includes/table.blade.php

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class="form-check-input"
9999
:reordering="$reordering"
100100
:url="method_exists($this, 'getTableRowUrl') ? $this->getTableRowUrl($row) : ''"
101101
:target="method_exists($this, 'getTableRowUrlTarget') ? $this->getTableRowUrlTarget($row) : '_self'"
102+
:wireclick="method_exists($this, 'getTableRowWireClick') ? $this->getTableRowWireClick($row) : ''"
102103
:class="method_exists($this, 'setTableRowClass') ? ' ' . $this->setTableRowClass($row) : ''"
103104
:id="method_exists($this, 'setTableRowId') ? $this->setTableRowId($row) : ''"
104105
:customAttributes="method_exists($this, 'setTableRowAttributes') ? $this->setTableRowAttributes($row) : []"

resources/views/tailwind/components/table/row.blade.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@props(['url' => null, 'target' => '_self', 'reordering' => false, 'customAttributes' => []])
1+
@props(['url' => null, 'wireclick' => null, 'target' => '_self', 'reordering' => false, 'customAttributes' => []])
22

33
@if (!$reordering && (method_exists($attributes, 'has') ? $attributes->has('wire:sortable.item') : array_key_exists('wire:sortable.item', $attributes->getAttributes())))
44
@php
@@ -7,10 +7,12 @@
77
@endif
88

99
<tr
10-
{{ $attributes->merge($customAttributes)->merge(['class' => $url ? 'cursor-pointer' : '']) }}
10+
{{ $attributes->merge($customAttributes)->merge(['class' => ($url || $wireclick) ? 'cursor-pointer' : '']) }}
1111

1212
@if ($url)
1313
onclick="window.open('{{ $url }}', '{{ $target }}')"
14+
@elseif ($wireclick)
15+
wire:click="{{ $wireclick }}"
1416
@endif
1517
>
1618
{{ $slot }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<div class="flex rounded-md shadow-sm mt-1">
2+
<input
3+
wire:model.stop="filters.{{ $key }}"
4+
wire:key="filter-{{ $key }}"
5+
id="filter-{{ $key }}"
6+
type="datetime-local"
7+
@if(isset($filter->options['min']) && strlen($filter->options['min'])) min="{{ $filter->options['min'] }}" @endif
8+
@if(isset($filter->options['max']) && strlen($filter->options['max'])) max="{{ $filter->options['max'] }}" @endif
9+
class="block w-full border-gray-300 rounded-md shadow-sm transition duration-150 ease-in-out focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 dark:bg-gray-800 dark:text-white dark:border-gray-600"
10+
/>
11+
</div>

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

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class="block text-sm font-medium leading-5 text-gray-700 dark:text-white">
6262
@include('livewire-tables::tailwind.includes.filter-type-multiselect')
6363
@elseif($filter->isDate())
6464
@include('livewire-tables::tailwind.includes.filter-type-date')
65+
@elseif($filter->isDatetime())
66+
@include('livewire-tables::tailwind.includes.filter-type-datetime')
6567
@endif
6668
</div>
6769
</div>

resources/views/tailwind/includes/partials/pagination.blade.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@
1010
{!! __('pagination.previous') !!}
1111
</span>
1212
@else
13-
<button wire:click="previousPage('{{ $paginator->getPageName() }}')" wire:loading.attr="disabled" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}.before" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:border-gray-600 dark:hover:bg-gray-600">
13+
<button type="button" wire:click="previousPage('{{ $paginator->getPageName() }}')" wire:loading.attr="disabled" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}.before" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:border-gray-600 dark:hover:bg-gray-600">
1414
{!! __('pagination.previous') !!}
1515
</button>
1616
@endif
1717
</span>
1818

1919
<span>
2020
@if ($paginator->hasMorePages())
21-
<button wire:click="nextPage('{{ $paginator->getPageName() }}')" wire:loading.attr="disabled" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}.before" class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:border-gray-600 dark:hover:bg-gray-600">
21+
<button type="button" wire:click="nextPage('{{ $paginator->getPageName() }}')" wire:loading.attr="disabled" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}.before" class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:border-gray-600 dark:hover:bg-gray-600">
2222
{!! __('pagination.next') !!}
2323
</button>
2424
@else
@@ -55,7 +55,7 @@
5555
</span>
5656
</span>
5757
@else
58-
<button wire:click="previousPage('{{ $paginator->getPageName() }}')" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}.after" rel="prev" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150 dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:border-gray-600 dark:hover:bg-gray-600" aria-label="{{ __('pagination.previous') }}">
58+
<button type="button" wire:click="previousPage('{{ $paginator->getPageName() }}')" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}.after" rel="prev" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150 dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:border-gray-600 dark:hover:bg-gray-600" aria-label="{{ __('pagination.previous') }}">
5959
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
6060
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
6161
</svg>
@@ -81,7 +81,7 @@
8181
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 dark:bg-gray-500 dark:text-white dark:border-gray-500">{{ $page }}</span>
8282
</span>
8383
@else
84-
<button wire:click="gotoPage({{ $page }}, '{{ $paginator->getPageName() }}')" class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:border-gray-600 dark:hover:bg-gray-600" aria-label="{{ __('Go to page :page', ['page' => $page]) }}">
84+
<button type="button" wire:click="gotoPage({{ $page }}, '{{ $paginator->getPageName() }}')" class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:border-gray-600 dark:hover:bg-gray-600" aria-label="{{ __('Go to page :page', ['page' => $page]) }}">
8585
{{ $page }}
8686
</button>
8787
@endif
@@ -93,7 +93,7 @@
9393
<span>
9494
{{-- Next Page Link --}}
9595
@if ($paginator->hasMorePages())
96-
<button wire:click="nextPage('{{ $paginator->getPageName() }}')" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}.after" rel="next" class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150 dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:border-gray-600 dark:hover:bg-gray-600" aria-label="{{ __('pagination.next') }}">
96+
<button type="button" wire:click="nextPage('{{ $paginator->getPageName() }}')" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}.after" rel="next" class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150 dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:border-gray-600 dark:hover:bg-gray-600" aria-label="{{ __('pagination.next') }}">
9797
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
9898
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
9999
</svg>

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

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ class="rounded border-gray-300 text-indigo-600 shadow-sm transition duration-150
101101
:reordering="$reordering"
102102
:url="method_exists($this, 'getTableRowUrl') ? $this->getTableRowUrl($row) : ''"
103103
:target="method_exists($this, 'getTableRowUrlTarget') ? $this->getTableRowUrlTarget($row) : '_self'"
104+
:wireclick="method_exists($this, 'getTableRowWireClick') ? $this->getTableRowWireClick($row) : ''"
104105
:class="
105106
($index % 2 === 0 ?
106107
'bg-white dark:bg-gray-700 dark:text-white' . (method_exists($this, 'getTableRowUrl') ? ' hover:bg-gray-100' : '') :

src/Commands/MakeCommand.php

+39-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Rappasoft\LaravelLivewireTables\Commands;
44

55
use Illuminate\Console\Command;
6+
use Illuminate\Database\Eloquent\Model;
67
use Illuminate\Support\Facades\File;
78
use Illuminate\Support\Str;
89
use Livewire\Commands\ComponentParser;
@@ -141,8 +142,8 @@ public function classContents(): string
141142
$template = file_get_contents(__DIR__.DIRECTORY_SEPARATOR.'table-with-model.stub');
142143

143144
$contents = str_replace(
144-
['[namespace]', '[class]', '[model]', '[model_import]'],
145-
[$this->parser->classNamespace(), $this->parser->className(), $this->model, $this->getModelImport()],
145+
['[namespace]', '[class]', '[model]', '[model_import]', '[columns]'],
146+
[$this->parser->classNamespace(), $this->parser->className(), $this->model, $this->getModelImport(), $this->generateColumns($this->getModelImport())],
146147
$template
147148
);
148149
} else {
@@ -204,4 +205,40 @@ public function getModelImport(): string
204205

205206
return 'App\Models\\' . $this->model;
206207
}
208+
209+
/**
210+
* @param string $modelName
211+
* @return string
212+
* @throws Exception
213+
*/
214+
private function generateColumns(string $modelName): string
215+
{
216+
$model = new $modelName();
217+
218+
if ($model instanceof Model === false) {
219+
throw new \Exception('Invalid model given.');
220+
}
221+
222+
$getFillable = array_merge(
223+
[$model->getKeyName()],
224+
$model->getFillable(),
225+
['created_at', 'updated_at']
226+
);
227+
228+
$columns = "[\n";
229+
230+
foreach ($getFillable as $field) {
231+
if (in_array($field, $model->getHidden())) {
232+
continue;
233+
}
234+
235+
$title = Str::of($field)->replace('_', ' ')->ucfirst();
236+
237+
$columns .= ' Column::make("' . $title . '", "' . $field . '")' . "\n" . ' ->sortable(),' . "\n";
238+
}
239+
240+
$columns .= " ]";
241+
242+
return $columns;
243+
}
207244
}

0 commit comments

Comments
 (0)