Skip to content

Commit

Permalink
Merge branch 'component-column' of https://github.com/CristhoferMF/la…
Browse files Browse the repository at this point in the history
…ravel-livewire-tables into CristhoferMF-component-column
  • Loading branch information
rappasoft committed Dec 21, 2022
2 parents e6069cd + 19493d4 commit 9a65ba5
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 0 deletions.
60 changes: 60 additions & 0 deletions src/Views/Columns/ComponentColumn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Columns;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\HtmlString;
use Illuminate\View\ComponentAttributeBag;
use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
use Rappasoft\LaravelLivewireTables\Views\Column;
use Rappasoft\LaravelLivewireTables\Views\Traits\Configuration\ComponentColumnConfiguration;
use Rappasoft\LaravelLivewireTables\Views\Traits\Helpers\ComponentColumnHelpers;

class ComponentColumn extends Column
{
use ComponentColumnHelpers,
ComponentColumnConfiguration;

protected string $componentView;
protected $attributesCallback;
protected $slotCallback;

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

public function getContents(Model $row)
{
if ($this->isLabel()) {
throw new DataTableConfigurationException('You can not use a label column with a component column');
}

if (false === $this->hasComponentView()) {
throw new DataTableConfigurationException('You must specify a component view for a component column');
}

$attributes = [];
$value = $this->getValue($row);
$slotContent = $value;

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');
}
}
if ($this->hasSlotCallback()) {
$slotContent = call_user_func($this->getSlotCallback(), $value, $row, $this);
if (is_string($slotContent)) {
$slotContent = new HtmlString($slotContent);
}
}

return view($this->getComponentView(), [
'attributes' => new ComponentAttributeBag($attributes),
'slot' => $slotContent,
]);
}
}
24 changes: 24 additions & 0 deletions src/Views/Traits/Configuration/ComponentColumnConfiguration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Traits\Configuration;

trait ComponentColumnConfiguration
{
public function component(string $component): self
{
$this->componentView = 'components.' . $component;
return $this;
}

public function attributes(callable $callback): self
{
$this->attributesCallback = $callback;
return $this;
}

public function slot(callable $callback): self
{
$this->slotCallback = $callback;
return $this;
}
}
39 changes: 39 additions & 0 deletions src/Views/Traits/Helpers/ComponentColumnHelpers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Traits\Helpers;

trait ComponentColumnHelpers
{
public function getAttributesCallback()
{
return $this->attributesCallback;
}

public function hasAttributesCallback(): bool
{
return $this->attributesCallback !== null;
}

public function getSlotCallback()
{
return $this->slotCallback;
}

public function hasSlotCallback(): bool
{
return $this->slotCallback !== null;
}

/**
* Get the value of componentView
*/
public function getComponentView()
{
return $this->componentView;
}

public function hasComponentView(): bool
{
return isset($this->componentView);
}
}
36 changes: 36 additions & 0 deletions tests/Views/ComponentColumnTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Tests\Views;

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

class ComponentColumnTest extends TestCase
{
/** @test */
public function component_column_attributes_callback_return_can_not_be_an_string()
{
$this->expectException(DataTableConfigurationException::class);
ComponentColumn::make('Name')
->component('alert')
->attributes(fn () => 'string')->getContents(Pet::find(1));
}

/** @test */
public function component_column_component_has_to_be_an_string()
{
$column = ComponentColumn::make('Name')
->component('alert');
$this->assertEquals('components.alert', $column->getComponentView());
}

/** @test */
public function component_column_component_view_has_to_be_set()
{
$this->expectException(DataTableConfigurationException::class);
ComponentColumn::make('Name')
->getContents(Pet::find(1));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Tests\Views\Traits\Configuration;

use Closure;
use Rappasoft\LaravelLivewireTables\Tests\TestCase;
use Rappasoft\LaravelLivewireTables\Views\Columns\ComponentColumn;

class ComponentColumnConfigurationTest extends TestCase
{
/** @test */
public function component_column_can_set_slot_callback(): void
{
$column = ComponentColumn::make('Name');

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

$column->slot(fn ($value) => $value);

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

$this->assertTrue($column->getSlotCallback() instanceof Closure);
}

/** @test */
public function component_column_can_set_attributes_callback(): void
{
$column = ComponentColumn::make('Name');

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

$column->attributes(fn ($value) => $value);

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

$this->assertTrue($column->getAttributesCallback() instanceof Closure);
}
}

0 comments on commit 9a65ba5

Please sign in to comment.