diff --git a/CHANGELOG.md b/CHANGELOG.md index 1193fa01d..27037e489 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to `laravel-livewire-tables` will be documented in this file +## [Unreleased] - 3.x setTrAttributes +- Adding capabilities & tests for setTrAttributes + ## [Unreleased] - 3.x Fixes for reordering striping - Force calculation of even/odd only once in reorder mode - Call internal method for reordering, and pass to configured method to process diff --git a/resources/views/components/table/tr.blade.php b/resources/views/components/table/tr.blade.php index 92facb790..92d1326ea 100644 --- a/resources/views/components/table/tr.blade.php +++ b/resources/views/components/table/tr.blade.php @@ -16,14 +16,16 @@ :draggable="currentlyReorderingStatus" wire:key="{{ $tableName }}-tablerow-tr-{{ $row->{$this->getPrimaryKey()} }}" loopType="{{ ($rowIndex % 2 === 0) ? 'even' : 'odd' }}" + {{ + $attributes->merge($customAttributes) + ->class(['bg-white dark:bg-gray-700 dark:text-white rappasoft-striped-row' => ($component->isTailwind() && ($customAttributes['default'] ?? true) && $rowIndex % 2 === 0)]) + ->class(['bg-gray-50 dark:bg-gray-800 dark:text-white rappasoft-striped-row' => ($component->isTailwind() && ($customAttributes['default'] ?? true) && $rowIndex % 2 !== 0)]) + ->class(['cursor-pointer' => ($component->isTailwind() && $component->hasTableRowUrl() && ($customAttributes['default'] ?? true))]) + ->class(['bg-light rappasoft-striped-row' => ($component->isBootstrap() && $rowIndex % 2 === 0 && ($customAttributes['default'] ?? true))]) + ->class(['bg-white rappasoft-striped-row' => ($component->isBootstrap() && $rowIndex % 2 !== 0 && ($customAttributes['default'] ?? true))]) + ->except(['default']) + }} - @class([ - 'bg-white dark:bg-gray-700 dark:text-white rappasoft-striped-row' => ($component->isTailwind() && ($customAttributes['default'] ?? true) && $rowIndex % 2 === 0), - 'bg-gray-50 dark:bg-gray-800 dark:text-white rappasoft-striped-row' => ($component->isTailwind() && ($customAttributes['default'] ?? true) && $rowIndex % 2 !== 0), - 'cursor-pointer' => ($component->isTailwind() && $component->hasTableRowUrl()), - 'bg-light rappasoft-striped-row' => ($component->isBootstrap() && $rowIndex % 2 === 0), - 'bg-white rappasoft-striped-row' => ($component->isBootstrap() && $rowIndex % 2 !== 0), - ]) > {{ $slot }} diff --git a/tests/Http/Livewire/PetsTableAttributes.php b/tests/Http/Livewire/PetsTableAttributes.php new file mode 100644 index 000000000..53f79646f --- /dev/null +++ b/tests/Http/Livewire/PetsTableAttributes.php @@ -0,0 +1,171 @@ +setPrimaryKey('id') + ->setTrAttributes(function ($row, $index) { + if ($index === 0) { + return [ + 'testTrAttribute' => 'testTrAttributeValueForTestSuiteIndex0', + 'default' => false, + ]; + } + if ($index === 1) { + return [ + 'testTrAttribute' => 'testTrAttributeValueForTestSuiteIndex1', + 'default' => false, + ]; + } + if ($index === 500) { + return [ + 'testTrAttribute' => 'testTrAttributeValueForTestSuiteNotSeen', + 'default' => false, + ]; + } + + return []; + }); + + } + + public function columns(): array + { + return [ + Column::make('ID', 'id') + ->sortable() + ->setSortingPillTitle('Key') + ->setSortingPillDirections('0-9', '9-0'), + Column::make('Sort') + ->sortable() + ->excludeFromColumnSelect(), + Column::make('Name') + ->sortable() + ->secondaryHeader($this->getFilterByKey('pet_name_filter')) + ->footerFilter('pet_name_filter') + ->searchable(), + + Column::make('Age'), + + Column::make('Breed', 'breed.name') + ->secondaryHeaderFilter('breed') + ->footer($this->getFilterByKey('breed')) + ->sortable( + fn (Builder $query, string $direction) => $query->orderBy('pets.id', $direction) + ) + ->searchable( + fn (Builder $query, $searchTerm) => $query->orWhere('breed.name', $searchTerm) + ), + + Column::make('Other') + ->label(function ($row, Column $column) { + return 'Other'; + }) + ->footer(function ($rows) { + return 'Count: '.$rows->count(); + }), + + LinkColumn::make('Link') + ->title(fn ($row) => 'Edit') + ->location(fn ($row) => 'http://www.google.com') + ->attributes(fn ($row) => [ + 'class' => 'rounded-full', + 'alt' => $row->name.' Avatar', + ]), + ImageColumn::make('RowImg') + ->location(fn ($row) => 'test'.$row->id) + ->attributes(fn ($row) => [ + 'class' => 'rounded-full', + 'alt' => $row->name.' Avatar', + ]), + Column::make('Last Visit', 'last_visit') + ->sortable() + ->deselected(), + ]; + } + + public function filters(): array + { + return [ + MultiSelectFilter::make('Breed') + ->options( + Breed::query() + ->orderBy('name') + ->get() + ->keyBy('id') + ->map(fn ($breed) => $breed->name) + ->toArray() + ) + ->filter(function (Builder $builder, array $values) { + return $builder->whereIn('breed_id', $values); + }), + MultiSelectDropdownFilter::make('Species') + ->options( + Species::query() + ->orderBy('name') + ->get() + ->keyBy('id') + ->map(fn ($species) => $species->name) + ->toArray() + ) + ->filter(function (Builder $builder, array $values) { + return $builder->whereIn('species_id', $values); + }), + NumberFilter::make('Breed ID', 'breed_id_filter') + ->filter(function (Builder $builder, string $value) { + return $builder->where('breed_id', '=', $value); + }), + + TextFilter::make('Pet Name', 'pet_name_filter') + ->filter(function (Builder $builder, string $value) { + return $builder->where('pets.name', '=', $value); + }), + + DateFilter::make('Last Visit After Date', 'last_visit_date_filter') + ->filter(function (Builder $builder, string $value) { + return $builder->whereDate('pets.last_visit', '=>', $value); + }), + + DateTimeFilter::make('Last Visit Before DateTime', 'last_visit_datetime_filter') + ->filter(function (Builder $builder, string $value) { + return $builder->whereDate('pets.last_visit', '<=', $value); + }), + + SelectFilter::make('Breed SelectFilter', 'breed_select_filter') + ->options( + Breed::query() + ->orderBy('name') + ->get() + ->keyBy('id') + ->map(fn ($breed) => $breed->name) + ->toArray() + ) + ->filter(function (Builder $builder, string $value) { + return $builder->where('breed_id', $value); + }) + ->setCustomFilterLabel('livewire-tables::tests.testFilterLabel') + ->setFilterPillBlade('livewire-tables::tests.testFilterPills'), + ]; + } +} diff --git a/tests/Traits/Visuals/ComponentVisualsTest.php b/tests/Traits/Visuals/ComponentVisualsTest.php index 260b66669..cc7869dca 100644 --- a/tests/Traits/Visuals/ComponentVisualsTest.php +++ b/tests/Traits/Visuals/ComponentVisualsTest.php @@ -9,6 +9,7 @@ use Rappasoft\LaravelLivewireTables\Tests\Http\Livewire\FailingTables\NoBuildMethodTable; use Rappasoft\LaravelLivewireTables\Tests\Http\Livewire\FailingTables\NoPrimaryKeyTable; use Rappasoft\LaravelLivewireTables\Tests\Http\Livewire\PetsTable; +use Rappasoft\LaravelLivewireTables\Tests\Http\Livewire\PetsTableAttributes; use Rappasoft\LaravelLivewireTables\Tests\TestCase; class ComponentVisualsTest extends TestCase @@ -94,4 +95,20 @@ public function fails_when_table_has_no_model_or_builder(): void $this->fail('Did Not Throw Error - Missing Model/Builder'); } } + + /** @test */ + public function can_see_valid_tr_attributes_html(): void + { + Livewire::test(PetsTableAttributes::class) + ->assertSeeHtml('testTrAttribute="testTrAttributeValueForTestSuiteIndex0"') + ->assertSeeHtml('testTrAttribute="testTrAttributeValueForTestSuiteIndex1"'); + } + + /** @test */ + public function cannot_see_invalid_tr_attributes_html(): void + { + Livewire::test(PetsTableAttributes::class) + ->assertSeeHtml('testTrAttribute="testTrAttributeValueForTestSuiteIndex0"') + ->assertDontSeeHtml('testTrAttribute="testTrAttributeValueForTestSuiteNotSeen"'); + } }