Skip to content

Commit

Permalink
Add WireLink Column (#1763)
Browse files Browse the repository at this point in the history
* Add WireLinkColumn

* Add Tests for WireLinkColumn

---------

Co-authored-by: lrljoe <[email protected]>
  • Loading branch information
lrljoe and lrljoe authored Jul 11, 2024
1 parent 799ccfd commit 220d6da
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 0 deletions.
37 changes: 37 additions & 0 deletions docs/column-types/wire_link_column.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: Wire Link Column (beta)
weight: 13
---

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',
]),
```
9 changes: 9 additions & 0 deletions resources/views/includes/columns/wire-link.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<button
{!! count($attributes) ? $column->arrayToAttributes($attributes) : '' !!}
@if($column->hasConfirmMessage())
wire:confirm="{{ $column->getConfirmMessage() }}"
@endif
@if($column->hasActionCallback())
wire:click="{{ $path }}"
@endif
>{{ $title }}</button>
45 changes: 45 additions & 0 deletions src/Views/Columns/WireLinkColumn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Columns;

use Illuminate\Database\Eloquent\Model;
use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
use Rappasoft\LaravelLivewireTables\Views\Column;
use Rappasoft\LaravelLivewireTables\Views\Traits\Configuration\WireLinkColumnConfiguration;
use Rappasoft\LaravelLivewireTables\Views\Traits\Core\{HasActionCallback,HasConfirmation, HasTitleCallback};
use Rappasoft\LaravelLivewireTables\Views\Traits\Helpers\WireLinkColumnHelpers;

class WireLinkColumn extends Column
{
use WireLinkColumnConfiguration,
WireLinkColumnHelpers,
HasActionCallback,
HasTitleCallback,
HasConfirmation;

protected string $view = 'livewire-tables::includes.columns.wire-link';

public function __construct(string $title, ?string $from = null)
{
parent::__construct($title, $from);

$this->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]) : []);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Traits\Configuration;

trait WireLinkColumnConfiguration {}
28 changes: 28 additions & 0 deletions src/Views/Traits/Core/HasActionCallback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Traits\Core;

use Closure;
use Rappasoft\LaravelLivewireTables\Views\{Column,Filter};

trait HasActionCallback
{
protected mixed $actionCallback = null;

public function action(callable $callback): self
{
$this->actionCallback = $callback;

return $this;
}

public function getActionCallback(): ?callable
{
return $this->actionCallback;
}

public function hasActionCallback(): bool
{
return $this->actionCallback !== null;
}
}
28 changes: 28 additions & 0 deletions src/Views/Traits/Core/HasConfirmation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Traits\Core;

use Closure;
use Rappasoft\LaravelLivewireTables\Views\{Column,Filter};

trait HasConfirmation
{
protected ?string $confirmMessage;

public function confirmMessage(string $confirmMessage): self
{
$this->confirmMessage = $confirmMessage;

return $this;
}

public function hasConfirmMessage(): bool
{
return isset($this->confirmMessage);
}

public function getConfirmMessage(): string
{
return $this->confirmMessage;
}
}
5 changes: 5 additions & 0 deletions src/Views/Traits/Helpers/WireLinkColumnHelpers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Traits\Helpers;

trait WireLinkColumnHelpers {}
66 changes: 66 additions & 0 deletions tests/Views/Columns/WireLinkColumnTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Tests\Views\Columns;

use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
use Rappasoft\LaravelLivewireTables\Tests\Models\Pet;
use Rappasoft\LaravelLivewireTables\Tests\TestCase;
use Rappasoft\LaravelLivewireTables\Views\Columns\WireLinkColumn;

class WireLinkColumnTest extends TestCase
{
public function test_can_set_the_column_title(): void
{
$column = WireLinkColumn::make('Name', 'name');

$this->assertSame('Name', $column->getTitle());
}

public function test_can_not_infer_field_name_from_title_if_no_from(): void
{
$column = WireLinkColumn::make('My Title');

$this->assertNull($column->getField());
}

public function test_can_not_render_field_if_no_title_callback(): void
{
$this->expectException(DataTableConfigurationException::class);

WireLinkColumn::make('Name')->getContents(Pet::find(1));
}

public function test_can_not_render_field_if_no_action_callback(): void
{
$this->expectException(DataTableConfigurationException::class);

WireLinkColumn::make('Name')->title(fn ($row) => 'Edit')->getContents(Pet::find(1));
}

public function test_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);
}

public function test_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);
}

public function test_can_add_confirm_message(): void
{
$column = WireLinkColumn::make('Name', 'name');

$this->assertFalse($column->hasConfirmMessage());

$column->confirmMessage('Test');

$this->assertTrue($column->hasConfirmMessage());

$this->assertSame('Test', $column->getConfirmMessage());
}
}

0 comments on commit 220d6da

Please sign in to comment.