feat: Update ProjectTable with ID column, improved actions buttons, and modern column configuration

This commit is contained in:
2026-05-27 13:38:23 +02:00
parent 2da0eb817e
commit 0f1aa2c38e
+69 -28
View File
@@ -4,6 +4,9 @@ namespace App\Livewire;
use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column;
use Rappasoft\LaravelLivewireTables\Views\Columns\{BooleanColumn, ButtonGroupColumn, LinkColumn, ImageColumn};
use Rappasoft\LaravelLivewireTables\Views\Filters\{DateFilter, MultiSelectFilter, SelectFilter};
use App\Models\Project;
class ProjectTable extends DataTableComponent
@@ -14,53 +17,91 @@ class ProjectTable extends DataTableComponent
{
$this->setPrimaryKey('id')
->setDefaultSort('created_at', 'desc')
->setTableAttributes(['class' => 'table-auto w-full'])
->setThAttributes(['class' => 'px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider'])
->setTdAttributes(['class' => 'px-4 py-2 whitespace-nowrap text-sm text-gray-900']);
->setTableAttributes(['class' => 'table-auto w-full']);
$this->setThAttributes(function(Column $column) {
return ['class' => 'px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider'];
});
$this->setTdAttributes(function(Column $column) {
return ['class' => 'px-4 py-2 whitespace-nowrap text-sm text-gray-900'];
});
}
public function columns(): array
{
return [
Column::make(__('ID'), 'id')
->sortable()
->searchable(),
Column::make(__('Project Name'), 'name')
->sortable()
->searchable(),
Column::make(__('Address'), 'address')
->sortable()
->searchable(),
Column::make(__('Status'), 'status')
->sortable()
->filterable([
'planning' => __('Planning'),
'in_progress' => __('In progress'),
'paused' => __('Paused'),
'completed' => __('Completed'),
])
->label(fn ($value, $row, $column) =>
match ($value) {
'planning' => '<span class="badge badge-primary">'.__('Planning').'</span>',
'in_progress' => '<span class="badge badge-success">'.__('In progress').'</span>',
'paused' => '<span class="badge badge-warning">'.__('Paused').'</span>',
'completed' => '<span class="badge badge-secondary">'.__('Completed').'</span>',
default => $value
}
),
->sortable(),
Column::make(__('Start Date'), 'start_date')
->sortable()
->format(fn ($value, $row, $column) => $value ? $value->format('Y-m-d') : ''),
Column::make(__('Estimated End Date'), 'end_date_estimated')
->sortable()
->format(fn ($value, $row, $column) => $value ? $value->format('Y-m-d') : ''),
Column::make(__('Actions'))
->label(fn ($row) => '<div class="flex space-x-2">
<a href="'.route('projects.edit', $row->id).'" class="btn btn-sm btn-primary">'.__('Edit').'</a>
<form action="'.route('projects.destroy', $row->id).'" method="POST" onsubmit="return confirm(__('Are you sure you want to delete this project?'));">
'.csrf_field().'
<input type="hidden" name="_method" value="DELETE">
<button type="submit" class="btn btn-sm btn-error">'.__('Delete').'</button>
</form>
</div>')
->htmlAttribute(['class' => 'text-right']),
->label(function ($row) {
$confirm = __('Are you sure you want to delete this project?');
return '
<div class="flex space-x-2">
<a href="'.route('projects.edit', $row->id).'" class="btn btn-sm">'.__('Edit').'</a>
<form action="'.route('projects.destroy', $row->id).'" method="POST" onsubmit="return confirm(\''.$confirm.'\');">
'.csrf_field().'
<input type="hidden" name="_method" value="DELETE">
<button type="submit" class="btn btn-sm">'.__('Delete').'</button>
</form>
</div>';
})
->html(),
ButtonGroupColumn::make(__('Actions'))
->attributes(function($row) {
return [
'class' => 'space-x-2',
];
})
->buttons([
LinkColumn::make('Edit')
->title(fn($row) => __('Edit'))
->location(fn($row) => route('projects.edit', $row->id))
->attributes(function($row) {
return [
'target' => '_blank',
'class' => 'text-blue-500 hover:underline',
];
}),
LinkColumn::make('View') // make() has no effect in this case but needs to be set anyway
->title(fn($row) => __('View'))
->location(fn($row) => route('projects.map', $row->id))
->attributes(function($row) {
return [
'class' => 'text-blue-500 hover:underline',
];
}),
]),
];
}
public function filters(): array
{
return [];
}
}