Suggestions/recommendations
kdion4891 opened this issue · comments
Here are some suggestions/recommendations.
1. Use a baseQuery instead
Right now you specify a model
method, but it makes more sense to use a base query. This would eliminate the need for the with
method as well.
For example, instead of this:
public function model()
{
return User::class;
}
public function with()
{
return ['address', 'post'];
}
Have something like this:
public function baseQuery()
{
return User::with(['address', 'post'])->withCount('posts');
}
Notice how I've added withCount
to this. Doing it this way makes withCount
possible without having to implement a bunch of other methods. Then we would be able to use posts_count
in the $fields
name
.
2. Make field declaration expressive
Right now, you dump the fields into an array. Sure, this works, but it is confusing and makes future updates a nightmare. I propose you do field declaration similar to Laravel Nova. Then developers know exactly what they can do with fields, and makes it nicer to work with.
For example, instead of this:
public $fields = [
[
'title' => 'ID',
'name' => 'id',
'header_class' => '',
'cell_class' => '',
'sortable' => true,
],
[
'title' => 'City',
'name' => 'address.city',
'header_class' => 'bolded',
'cell_class' => 'bolded bg-green',
'sortable' => true,
'searchable' => true,
],
];
Have something like this:
public function fields()
{
return [
Field::make('ID', 'id')->sortable();
Field::make('City', 'address.city')->headerClass('bolded')->cellClass('bolded bg-green')->sortable()->searchable();
Field::make('Posts Count', 'posts_count')->cellClass('text-muted');
];
}
Things like searchable/sortable can default to false
, and using this method would convert said values to true
.
3. Use a single view for all tables
You can use a single view for ALL tables. This would eliminate the need for devs to scaffold their own view files, which is tedious. Since the package dynamically declares stuff anyways, there shouldn't be a need for this. The package can simply publish 1 view file to the views/vendor folder, and the stub used by livewire-tables:make
can contain this view by default. Then developers can easily make changes to that one view file if they want, and it would apply to all tables.
In this view, just use @foreach
loops to iterate the fields and output the headings, etc..
For example:
@if($hasSearch)
{{-- show search input etc. --}}
@endif
<table class="table-wrapper">
<thead>
<tr>
@foreach($fields as $field)
<th class="header {{ $field['headerClass'] }}" wire:click="$emit('sortColumn', {{ $loop->index() }})">{{ $field['title'] }}</th>
@endforeach
</tr>
</thead>
<tbody>
@foreach ($rowData as $row)
<tr>
@foreach($fields as $field)
<td class="table-cell {{ $field['cellClass'] }}">
@if($field['view'])
{{-- field uses a custom view file for the TD :) --}}
@include($field['view'])
@elseif(strpos($field['name'], '.') !== false)
{{-- explode by period or w/e for relationship logic --}}
...
@else
{{ $row->{$field['name']} }}
@endif
</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
@if($paginate)
{{ $rowData->links() }}
@endif
Notice how I've included a conditional for each TD. If we added a new view()
method to the field delcaration, devs could use their own custom view file for the TD, and it would automatically be passed the $row
var.
For relationships, we can just check if the name
has a period. If it does, explode it into the actual value or w/e. See this: https://stackoverflow.com/questions/33645301/how-do-i-traverse-through-model-relationships-in-laravel-with-dot-syntax
Anyways, these are just a few ideas. Would love to hear your thoughts on these.