Skip to content

Commit

Permalink
Migrate LivewireComponentColumn methods and add some missing basic te…
Browse files Browse the repository at this point in the history
…sts (#2168)

* Migrate methods and add some missing tests

* Fix styling

* Add Attribute Checks

* Fix styling

---------

Co-authored-by: lrljoe <[email protected]>
  • Loading branch information
lrljoe and lrljoe authored Jan 11, 2025
1 parent 2ecd092 commit 1d83e0e
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 44 deletions.
40 changes: 1 addition & 39 deletions src/Views/Columns/LivewireComponentColumn.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
'<livewire:dynamic-component :component="$component" '.$implodedAttributes.' :wire:key="'.$row->{$row->getKeyName()}.'" />',
[
'component' => $this->livewireComponent,
...$attributes,
],
));

}
protected ?string $livewireComponent;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
57 changes: 56 additions & 1 deletion src/Views/Traits/Helpers/LivewireComponentColumnHelpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
'<livewire:dynamic-component :component="$component" '.$implodedAttributes.' :wire:key="'.$row->{$row->getKeyName()}.'" />',
[
'component' => $this->getLivewireComponent(),
...$attributes,
],
));

}
}
95 changes: 95 additions & 0 deletions tests/Unit/Views/Columns/LivewireComponentColumnTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Tests\Unit\Views\Columns;

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

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

$this->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());
}
}

0 comments on commit 1d83e0e

Please sign in to comment.