diff --git a/CHANGELOG.md b/CHANGELOG.md index d137430cf..23aceebc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to `laravel-livewire-tables` will be documented in this file +## [v3.2.1] - 2023-02-19 +### New Features +- Creation of new WireLink Column + ## [v3.2.0] - 2023-01-04 ### Tweaks - Migration to new Core Traits, and de-duplication of code by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/1623 diff --git a/docs/columns/other-column-types.md b/docs/columns/other-column-types.md index dc80da449..0d15ab564 100644 --- a/docs/columns/other-column-types.md +++ b/docs/columns/other-column-types.md @@ -191,6 +191,41 @@ LinkColumn::make('Action') ]), ``` +## WireLinkColumn Columns + +WireLink columns provide a way to display Wired Links in your table without having to use `format()` or partial views, with or without a Confirmation Message + +WireLinkColumn requires title, and an "action", which must be a valid LiveWire method in the current class, or a global method + +Without a Confirmation Message +```php + WireLinkColumn::make("Delete Item") + ->title(fn($row) => 'Delete Item') + ->action(fn($row) => 'delete("'.$row->id.'")'), +``` + +You may also pass a string to "confirmMessage", which will utilise LiveWire 3's "wire:confirm" approach to display a confirmation modal. + +```php + WireLinkColumn::make("Delete Item") + ->title(fn($row) => 'Delete Item') + ->confirmMessage('Are you sure you want to delete this item?') + ->action(fn($row) => 'delete("'.$row->id.'")') + ->attributes(fn($row) => [ + 'class' => 'btn btn-danger', + ]), +``` + +And you may also pass an array of attributes, which will be applied to the "button" element used within the Column +```php + WireLinkColumn::make("Delete Item") + ->title(fn($row) => 'Delete Item') + ->action(fn($row) => 'delete("'.$row->id.'")') + ->attributes(fn($row) => [ + 'class' => 'btn btn-danger', + ]), +``` + ## Button Group Columns Button group columns let you provide an array of LinkColumns to display in a single cell. diff --git a/resources/views/includes/columns/wirelink.blade.php b/resources/views/includes/columns/wirelink.blade.php new file mode 100644 index 000000000..191ba5f1d --- /dev/null +++ b/resources/views/includes/columns/wirelink.blade.php @@ -0,0 +1,9 @@ + diff --git a/src/Traits/Helpers/TableAttributeHelpers.php b/src/Traits/Helpers/TableAttributeHelpers.php index 25a970628..3da2da12e 100644 --- a/src/Traits/Helpers/TableAttributeHelpers.php +++ b/src/Traits/Helpers/TableAttributeHelpers.php @@ -16,7 +16,7 @@ public function getComponentWrapperAttributes(): array } /** - * @return array + * @return array */ public function getTableWrapperAttributes(): array { @@ -24,7 +24,7 @@ public function getTableWrapperAttributes(): array } /** - * @return array + * @return array */ public function getTableAttributes(): array { @@ -32,7 +32,7 @@ public function getTableAttributes(): array } /** - * @return array + * @return array */ public function getTheadAttributes(): array { @@ -40,7 +40,7 @@ public function getTheadAttributes(): array } /** - * @return array + * @return array */ public function getTbodyAttributes(): array { @@ -48,7 +48,7 @@ public function getTbodyAttributes(): array } /** - * @return array + * @return array */ public function getThAttributes(Column $column): array { @@ -56,7 +56,7 @@ public function getThAttributes(Column $column): array } /** - * @return array + * @return array */ public function getThSortButtonAttributes(Column $column): array { diff --git a/src/Views/Columns/WireLinkColumn.php b/src/Views/Columns/WireLinkColumn.php new file mode 100644 index 000000000..91665f288 --- /dev/null +++ b/src/Views/Columns/WireLinkColumn.php @@ -0,0 +1,45 @@ +label(fn () => null); + } + + public function getContents(Model $row): null|string|\Illuminate\Support\HtmlString|DataTableConfigurationException|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + { + if (! $this->hasTitleCallback()) { + throw new DataTableConfigurationException('You must specify a title callback for a WireLink column.'); + } + + if (! $this->hasActionCallback()) { + throw new DataTableConfigurationException('You must specify an action callback for a WireLink column.'); + } + + return view($this->getView()) + ->withColumn($this) + ->withTitle(app()->call($this->getTitleCallback(), ['row' => $row])) + ->withPath(app()->call($this->getActionCallback(), ['row' => $row])) + ->withAttributes($this->hasAttributesCallback() ? app()->call($this->getAttributesCallback(), ['row' => $row]) : []); + } +} diff --git a/src/Views/Traits/Configuration/WireLinkColumnConfiguration.php b/src/Views/Traits/Configuration/WireLinkColumnConfiguration.php new file mode 100644 index 000000000..b2aa49683 --- /dev/null +++ b/src/Views/Traits/Configuration/WireLinkColumnConfiguration.php @@ -0,0 +1,7 @@ +actionCallback = $callback; + + return $this; + } + + public function getActionCallback(): ?callable + { + return $this->actionCallback; + } + + public function hasActionCallback(): bool + { + return $this->actionCallback !== null; + } +} diff --git a/src/Views/Traits/Core/HasConfirmation.php b/src/Views/Traits/Core/HasConfirmation.php new file mode 100644 index 000000000..9a8597947 --- /dev/null +++ b/src/Views/Traits/Core/HasConfirmation.php @@ -0,0 +1,28 @@ +confirmMessage = $confirmMessage; + + return $this; + } + + public function hasConfirmMessage(): bool + { + return isset($this->confirmMessage); + } + + public function getConfirmMessage(): string + { + return $this->confirmMessage; + } +} diff --git a/src/Views/Traits/Helpers/WireLinkColumnHelpers.php b/src/Views/Traits/Helpers/WireLinkColumnHelpers.php new file mode 100644 index 000000000..d342db23a --- /dev/null +++ b/src/Views/Traits/Helpers/WireLinkColumnHelpers.php @@ -0,0 +1,7 @@ +assertSame('Name', $column->getTitle()); + } + + /** @test */ + public function can_not_infer_field_name_from_title_if_no_from(): void + { + $column = WireLinkColumn::make('My Title'); + + $this->assertNull($column->getField()); + } + + /** @test */ + public function can_not_render_field_if_no_title_callback(): void + { + $this->expectException(DataTableConfigurationException::class); + + WireLinkColumn::make('Name')->getContents(Pet::find(1)); + } + + /** @test */ + public function can_not_render_field_if_no_action_callback(): void + { + $this->expectException(DataTableConfigurationException::class); + + WireLinkColumn::make('Name')->title(fn ($row) => 'Edit')->getContents(Pet::find(1)); + } + + /** @test */ + public function can_render_field_if_title_and_action_callback(): void + { + $column = WireLinkColumn::make('Name')->title(fn ($row) => 'Edit')->action(fn ($row) => 'delete("'.$row->id.'")')->getContents(Pet::find(1)); + + $this->assertNotEmpty($column); + } + + /** @test */ + public function can_render_field_if_confirm_set(): void + { + $column = WireLinkColumn::make('Name')->title(fn ($row) => 'Edit')->action(fn ($row) => 'delete("'.$row->id.'")')->confirmMessage('Test')->getContents(Pet::find(1)); + + $this->assertNotEmpty($column); + } +}