Skip to content

Commit e3cc1e5

Browse files
webarddanharrin
andauthored
Feature: hide actions column when no actions are available for any row (#20133)
* hide actions column when no columns * reduce memory usage by not storing visible actions for more than one row --------- Co-authored-by: Dan Harrin <git@danharrin.com>
1 parent 8212b2b commit e3cc1e5

3 files changed

Lines changed: 154 additions & 56 deletions

File tree

packages/tables/resources/views/index.blade.php

Lines changed: 62 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,47 @@
146146
$defaultSortOptionLabel = $getDefaultSortOptionLabel();
147147
$sortDirection = $getSortDirection();
148148
149-
if (count($defaultRecordActions) && (! $isReordering)) {
149+
$reduceVisibleRecordActions = function ($record) use ($defaultRecordActions): array {
150+
return array_reduce(
151+
$defaultRecordActions,
152+
function (array $carry, $action) use ($record): array {
153+
$action = $action->getClone();
154+
155+
if (! $action instanceof \Filament\Actions\BulkAction) {
156+
$action->record($record);
157+
}
158+
159+
if ($action->isHidden()) {
160+
return $carry;
161+
}
162+
163+
$carry[] = $action;
164+
165+
return $carry;
166+
},
167+
initial: [],
168+
);
169+
};
170+
171+
$recordActionsByRecordKey = [];
172+
$hasRecordActionsForAnyRecord = false;
173+
174+
// Determine whether the record actions column should be rendered by scanning
175+
// records until one exposes a visible action. Every record that gets checked
176+
// is cached so the row loop below never re-evaluates its visibility.
177+
if (($records !== null) && (! $isReordering)) {
178+
foreach ($records as $record) {
179+
$recordActionsByRecordKey[$getRecordKey($record)] = $currentRecordActions = $reduceVisibleRecordActions($record);
180+
181+
if ($currentRecordActions !== []) {
182+
$hasRecordActionsForAnyRecord = true;
183+
184+
break;
185+
}
186+
}
187+
}
188+
189+
if ($hasRecordActionsForAnyRecord && (! $isReordering)) {
150190
$columnsCount++;
151191
}
152192
@@ -1020,25 +1060,8 @@ class="fi-ta-sorting-settings"
10201060
$collapsibleColumnsLayout?->record($record)->recordKey($recordKey);
10211061
$hasCollapsibleColumnsLayout = (bool) $collapsibleColumnsLayout?->isVisible();
10221062
1023-
$recordActions = array_reduce(
1024-
$defaultRecordActions,
1025-
function (array $carry, $action) use ($record): array {
1026-
$action = $action->getClone();
1027-
1028-
if (! $action instanceof \Filament\Actions\BulkAction) {
1029-
$action->record($record);
1030-
}
1031-
1032-
if ($action->isHidden()) {
1033-
return $carry;
1034-
}
1035-
1036-
$carry[] = $action;
1037-
1038-
return $carry;
1039-
},
1040-
initial: [],
1041-
);
1063+
$recordActions = $recordActionsByRecordKey[$recordKey]
1064+
?? ($hasRecordActionsForAnyRecord ? $reduceVisibleRecordActions($record) : []);
10421065
@endphp
10431066

10441067
@if ((string) $recordGroupTitle !== (string) $previousRecordGroupTitle)
@@ -1526,7 +1549,7 @@ class="fi-ta-page-checkbox fi-checkbox-input"
15261549
@if ($isReordering)
15271550
<th></th>
15281551
@else
1529-
@if (count($defaultRecordActions) && in_array($recordActionsPosition, [RecordActionsPosition::BeforeCells, RecordActionsPosition::BeforeColumns]))
1552+
@if ($hasRecordActionsForAnyRecord && in_array($recordActionsPosition, [RecordActionsPosition::BeforeCells, RecordActionsPosition::BeforeColumns]))
15301553
<th></th>
15311554
@endif
15321555

@@ -1566,7 +1589,7 @@ class="fi-ta-page-checkbox fi-checkbox-input"
15661589
@endforeach
15671590

15681591
@if ((! $isReordering) && count($records))
1569-
@if (count($defaultRecordActions) && in_array($recordActionsPosition, [RecordActionsPosition::AfterColumns, RecordActionsPosition::AfterCells]))
1592+
@if ($hasRecordActionsForAnyRecord && in_array($recordActionsPosition, [RecordActionsPosition::AfterColumns, RecordActionsPosition::AfterCells]))
15701593
<th></th>
15711594
@endif
15721595

@@ -1582,7 +1605,7 @@ class="fi-ta-page-checkbox fi-checkbox-input"
15821605
@if ($isReordering)
15831606
<th></th>
15841607
@else
1585-
@if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::BeforeCells)
1608+
@if ($hasRecordActionsForAnyRecord && $recordActionsPosition === RecordActionsPosition::BeforeCells)
15861609
@if ($recordActionsColumnLabel)
15871610
<th
15881611
class="fi-ta-header-cell"
@@ -1638,7 +1661,7 @@ class="fi-ta-page-checkbox fi-checkbox-input"
16381661
</th>
16391662
@endif
16401663

1641-
@if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::BeforeColumns)
1664+
@if ($hasRecordActionsForAnyRecord && $recordActionsPosition === RecordActionsPosition::BeforeColumns)
16421665
@if ($recordActionsColumnLabel)
16431666
<th
16441667
class="fi-ta-header-cell"
@@ -1764,7 +1787,7 @@ class="fi-ta-header-cell-tooltip"
17641787
@endforeach
17651788

17661789
@if ((! $isReordering) && count($records))
1767-
@if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::AfterColumns)
1790+
@if ($hasRecordActionsForAnyRecord && $recordActionsPosition === RecordActionsPosition::AfterColumns)
17681791
@if ($recordActionsColumnLabel)
17691792
<th
17701793
class="fi-ta-header-cell fi-align-end"
@@ -1820,7 +1843,7 @@ class="fi-ta-page-checkbox fi-checkbox-input"
18201843
</th>
18211844
@endif
18221845

1823-
@if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::AfterCells)
1846+
@if ($hasRecordActionsForAnyRecord && $recordActionsPosition === RecordActionsPosition::AfterCells)
18241847
@if ($recordActionsColumnLabel)
18251848
<th
18261849
class="fi-ta-header-cell fi-align-end"
@@ -1859,7 +1882,7 @@ class="fi-ta-row fi-ta-row-not-reorderable"
18591882
@if ($isReordering)
18601883
<td></td>
18611884
@else
1862-
@if (count($defaultRecordActions) && in_array($recordActionsPosition, [RecordActionsPosition::BeforeCells, RecordActionsPosition::BeforeColumns]))
1885+
@if ($hasRecordActionsForAnyRecord && in_array($recordActionsPosition, [RecordActionsPosition::BeforeCells, RecordActionsPosition::BeforeColumns]))
18631886
<td></td>
18641887
@endif
18651888

@@ -1892,7 +1915,7 @@ class="fi-ta-row fi-ta-row-not-reorderable"
18921915
@endforeach
18931916

18941917
@if ((! $isReordering) && count($records))
1895-
@if (count($defaultRecordActions) && in_array($recordActionsPosition, [RecordActionsPosition::AfterColumns, RecordActionsPosition::AfterCells]))
1918+
@if ($hasRecordActionsForAnyRecord && in_array($recordActionsPosition, [RecordActionsPosition::AfterColumns, RecordActionsPosition::AfterCells]))
18961919
<td></td>
18971920
@endif
18981921

@@ -1921,25 +1944,8 @@ class="fi-ta-row fi-ta-row-not-reorderable"
19211944
$recordGroupTitle = $group?->getTitle($record, $recordGroupKey);
19221945
$recordIsSelectable = $isSelectionEnabled && $isRecordSelectable($record);
19231946
1924-
$recordActions = array_reduce(
1925-
$defaultRecordActions,
1926-
function (array $carry, $action) use ($record): array {
1927-
$action = $action->getClone();
1928-
1929-
if (! $action instanceof \Filament\Actions\BulkAction) {
1930-
$action->record($record);
1931-
}
1932-
1933-
if ($action->isHidden()) {
1934-
return $carry;
1935-
}
1936-
1937-
$carry[] = $action;
1938-
1939-
return $carry;
1940-
},
1941-
initial: [],
1942-
);
1947+
$recordActions = $recordActionsByRecordKey[$recordKey]
1948+
?? ($hasRecordActionsForAnyRecord ? $reduceVisibleRecordActions($record) : []);
19431949
@endphp
19441950

19451951
@if ((string) $recordGroupTitle !== (string) $previousRecordGroupTitle)
@@ -1950,7 +1956,7 @@ function (array $carry, $action) use ($record): array {
19501956
@endphp
19511957

19521958
<x-filament-tables::summary.row
1953-
:actions="count($defaultRecordActions)"
1959+
:actions="$hasRecordActionsForAnyRecord"
19541960
:actions-position="$recordActionsPosition"
19551961
:columns="$columns"
19561962
:group-column="$groupColumn"
@@ -1976,7 +1982,7 @@ class="fi-ta-row fi-ta-group-header-row"
19761982
19771983
if (
19781984
($recordCheckboxPosition === RecordCheckboxPosition::BeforeCells) &&
1979-
count($defaultRecordActions) &&
1985+
$hasRecordActionsForAnyRecord &&
19801986
($recordActionsPosition === RecordActionsPosition::BeforeCells)
19811987
) {
19821988
$groupHeaderColspan--;
@@ -1985,7 +1991,7 @@ class="fi-ta-row fi-ta-group-header-row"
19851991
@endphp
19861992

19871993
@if ($isSelectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::BeforeCells)
1988-
@if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::BeforeCells)
1994+
@if ($hasRecordActionsForAnyRecord && $recordActionsPosition === RecordActionsPosition::BeforeCells)
19891995
<td></td>
19901996
@endif
19911997

@@ -2155,7 +2161,7 @@ class="fi-ta-reorder-handle fi-icon-btn"
21552161
</td>
21562162
@endif
21572163

2158-
@if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::BeforeCells && (! $isReordering))
2164+
@if ($hasRecordActionsForAnyRecord && $recordActionsPosition === RecordActionsPosition::BeforeCells && (! $isReordering))
21592165
<td class="fi-ta-cell">
21602166
<div
21612167
@class([
@@ -2201,7 +2207,7 @@ class="fi-ta-record-checkbox fi-checkbox-input"
22012207
</td>
22022208
@endif
22032209

2204-
@if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::BeforeColumns && (! $isReordering))
2210+
@if ($hasRecordActionsForAnyRecord && $recordActionsPosition === RecordActionsPosition::BeforeColumns && (! $isReordering))
22052211
<td class="fi-ta-cell">
22062212
<div
22072213
@class([
@@ -2282,7 +2288,7 @@ class="fi-ta-record-checkbox fi-checkbox-input"
22822288
</td>
22832289
@endforeach
22842290

2285-
@if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::AfterColumns && (! $isReordering))
2291+
@if ($hasRecordActionsForAnyRecord && $recordActionsPosition === RecordActionsPosition::AfterColumns && (! $isReordering))
22862292
<td class="fi-ta-cell">
22872293
<div
22882294
@class([
@@ -2328,7 +2334,7 @@ class="fi-ta-record-checkbox fi-checkbox-input"
23282334
</td>
23292335
@endif
23302336

2331-
@if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::AfterCells && (! $isReordering))
2337+
@if ($hasRecordActionsForAnyRecord && $recordActionsPosition === RecordActionsPosition::AfterCells && (! $isReordering))
23322338
<td class="fi-ta-cell">
23332339
<div
23342340
@class([
@@ -2366,7 +2372,7 @@ class="fi-ta-record-checkbox fi-checkbox-input"
23662372
@endphp
23672373

23682374
<x-filament-tables::summary.row
2369-
:actions="count($defaultRecordActions)"
2375+
:actions="$hasRecordActionsForAnyRecord"
23702376
:actions-position="$recordActionsPosition"
23712377
:columns="$columns"
23722378
:group-column="$groupColumn"
@@ -2385,7 +2391,7 @@ class="fi-ta-record-checkbox fi-checkbox-input"
23852391
@endphp
23862392

23872393
<x-filament-tables::summary
2388-
:actions="count($defaultRecordActions)"
2394+
:actions="$hasRecordActionsForAnyRecord"
23892395
:actions-position="$recordActionsPosition"
23902396
:all-table-summary="$hasAllTableSummary"
23912397
:columns="$columns"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace Filament\Tests\Fixtures\Livewire;
4+
5+
use Filament\Actions\Action;
6+
use Filament\Actions\Concerns\InteractsWithActions;
7+
use Filament\Actions\Contracts\HasActions;
8+
use Filament\Schemas\Concerns\InteractsWithSchemas;
9+
use Filament\Schemas\Contracts\HasSchemas;
10+
use Filament\Tables;
11+
use Filament\Tables\Table;
12+
use Filament\Tests\Fixtures\Models\Post;
13+
use Illuminate\Contracts\View\View;
14+
use Livewire\Component;
15+
16+
class PostsTableWithToggleableRecordActions extends Component implements HasActions, HasSchemas, Tables\Contracts\HasTable
17+
{
18+
use InteractsWithActions;
19+
use InteractsWithSchemas;
20+
use Tables\Concerns\InteractsWithTable;
21+
22+
public bool $hasVisibleRecordActions = true;
23+
24+
public ?int $visibleRecordActionForKey = null;
25+
26+
public function mount(bool $hasVisibleRecordActions = true, ?int $visibleRecordActionForKey = null): void
27+
{
28+
$this->hasVisibleRecordActions = $hasVisibleRecordActions;
29+
$this->visibleRecordActionForKey = $visibleRecordActionForKey;
30+
}
31+
32+
public function table(Table $table): Table
33+
{
34+
return $table
35+
->query(Post::query())
36+
->columns([
37+
Tables\Columns\TextColumn::make('title'),
38+
])
39+
->recordActions([
40+
Action::make('test')
41+
->visible(fn (Post $record): bool => $this->hasVisibleRecordActions
42+
&& (($this->visibleRecordActionForKey === null) || ($record->getKey() === $this->visibleRecordActionForKey))),
43+
]);
44+
}
45+
46+
public function render(): View
47+
{
48+
return view('livewire.table');
49+
}
50+
}

0 commit comments

Comments
 (0)