diff --git a/src/Views/Columns/LivewireComponentColumn.php b/src/Views/Columns/LivewireComponentColumn.php index ce10d4268..add573962 100644 --- a/src/Views/Columns/LivewireComponentColumn.php +++ b/src/Views/Columns/LivewireComponentColumn.php @@ -16,43 +16,5 @@ class LivewireComponentColumn extends Column use LivewireComponentColumnConfiguration, LivewireComponentColumnHelpers; - protected string $livewireComponent; - - public function component(string $livewireComponent): self - { - $this->livewireComponent = (Str::startsWith($livewireComponent, 'livewire:')) ? substr($livewireComponent, 9) : $livewireComponent; - - return $this; - } - - public function getContents(Model $row): null|string|HtmlString|DataTableConfigurationException|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View - { - if ($this->isLabel()) { - throw new DataTableConfigurationException('You can not use a label column with a component column'); - } - - $attributes = []; - $value = $this->getValue($row); - - if ($this->hasAttributesCallback()) { - $attributes = call_user_func($this->getAttributesCallback(), $value, $row, $this); - - if (! is_array($attributes)) { - throw new DataTableConfigurationException('The return type of callback must be an array'); - } - } - - $implodedAttributes = collect($attributes)->map(function ($value, $key) { - return ':'.$key.'="$'.$key.'"'; - })->implode(' '); - - return new HtmlString(Blade::render( - '', - [ - 'component' => $this->livewireComponent, - ...$attributes, - ], - )); - - } + protected ?string $livewireComponent; } diff --git a/src/Views/Traits/Configuration/LivewireComponentColumnConfiguration.php b/src/Views/Traits/Configuration/LivewireComponentColumnConfiguration.php index 3f5507e13..417e3a81c 100644 --- a/src/Views/Traits/Configuration/LivewireComponentColumnConfiguration.php +++ b/src/Views/Traits/Configuration/LivewireComponentColumnConfiguration.php @@ -2,11 +2,14 @@ namespace Rappasoft\LaravelLivewireTables\Views\Traits\Configuration; +use Illuminate\Support\Str; + trait LivewireComponentColumnConfiguration { - use ComponentColumnConfiguration; - - protected string $componentView; + public function component(string $livewireComponent): self + { + $this->livewireComponent = (Str::startsWith($livewireComponent, 'livewire:')) ? substr($livewireComponent, 9) : $livewireComponent; - protected mixed $slotCallback; + return $this; + } } diff --git a/src/Views/Traits/Helpers/LivewireComponentColumnHelpers.php b/src/Views/Traits/Helpers/LivewireComponentColumnHelpers.php index 5bf8bea90..be047c5dc 100644 --- a/src/Views/Traits/Helpers/LivewireComponentColumnHelpers.php +++ b/src/Views/Traits/Helpers/LivewireComponentColumnHelpers.php @@ -2,7 +2,62 @@ namespace Rappasoft\LaravelLivewireTables\Views\Traits\Helpers; +use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\Blade; +use Illuminate\Support\HtmlString; +use Illuminate\Support\Str; +use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException; + trait LivewireComponentColumnHelpers { - use ComponentColumnHelpers; + /** + * Retrieves the defined Component View + */ + public function getLivewireComponent(): ?string + { + return $this->livewireComponent ?? null; + } + + /** + * Determines whether a Component View has been set + */ + public function hasLivewireComponent(): bool + { + return isset($this->livewireComponent); + } + + public function getContents(Model $row): null|string|HtmlString|DataTableConfigurationException|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + { + if (! $this->hasLivewireComponent()) { + throw new DataTableConfigurationException('You must define a Livewire Component for this column'); + } + + if ($this->isLabel()) { + throw new DataTableConfigurationException('You can not use a label column with a Livewire Component column'); + } + + $attributes = []; + $value = $this->getValue($row); + + if ($this->hasAttributesCallback()) { + $attributes = call_user_func($this->getAttributesCallback(), $value, $row, $this); + + if (! is_array($attributes)) { + throw new DataTableConfigurationException('The return type of callback must be an array'); + } + } + + $implodedAttributes = collect($attributes)->map(function ($value, $key) { + return ':'.$key.'="$'.$key.'"'; + })->implode(' '); + + return new HtmlString(Blade::render( + '', + [ + 'component' => $this->getLivewireComponent(), + ...$attributes, + ], + )); + + } } diff --git a/tests/Unit/Views/Columns/LivewireComponentColumnTest.php b/tests/Unit/Views/Columns/LivewireComponentColumnTest.php new file mode 100644 index 000000000..eab5d9972 --- /dev/null +++ b/tests/Unit/Views/Columns/LivewireComponentColumnTest.php @@ -0,0 +1,95 @@ +assertSame('Name', $column->getTitle()); + } + + public function test_can_not_be_a_label_without_component(): void + { + $this->expectException(DataTableConfigurationException::class); + + $column = LivewireComponentColumn::make('Total Users')->label(fn () => 'My Label')->getContents(Pet::find(1)); + + } + + public function test_can_not_be_a_label_with_component(): void + { + $this->expectException(DataTableConfigurationException::class); + + $column = LivewireComponentColumn::make('Total Users')->component('test-component')->label(fn () => 'My Label')->getContents(Pet::find(1)); + + } + + public function test_can_add_livewire_component(): void + { + $column = LivewireComponentColumn::make('Name', 'name'); + + $this->assertFalse($column->hasLivewireComponent()); + $column->component('test-component'); + $this->assertTrue($column->hasLivewireComponent()); + } + + public function test_can_get_livewire_component(): void + { + $column = LivewireComponentColumn::make('Name', 'name'); + + $this->assertFalse($column->hasLivewireComponent()); + $this->assertNull($column->getLivewireComponent()); + + $column->component('test-component'); + + $this->assertTrue($column->hasLivewireComponent()); + $this->assertSame('test-component', $column->getLivewireComponent()); + } + + public function test_can_not_avoid_defining_livewire_component(): void + { + $this->expectException(DataTableConfigurationException::class); + + $contents = LivewireComponentColumn::make('Name')->getContents(Pet::find(1)); + + } + + public function test_attributes_should_return_array(): void + { + $this->expectException(DataTableConfigurationException::class); + + $column = LivewireComponentColumn::make('Name')->component('test-component')->attributes(fn ($value, $row, Column $column) => 'test'); + + $column->getContents(Pet::find(1)); + } + + public function test_can_check_attribute_callback_presence(): void + { + $column = LivewireComponentColumn::make('Name', 'name')->component('test-component'); + $this->assertFalse($column->hasAttributesCallback()); + } + + public function test_can_set_attribute_callback(): void + { + $column = LivewireComponentColumn::make('Name', 'name')->component('test-component'); + $this->assertFalse($column->hasAttributesCallback()); + + $column->attributes(function ($row) { + return [ + 'class' => '!rounded-lg self-center', + 'default' => true, + ]; + }); + + $this->assertTrue($column->hasAttributesCallback()); + } +}