@php use Filament\Support\Enums\Alignment; use Filament\Support\Enums\VerticalAlignment; use Filament\Support\Enums\Width; use Filament\Support\Facades\FilamentView; use Filament\Tables\Actions\HeaderActionsPosition; use Filament\Tables\Columns\Column; use Filament\Tables\Columns\ColumnGroup; use Filament\Tables\Enums\ColumnManagerLayout; use Filament\Tables\Enums\ColumnManagerResetActionPosition; use Filament\Tables\Enums\FiltersLayout; use Filament\Tables\Enums\FiltersResetActionPosition; use Filament\Tables\Enums\RecordActionsPosition; use Filament\Tables\Enums\RecordCheckboxPosition; use Filament\Tables\View\TablesRenderHook; use Illuminate\Support\Str; use Illuminate\View\ComponentAttributeBag; $defaultRecordActions = $getRecordActions(); $flatRecordActionsCount = count($getFlatRecordActions()); $recordActionsAlignment = $getRecordActionsAlignment(); $recordActionsPosition = $getRecordActionsPosition(); $recordActionsColumnLabel = $getRecordActionsColumnLabel(); if (!$recordActionsAlignment instanceof Alignment) { $recordActionsAlignment = filled($recordActionsAlignment) ? Alignment::tryFrom($recordActionsAlignment) ?? $recordActionsAlignment : null; } $activeFiltersCount = $getActiveFiltersCount(); $isSelectionDisabled = $isSelectionDisabled(); $maxSelectableRecords = $getMaxSelectableRecords(); $columns = $getVisibleColumns(); $collapsibleColumnsLayout = $getCollapsibleColumnsLayout(); $columnsLayout = $getColumnsLayout(); $content = $getContent(); $contentGrid = $getContentGrid(); $contentFooter = $getContentFooter(); $filterIndicators = $getFilterIndicators(); $filtersApplyAction = $getFiltersApplyAction(); $filtersForm = $getFiltersForm(); $filtersFormWidth = $getFiltersFormWidth(); $filtersResetActionPosition = $getFiltersResetActionPosition(); $columnManagerResetActionPosition = $getColumnManagerResetActionPosition(); $hasColumnGroups = $hasColumnGroups(); $hasColumnsLayout = $hasColumnsLayout(); $hasPageSummary = $hasPageSummary(); $hasAllTableSummary = $hasAllTableSummary(); $hasSummary = $hasSummary($this->getAllTableSummaryQuery()); $hasTopLevelSummary = $hasSummary && ($hasPageSummary || $hasAllTableSummary); $header = $getHeader(); $headerActions = array_filter( $getHeaderActions(), fn(\Filament\Actions\Action|\Filament\Actions\ActionGroup $action): bool => $action->isVisible(), ); $headerActionsPosition = $getHeaderActionsPosition(); $heading = $getHeading(); $group = $getGrouping(); $toolbarActions = array_filter( $getToolbarActions(), fn(\Filament\Actions\Action|\Filament\Actions\ActionGroup $action): bool => $action->isVisible(), ); $hasNonBulkToolbarAction = false; foreach ($toolbarActions as $toolbarAction) { if ($toolbarAction instanceof \Filament\Actions\BulkActionGroup) { continue; } if ($toolbarAction instanceof \Filament\Actions\ActionGroup) { if ($toolbarAction->hasNonBulkAction()) { $hasNonBulkToolbarAction = true; break; } continue; } if (!$toolbarAction->isBulk()) { $hasNonBulkToolbarAction = true; break; } } $groups = $getGroups(); $description = $getDescription(); $isGroupsOnly = $isGroupsOnly() && $group; $isReorderable = $isReorderable(); $isReordering = $isReordering(); $areGroupingSettingsVisible = !$isReordering && count($groups) && !$areGroupingSettingsHidden(); $isGroupingDirectionSettingHidden = $isGroupingDirectionSettingHidden(); $areGroupsCollapsedByDefault = $areGroupsCollapsedByDefault(); $areGroupingSettingsInDropdownOnDesktop = $areGroupingSettingsInDropdownOnDesktop(); $isColumnSearchVisible = $isSearchableByColumn(); $isGlobalSearchVisible = $isSearchable(); $isSearchOnBlur = $isSearchOnBlur(); $isSelectionEnabled = $isSelectionEnabled() && !$isGroupsOnly; $selectsCurrentPageOnly = $selectsCurrentPageOnly(); $selectsGroupsOnly = $selectsGroupsOnly(); $recordCheckboxPosition = $getRecordCheckboxPosition(); $isStriped = $isStriped(); $isStackedOnMobile = $isStackedOnMobile(); $isLoaded = $isLoaded(); $hasFilters = $isFilterable(); $filtersLayout = $getFiltersLayout(); $filtersTriggerAction = $getFiltersTriggerAction(); $hasFiltersDialog = $hasFilters && in_array($filtersLayout, [FiltersLayout::Dropdown, FiltersLayout::Modal]); $hasFiltersAboveContent = $hasFilters && in_array($filtersLayout, [FiltersLayout::AboveContent, FiltersLayout::AboveContentCollapsible]); $hasFiltersBelowContent = $hasFilters && $filtersLayout === FiltersLayout::BelowContent; $hasFiltersBeforeContent = $hasFilters && in_array($filtersLayout, [FiltersLayout::BeforeContent, FiltersLayout::BeforeContentCollapsible]); $hasFiltersAfterContent = $hasFilters && in_array($filtersLayout, [FiltersLayout::AfterContent, FiltersLayout::AfterContentCollapsible]); $hasCollapsibleFilters = $hasFilters && in_array($filtersLayout, [ FiltersLayout::AboveContentCollapsible, FiltersLayout::BeforeContentCollapsible, FiltersLayout::AfterContentCollapsible, ]); $hasFiltersTrigger = $hasFilters && ($hasFiltersDialog || $hasFiltersBeforeContent || $hasFiltersAfterContent); $filtersFormMaxHeight = $getFiltersFormMaxHeight(); $hasColumnManager = $hasColumnManager(); $columnManagerLayout = $getColumnManagerLayout(); $hasReorderableColumns = $hasReorderableColumns(); $hasToggleableColumns = $hasToggleableColumns(); $columnManagerApplyAction = $getColumnManagerApplyAction(); $columnManagerTriggerAction = $getColumnManagerTriggerAction(); $hasHeader = $header || $heading || $description || ($headerActions && !$isReordering) || $isReorderable || $areGroupingSettingsVisible || $isGlobalSearchVisible || $hasFilters || count($filterIndicators) || $hasColumnManager; $hasHeaderToolbar = $isReorderable || $areGroupingSettingsVisible || $isGlobalSearchVisible || $hasFiltersTrigger || $hasColumnManager; // https://github.com/filamentphp/filament/pull/19787 $headerVisibilityMode = $hasHeader || $hasNonBulkToolbarAction ? 'visible' : (count($toolbarActions) ? 'selection' : 'hidden'); $headerToolbarVisibilityMode = $hasHeaderToolbar || $hasNonBulkToolbarAction ? 'visible' : (count($toolbarActions) ? 'selection' : 'hidden'); $headingTag = $getHeadingTag(); $secondLevelHeadingTag = $heading ? $getHeadingTag(1) : $headingTag; $pluralModelLabel = $getPluralModelLabel(); $records = $isLoaded ? $getRecords() : null; $hasPagination = ($records instanceof \Illuminate\Contracts\Pagination\Paginator || $records instanceof \Illuminate\Contracts\Pagination\CursorPaginator) && ($records instanceof \Illuminate\Contracts\Pagination\LengthAwarePaginator ? $records->total() : $records->isNotEmpty()); $hasEmptyState = $records !== null && !count($records); $hasContentLayout = $content || $hasColumnsLayout; $searchDebounce = $getSearchDebounce(); $allSelectableRecordsCount = $isSelectionEnabled && $isLoaded ? $getAllSelectableRecordsCount() : null; $columnsCount = count($columns); $reorderRecordsTriggerAction = $getReorderRecordsTriggerAction($isReordering); $page = $this->getTablePage(); $defaultSortOptionLabel = $getDefaultSortOptionLabel(); $sortDirection = $getSortDirection(); if (count($defaultRecordActions) && !$isReordering) { $columnsCount++; } if ($isSelectionEnabled || $isReordering) { $columnsCount++; } if ($group) { $groupedSummarySelectedState = $this->getTableSummarySelectedState( $this->getAllTableSummaryQuery(), modifyQueryUsing: fn(\Illuminate\Database\Query\Builder $query) => $group->groupQuery( $query, model: $getQuery()->getModel(), ), ); } if (is_string($filtersFormWidth)) { $filtersFormWidth = Width::tryFrom($filtersFormWidth) ?? $filtersFormWidth; } @endphp
class(['fi-ta', 'fi-loading' => $records === null]) }}>
$hasContentLayout, 'fi-ta-ctn-with-footer' => $hasPagination || $hasEmptyState || $hasFiltersBelowContent, 'fi-ta-ctn-with-header' => $hasHeader, ])> @if ($hasFiltersBeforeContent)
!$hasCollapsibleFilters, ($filtersFormWidth ??= Width::ExtraSmall) instanceof Width ? "fi-width-{$filtersFormWidth->value}" : (is_string($filtersFormWidth) ? $filtersFormWidth : null), ])>
@endif
{{ FilamentView::renderHook(TablesRenderHook::HEADER_BEFORE, scopes: static::class) }} @if ($header) {{ $header }} @elseif (($heading || $description || $headerActions) && !$isReordering)
$headerActions && $headerActionsPosition === HeaderActionsPosition::Adaptive, ])> @if ($heading || $description)
@if ($heading) <{{ $headingTag }} class="fi-ta-header-heading"> {{ $heading }} @endif @if ($description)

{{ $description }}

@endif
@endif @if (!$isReordering && $headerActions)
@foreach ($headerActions as $action) {{ $action }} @endforeach
@endif
@endif {{ FilamentView::renderHook(TablesRenderHook::HEADER_AFTER, scopes: static::class) }} @if ($hasFiltersAboveContent)
@if ($hasCollapsibleFilters) {{ $filtersTriggerAction->badge($activeFiltersCount) }} @endif
@endif {{ FilamentView::renderHook(TablesRenderHook::TOOLBAR_BEFORE, scopes: static::class) }}
{{ FilamentView::renderHook(TablesRenderHook::TOOLBAR_START, scopes: static::class) }}
{{ FilamentView::renderHook(TablesRenderHook::TOOLBAR_REORDER_TRIGGER_BEFORE, scopes: static::class) }} @if ($isReorderable) {{ $reorderRecordsTriggerAction }} @endif {{ FilamentView::renderHook(TablesRenderHook::TOOLBAR_REORDER_TRIGGER_AFTER, scopes: static::class) }} @if (!$isReordering && count($toolbarActions)) @foreach ($toolbarActions as $action) {{ $action }} @endforeach @endif {{ FilamentView::renderHook(TablesRenderHook::TOOLBAR_GROUPING_SELECTOR_BEFORE, scopes: static::class) }} @if ($areGroupingSettingsVisible)
!$areGroupingSettingsInDropdownOnDesktop, ])> {{ $getGroupRecordsTriggerAction() }}
@if (!$isGroupingDirectionSettingHidden) @endif
@if (!$areGroupingSettingsInDropdownOnDesktop)
@if (!$isGroupingDirectionSettingHidden) @endif
@endif
@endif {{ FilamentView::renderHook(TablesRenderHook::TOOLBAR_GROUPING_SELECTOR_AFTER, scopes: static::class) }}
@if ($isGlobalSearchVisible || $hasFiltersTrigger || $hasColumnManager)
{{ FilamentView::renderHook(TablesRenderHook::TOOLBAR_SEARCH_BEFORE, scopes: static::class) }} @if ($isGlobalSearchVisible) @php $searchPlaceholder = $getSearchPlaceholder(); @endphp @endif {{ FilamentView::renderHook(TablesRenderHook::TOOLBAR_SEARCH_AFTER, scopes: static::class) }} @if ($hasFiltersTrigger || $hasColumnManager) @if ($hasFiltersDialog) @if ($filtersLayout === FiltersLayout::Modal || $filtersTriggerAction->isModalSlideOver()) @php $filtersTriggerActionModalAlignment = $filtersTriggerAction->getModalAlignment(); $filtersTriggerActionIsModalAutofocused = $filtersTriggerAction->isModalAutofocused(); $filtersTriggerActionHasModalCloseButton = $filtersTriggerAction->hasModalCloseButton(); $filtersTriggerActionIsModalClosedByClickingAway = $filtersTriggerAction->isModalClosedByClickingAway(); $filtersTriggerActionIsModalClosedByEscaping = $filtersTriggerAction->isModalClosedByEscaping(); $filtersTriggerActionModalDescription = $filtersTriggerAction->getModalDescription(); $filtersTriggerActionExtraModalWindowAttributeBag = $filtersTriggerAction->getExtraModalWindowAttributeBag(); $filtersTriggerActionExtraModalOverlayAttributeBag = $filtersTriggerAction->getExtraModalOverlayAttributeBag(); $filtersTriggerActionVisibleModalFooterActions = $filtersTriggerAction->getVisibleModalFooterActions(); $filtersTriggerActionModalFooterActionsAlignment = $filtersTriggerAction->getModalFooterActionsAlignment(); $filtersTriggerActionModalHeading = $filtersTriggerAction->getCustomModalHeading() ?? __('filament-tables::table.filters.heading'); $filtersTriggerActionModalIcon = $filtersTriggerAction->getModalIcon(); $filtersTriggerActionModalIconColor = $filtersTriggerAction->getModalIconColor(); $filtersTriggerActionIsModalSlideOver = $filtersTriggerAction->isModalSlideOver(); $filtersTriggerActionModalSlideOverPosition = $filtersTriggerAction->getModalSlideOverPosition(); $filtersTriggerActionIsModalFooterSticky = $filtersTriggerAction->isModalFooterSticky(); $filtersTriggerActionIsModalHeaderSticky = $filtersTriggerAction->isModalHeaderSticky(); @endphp {{ $filtersTriggerAction->badge($activeFiltersCount) }} {{ $filtersTriggerAction->getModalContent() }} {{ $filtersForm }} {{ $filtersTriggerAction->getModalContentFooter() }} @else {{ $filtersTriggerAction->badge($activeFiltersCount) }} @endif @elseif ($hasFiltersBeforeContent || $hasFiltersAfterContent) !$hasCollapsibleFilters, ])> {{ $filtersTriggerAction->badge($activeFiltersCount) }} @endif {{ FilamentView::renderHook(TablesRenderHook::TOOLBAR_COLUMN_MANAGER_TRIGGER_BEFORE, scopes: static::class) }} @if ($hasColumnManager) @php $columnManagerMaxHeight = $getColumnManagerMaxHeight(); $columnManagerWidth = $getColumnManagerWidth(); $columnManagerColumns = $getColumnManagerColumns(); @endphp @if ($columnManagerLayout === ColumnManagerLayout::Modal || $columnManagerTriggerAction->isModalSlideOver()) @php $columnManagerTriggerActionModalAlignment = $columnManagerTriggerAction->getModalAlignment(); $columnManagerTriggerActionIsModalAutofocused = $columnManagerTriggerAction->isModalAutofocused(); $columnManagerTriggerActionHasModalCloseButton = $columnManagerTriggerAction->hasModalCloseButton(); $columnManagerTriggerActionIsModalClosedByClickingAway = $columnManagerTriggerAction->isModalClosedByClickingAway(); $columnManagerTriggerActionIsModalClosedByEscaping = $columnManagerTriggerAction->isModalClosedByEscaping(); $columnManagerTriggerActionModalDescription = $columnManagerTriggerAction->getModalDescription(); $columnManagerTriggerActionExtraModalWindowAttributeBag = $columnManagerTriggerAction->getExtraModalWindowAttributeBag(); $columnManagerTriggerActionExtraModalOverlayAttributeBag = $columnManagerTriggerAction->getExtraModalOverlayAttributeBag(); $columnManagerTriggerActionVisibleModalFooterActions = $columnManagerTriggerAction->getVisibleModalFooterActions(); $columnManagerTriggerActionModalFooterActionsAlignment = $columnManagerTriggerAction->getModalFooterActionsAlignment(); $columnManagerTriggerActionModalHeading = $columnManagerTriggerAction->getCustomModalHeading() ?? __('filament-tables::table.column_manager.heading'); $columnManagerTriggerActionModalIcon = $columnManagerTriggerAction->getModalIcon(); $columnManagerTriggerActionModalIconColor = $columnManagerTriggerAction->getModalIconColor(); $columnManagerTriggerActionIsModalSlideOver = $columnManagerTriggerAction->isModalSlideOver(); $columnManagerTriggerActionModalSlideOverPosition = $columnManagerTriggerAction->getModalSlideOverPosition(); $columnManagerTriggerActionIsModalFooterSticky = $columnManagerTriggerAction->isModalFooterSticky(); $columnManagerTriggerActionIsModalHeaderSticky = $columnManagerTriggerAction->isModalHeaderSticky(); @endphp {{ $columnManagerTriggerAction }} {{ $columnManagerTriggerAction->getModalContent() }}
{{ $columnManagerTriggerAction->getModalContentFooter() }}
@else {{ $columnManagerTriggerAction }} @endif @endif {{ FilamentView::renderHook(TablesRenderHook::TOOLBAR_COLUMN_MANAGER_TRIGGER_AFTER, scopes: static::class) }} @endif
@endif {{ FilamentView::renderHook(TablesRenderHook::TOOLBAR_END) }}
{{ FilamentView::renderHook(TablesRenderHook::TOOLBAR_AFTER) }}
@if ($isReordering)
{{ \Filament\Support\generate_loading_indicator_html( new \Illuminate\View\ComponentAttributeBag([ 'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '', 'wire:target' => 'reorderTable', ]), ) }} {{ __('filament-tables::table.reorder_indicator') }}
@elseif ($isSelectionEnabled && $maxSelectableRecords !== 1 && $isLoaded)
{{ \Filament\Support\generate_loading_indicator_html( new \Illuminate\View\ComponentAttributeBag([ 'x-show' => 'isLoading', ]), ) }}
@if (!$isSelectionDisabled)
{{ FilamentView::renderHook(TablesRenderHook::SELECTION_INDICATOR_ACTIONS_BEFORE, scopes: static::class) }}
@if (!$selectsGroupsOnly) {{ trans_choice('filament-tables::table.selection_indicator.actions.select_all.label', $allSelectableRecordsCount, ['count' => \Illuminate\Support\Number::format($allSelectableRecordsCount, locale: app()->getLocale())]) }} @endif {{ __('filament-tables::table.selection_indicator.actions.deselect_all.label') }}
{{ FilamentView::renderHook(TablesRenderHook::SELECTION_INDICATOR_ACTIONS_AFTER, scopes: static::class) }}
@endif
@endif @if ($filterIndicators) @if (filled( $filterIndicatorsView = FilamentView::renderHook(TablesRenderHook::FILTER_INDICATORS, scopes: static::class, data: ['filterIndicators' => $filterIndicators]))) {{ $filterIndicatorsView }} @else
{{ __('filament-tables::table.filters.indicator') }}
@foreach ($filterIndicators as $indicator) @php $indicatorColor = $indicator->getColor(); @endphp {{ $indicator->getLabel() }} @if ($indicator->isRemovable()) @php $indicatorRemoveLivewireClickHandler = $indicator->getRemoveLivewireClickHandler(); @endphp @endif @endforeach
@if (collect($filterIndicators)->contains(fn(\Filament\Tables\Filters\Indicator $indicator): bool => $indicator->isRemovable())) {{ $getFiltersRemoveAllAction() }} @endif
@endif @endif @if ((!$content && !$hasColumnsLayout) || $records === null || count($records))
@if ($hasContentLayout && $records !== null && count($records)) @if (!$isReordering) @php $sortableColumns = array_filter( $columns, fn(\Filament\Tables\Columns\Column $column): bool => $column->isSortable(), ); @endphp @if ( ($isSelectionEnabled && $maxSelectableRecords !== 1 && !$isReordering && !$selectsGroupsOnly) || count($sortableColumns))
@if ($isSelectionEnabled && $maxSelectableRecords !== 1 && !$isReordering && !$selectsGroupsOnly) @endif @if (count($sortableColumns))
@endif
@endif @endif @if ($content) {{ $content->with(['records' => $records]) }} @else
when($contentGrid, fn(ComponentAttributeBag $attributes) => $attributes->grid($contentGrid))->class([ 'fi-ta-content', 'fi-ta-content-grid' => $contentGrid, 'fi-ta-content-grouped' => $this->getTableGrouping(), ]) }}> @php $previousRecord = null; $previousRecordGroupKey = null; $previousRecordGroupTitle = null; @endphp @foreach ($records as $record) @php $recordAction = $getRecordAction($record); $recordKey = $getRecordKey($record); $recordUrl = $getRecordUrl($record); $openRecordUrlInNewTab = $shouldOpenRecordUrlInNewTab($record); $recordGroupKey = $group?->getStringKey($record); $recordGroupTitle = $group?->getTitle($record); $isRecordGroupCollapsible = $group?->isCollapsible(); $collapsibleColumnsLayout?->record($record)->recordKey($recordKey); $hasCollapsibleColumnsLayout = (bool) $collapsibleColumnsLayout?->isVisible(); $recordActions = array_reduce( $defaultRecordActions, function (array $carry, $action) use ($record): array { $action = $action->getClone(); if (!$action instanceof \Filament\Actions\BulkAction) { $action->record($record); } if ($action->isHidden()) { return $carry; } $carry[] = $action; return $carry; }, initial: [], ); @endphp @if ((string) $recordGroupTitle !== (string) $previousRecordGroupTitle) @if ($hasSummary && !$isReordering && filled($previousRecordGroupTitle)) $isReordering])> @php $groupScopedAllTableSummaryQuery = $group->scopeQuery( $this->getAllTableSummaryQuery(), $previousRecord, ); @endphp
@endif
isCollapsible()) x-on:click="toggleCollapseGroup(@js($recordGroupTitle))" @if (!$hasSummary) x-bind:class="{ 'fi-collapsed': isGroupCollapsed(@js($recordGroupTitle)) }" @endif @endif @class([ 'fi-ta-group-header', 'fi-collapsible' => $isRecordGroupCollapsible, ]) > @if ($isSelectionEnabled && $maxSelectableRecords !== 1) @endif
<{{ $secondLevelHeadingTag }} class="fi-ta-group-heading"> @if (filled($recordGroupLabel = $group->isTitlePrefixedWithLabel() ? $group->getLabel() : null)) {{ $recordGroupLabel }}: @endif {{ $recordGroupTitle }} @if (filled($recordGroupDescription = $group->getDescription($record, $recordGroupTitle)))

{{ $recordGroupDescription }}

@endif
@if ($isRecordGroupCollapsible) @endif
@endif
$recordUrl || $recordAction, 'fi-ta-record-with-content-prefix' => $isReordering || ($isSelectionEnabled && $isRecordSelectable($record)), 'fi-ta-record-with-content-suffix' => $hasCollapsibleColumnsLayout && !$isReordering, ...$getRecordClasses($record), ]) x-bind:class="{ {{ $group?->isCollapsible() ? '\'fi-collapsed\': isGroupCollapsed(' . \Illuminate\Support\Js::from($recordGroupTitle) . '),' : '' }} 'fi-selected': isRecordSelected(@js($recordKey)), }"> @php $hasItemBeforeRecordContent = $isReordering || ($isSelectionEnabled && $isRecordSelectable($record)); $hasItemAfterRecordContent = $hasCollapsibleColumnsLayout && !$isReordering; @endphp @if ($isReordering) @elseif ($isSelectionEnabled && $isRecordSelectable($record)) @endif
@if ($recordUrl) class(['fi-ta-record-content']) }}> @foreach ($columnsLayout as $columnsLayoutComponent) {{ $columnsLayoutComponent->record($record)->recordKey($recordKey)->rowLoop($loop)->renderInLayout() }} @endforeach @elseif ($recordAction) @php $recordWireClickAction = $getRecordAction($record) ? "mountTableAction('{$recordAction}', '{$recordKey}')" : ($recordWireClickAction = "{$recordAction}('{$recordKey}')"); @endphp @else
@foreach ($columnsLayout as $columnsLayoutComponent) {{ $columnsLayoutComponent->record($record)->recordKey($recordKey)->rowLoop($loop)->renderInLayout() }} @endforeach
@endif @if ($hasCollapsibleColumnsLayout && !$isReordering)
{{ $collapsibleColumnsLayout }}
@endif
@if ($recordActions && !$isReordering)
'fi-align-start', Alignment::Center => 'fi-align-center', Alignment::End => 'fi-align-end', } => $contentGrid, 'fi-align-start md:fi-align-end' => !$contentGrid, 'fi-ta-actions-before-columns-position' => $recordActionsPosition === RecordActionsPosition::BeforeColumns, ])> @foreach ($recordActions as $action) {{ $action }} @endforeach
@endif
@if ($hasCollapsibleColumnsLayout && !$isReordering) @endif
@php $previousRecordGroupKey = $recordGroupKey; $previousRecordGroupTitle = $recordGroupTitle; $previousRecord = $record; @endphp @endforeach @if ( $hasSummary && !$isReordering && filled($previousRecordGroupTitle) && $this->shouldRenderTrailingGroupedTableSummary($previousRecord)) @php $groupScopedAllTableSummaryQuery = $group->scopeQuery( $this->getAllTableSummaryQuery(), $previousRecord, ); @endphp
@endif
@endif @if (($content || $hasColumnsLayout) && $contentFooter) {{ $contentFooter->with([ 'columns' => $columns, 'records' => $records, ]) }} @endif @if ($hasTopLevelSummary && !$isReordering)
@endif @elseif (!($content || $hasColumnsLayout) && $records !== null) @php $sortableColumns = $isStackedOnMobile ? array_filter( $columns, fn(\Filament\Tables\Columns\Column $column): bool => $column->isSortable(), ) : []; @endphp $isStackedOnMobile, ])> @if ( $isStackedOnMobile && (count($sortableColumns) || ($isSelectionEnabled && $maxSelectableRecords !== 1 && !$selectsGroupsOnly)) && !$isReordering) @endif @if ($hasColumnGroups) @if (count($records)) @if ($isReordering) @else @if (count($defaultRecordActions) && in_array($recordActionsPosition, [RecordActionsPosition::BeforeCells, RecordActionsPosition::BeforeColumns])) @endif @if ($isSelectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::BeforeCells) @endif @endif @endif @foreach ($columnsLayout as $columnGroup) @if ($columnGroup instanceof Column) @if ($columnGroup->isVisible() && !$columnGroup->isToggledHidden()) @endif @elseif ($columnGroup instanceof ColumnGroup) @php $columnGroupColumnsCount = count($columnGroup->getVisibleColumns()); @endphp @if ($columnGroupColumnsCount) @endif @endif @endforeach @if (!$isReordering && count($records)) @if (count($defaultRecordActions) && in_array($recordActionsPosition, [RecordActionsPosition::AfterColumns, RecordActionsPosition::AfterCells])) @endif @if ($isSelectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::AfterCells) @endif @endif @endif @if (count($records)) @if ($isReordering) @else @if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::BeforeCells) @if ($recordActionsColumnLabel) @else @endif @endif @if ($isSelectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::BeforeCells) @endif @if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::BeforeColumns) @if ($recordActionsColumnLabel) @else @endif @endif @endif @endif @php $hasHeaderCellRenderHook = FilamentView::hasRenderHook( TablesRenderHook::HEADER_CELL, scopes: static::class, ); @endphp @foreach ($columns as $column) @if ( $hasHeaderCellRenderHook && filled( $headerCellView = FilamentView::renderHook(TablesRenderHook::HEADER_CELL, scopes: static::class, data: [ 'column' => $column, 'isReordering' => $isReordering, ]))) {{ $headerCellView }} @else @php $columnName = $column->getName(); $columnLabel = $column->getLabel(); $columnAlignment = $column->getAlignment(); $columnWidth = $column->getWidth(); $isColumnActivelySorted = $getSortColumn() === $column->getName(); $isColumnSortable = $column->isSortable() && !$isReordering; $columnHeaderTooltip = $column->getHeaderTooltip(); $columnHeaderTooltipAttribute = $columnHeaderTooltip instanceof \Illuminate\Contracts\Support\Htmlable ? 'x-tooltip.html' : 'x-tooltip'; @endphp @endif @endforeach @if (!$isReordering && count($records)) @if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::AfterColumns) @if ($recordActionsColumnLabel) @else @endif @endif @if ($isSelectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::AfterCells) @endif @if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::AfterCells) @if ($recordActionsColumnLabel) @else @endif @endif @endif @if ($isColumnSearchVisible || count($records)) @if ($isColumnSearchVisible) @if (count($records)) @if ($isReordering) @else @if (count($defaultRecordActions) && in_array($recordActionsPosition, [RecordActionsPosition::BeforeCells, RecordActionsPosition::BeforeColumns])) @endif @if ($isSelectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::BeforeCells) @endif @endif @endif @foreach ($columns as $column) @php $columnName = $column->getName(); @endphp @endforeach @if (!$isReordering && count($records)) @if (count($defaultRecordActions) && in_array($recordActionsPosition, [RecordActionsPosition::AfterColumns, RecordActionsPosition::AfterCells])) @endif @if ($isSelectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::AfterCells) @endif @endif @endif @if (count($records)) @php $isRecordRowStriped = false; $previousRecord = null; $previousRecordGroupKey = null; $previousRecordGroupTitle = null; @endphp @foreach ($records as $record) @php $recordAction = $getRecordAction($record); $recordKey = $getRecordKey($record); $recordUrl = $getRecordUrl($record); $openRecordUrlInNewTab = $shouldOpenRecordUrlInNewTab($record); $recordGroupKey = $group?->getStringKey($record); $recordGroupTitle = $group?->getTitle($record); $recordActions = array_reduce( $defaultRecordActions, function (array $carry, $action) use ($record): array { $action = $action->getClone(); if (!$action instanceof \Filament\Actions\BulkAction) { $action->record($record); } if ($action->isHidden()) { return $carry; } $carry[] = $action; return $carry; }, initial: [], ); @endphp @if ((string) $recordGroupTitle !== (string) $previousRecordGroupTitle) @if ($hasSummary && !$isReordering && filled($previousRecordGroupTitle)) @php $groupColumn = $group->getColumn(); $groupScopedAllTableSummaryQuery = $group->scopeQuery( $this->getAllTableSummaryQuery(), $previousRecord, ); @endphp @endif @if (!$isGroupsOnly) @php $isRecordGroupCollapsible = $group?->isCollapsible(); $groupHeaderColspan = $columnsCount; if ($isSelectionEnabled) { $groupHeaderColspan--; if ( $recordCheckboxPosition === RecordCheckboxPosition::BeforeCells && count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::BeforeCells ) { $groupHeaderColspan--; } } @endphp @if ($isSelectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::BeforeCells) @if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::BeforeCells) @endif @endif @if ($isSelectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::AfterCells) @endif @endif @php $isRecordRowStriped = false; @endphp @endif @if (!$isGroupsOnly) $recordAction || $recordUrl, 'fi-striped' => $isStriped && $isRecordRowStriped, ...$getRecordClasses($record), ])> @if ($isReordering) @endif @if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::BeforeCells && !$isReordering) @endif @if ($isSelectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::BeforeCells && !$isReordering) @endif @if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::BeforeColumns && !$isReordering) @endif @foreach ($columns as $column) @php $column->record($record); $column->rowLoop($loop->parent); $column->recordKey($recordKey); $columnAction = $column->getAction(); $columnUrl = $column->getUrl(); $columnHasStateBasedUrls = $column->hasStateBasedUrls(); $isColumnClickDisabled = $column->isClickDisabled() || $isReordering; $columnWrapperTag = match (true) { ($columnUrl || ($recordUrl && $columnAction === null)) && !$columnHasStateBasedUrls && !$isColumnClickDisabled => 'a', ($columnAction || $recordAction) && !$columnHasStateBasedUrls && !$isColumnClickDisabled => 'button', default => 'div', }; if ($columnWrapperTag === 'button') { if ($columnAction instanceof \Filament\Actions\Action) { $columnWireClickAction = "mountTableAction('{$columnAction->getName()}', '{$recordKey}')"; } elseif ($columnAction) { $columnWireClickAction = "callTableColumnAction('{$column->getName()}', '{$recordKey}')"; } else { if ($this->getTable()->getAction($recordAction)) { $columnWireClickAction = "mountTableAction('{$recordAction}', '{$recordKey}')"; } else { $columnWireClickAction = "{$recordAction}('{$recordKey}')"; } } } @endphp @endforeach @if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::AfterColumns && !$isReordering) @endif @if ($isSelectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::AfterCells && !$isReordering) @endif @if (count($defaultRecordActions) && $recordActionsPosition === RecordActionsPosition::AfterCells && !$isReordering) @endif @endif @php $isRecordRowStriped = !$isRecordRowStriped; $previousRecord = $record; $previousRecordGroupKey = $recordGroupKey; $previousRecordGroupTitle = $recordGroupTitle; @endphp @endforeach @if ( $hasSummary && !$isReordering && filled($previousRecordGroupTitle) && $this->shouldRenderTrailingGroupedTableSummary($previousRecord)) @php $groupColumn = $group->getColumn(); $groupScopedAllTableSummaryQuery = $group->scopeQuery( $this->getAllTableSummaryQuery(), $previousRecord, ); @endphp @endif @if ($hasSummary && !$isReordering) @php $groupColumn = $group?->getColumn(); @endphp @endif @endif @endif @if ($records !== null && count($records) && $contentFooter) {{ $contentFooter->with([ 'columns' => $columns, 'records' => $records, ]) }} @endif
@if (count($sortableColumns))
@endif @if ($isSelectionEnabled && $maxSelectableRecords !== 1 && !$selectsGroupsOnly) @endif
getExtraHeaderAttributeBag()->class([ 'fi-ta-header-group-cell', 'fi-wrapped' => $columnGroup->canHeaderWrap(), ($columnGroupAlignment = $columnGroup->getAlignment()) instanceof \Filament\Support\Enums\Alignment ? "fi-align-{$columnGroupAlignment->value}" : (is_string($columnGroupAlignment) ? $columnGroupAlignment : ''), filled($columnGroupHiddenFrom = $columnGroup->getHiddenFrom()) ? "{$columnGroupHiddenFrom}:fi-hidden" : '', filled($columnGroupVisibleFrom = $columnGroup->getVisibleFrom()) ? "{$columnGroupVisibleFrom}:fi-visible" : '', ]) }}> {{ $columnGroup->getLabel() }}
{{ $recordActionsColumnLabel }} @if ($maxSelectableRecords !== 1 && !$selectsGroupsOnly) @endif {{ $recordActionsColumnLabel }} getExtraHeaderAttributeBag()->class([ 'fi-ta-header-cell', 'fi-ta-header-cell-' . str($columnName)->camel()->kebab(), 'fi-growable' => blank($columnWidth) && $column->canGrow(default: false), 'fi-grouped' => $column->getGroup(), 'fi-wrapped' => $column->canHeaderWrap(), 'fi-ta-header-cell-sorted' => $isColumnActivelySorted, ($columnAlignment = $column->getAlignment()) instanceof \Filament\Support\Enums\Alignment ? "fi-align-{$columnAlignment->value}" : (is_string($columnAlignment) ? $columnAlignment : ''), filled($columnHiddenFrom = $column->getHiddenFrom()) ? "{$columnHiddenFrom}:fi-hidden" : '', filled($columnVisibleFrom = $column->getVisibleFrom()) ? "{$columnVisibleFrom}:fi-visible" : '', ])->style([ 'width: ' . e($columnWidth) => filled($columnWidth), ]) }}> @if ($isColumnSortable) @if (filled($columnHeaderTooltip)) {{ $columnLabel }} @else {{ $columnLabel }} @endif {{ \Filament\Support\generate_icon_html( $isColumnActivelySorted && $sortDirection === 'asc' ? \Filament\Support\Icons\Heroicon::ChevronUp : \Filament\Support\Icons\Heroicon::ChevronDown, alias: match (true) { $isColumnActivelySorted && $sortDirection === 'asc' => \Filament\Tables\View\TablesIconAlias::HEADER_CELL_SORT_ASC_BUTTON, $isColumnActivelySorted && $sortDirection === 'desc' => \Filament\Tables\View\TablesIconAlias::HEADER_CELL_SORT_DESC_BUTTON, default => \Filament\Tables\View\TablesIconAlias::HEADER_CELL_SORT_BUTTON, }, attributes: new \Illuminate\View\ComponentAttributeBag([ 'wire:loading.remove.delay.' . config('filament.livewire_loading_delay', 'default') => true, 'wire:target' => "sortTable('{$columnName}')", ]), ) }} {{ \Filament\Support\generate_loading_indicator_html( new \Illuminate\View\ComponentAttributeBag([ 'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '', 'wire:target' => "sortTable('{$columnName}')", ]), ) }} @else @if (filled($columnHeaderTooltip)) {{ $columnLabel }} @else {{ $columnLabel }} @endif @endif {{ $recordActionsColumnLabel }} @if ($maxSelectableRecords !== 1 && !$selectsGroupsOnly) @endif {{ $recordActionsColumnLabel }}
($isIndividuallySearchable = $column->isIndividuallySearchable()), 'fi-ta-individual-search-cell-' . str($columnName)->camel()->kebab() => $isIndividuallySearchable, ])> @if ($isIndividuallySearchable) @endif
@if ($maxSelectableRecords !== 1) @endif
$isRecordGroupCollapsible, ])>
<{{ $secondLevelHeadingTag }} class="fi-ta-group-heading"> @if (filled($recordGroupLabel = $group->isTitlePrefixedWithLabel() ? $group->getLabel() : null)) {{ $recordGroupLabel }}: @endif {{ $recordGroupTitle }} @if (filled($recordGroupDescription = $group->getDescription($record, $recordGroupTitle)))

{{ $recordGroupDescription }}

@endif
@if ($isRecordGroupCollapsible) @endif
@if ($maxSelectableRecords !== 1) @endif
'fi-align-center', Alignment::Start, Alignment::Left => 'fi-align-start', Alignment::Between, Alignment::Justify => 'fi-align-between', Alignment::End, Alignment::Right => '', default => is_string($recordActionsAlignment) ? $recordActionsAlignment : '', }, ])> @foreach ($recordActions as $action) {{ $action }} @endforeach
@if ($isRecordSelectable($record)) @endif
'fi-align-center', Alignment::Start, Alignment::Left => 'fi-align-start', Alignment::Between, Alignment::Justify => 'fi-align-between', Alignment::End, Alignment::Right => '', default => is_string($recordActionsAlignment) ? $recordActionsAlignment : '', }, ])> @foreach ($recordActions as $action) {{ $action }} @endforeach
getExtraCellAttributeBag()->class([ 'fi-ta-cell', 'fi-ta-cell-' . str($column->getName())->camel()->kebab(), ($columnAlignment = $column->getAlignment()) instanceof \Filament\Support\Enums\Alignment ? "fi-align-{$columnAlignment->value}" : (is_string($columnAlignment) ? $columnAlignment : ''), ($columnVerticalAlignment = $column->getVerticalAlignment()) instanceof \Filament\Support\Enums\VerticalAlignment ? "fi-vertical-align-{$columnVerticalAlignment->value}" : (is_string($columnVerticalAlignment) ? $columnVerticalAlignment : ''), filled($columnHiddenFrom = $column->getHiddenFrom()) ? "{$columnHiddenFrom}:fi-hidden" : '', filled($columnVisibleFrom = $column->getVisibleFrom()) ? "{$columnVisibleFrom}:fi-visible" : '', ]) }}> {!! $isStackedOnMobile ? '
' . e($column->getLabel()) . '
' : '' !!} <{{ $columnWrapperTag }} @if ($columnWrapperTag === 'a') {{ \Filament\Support\generate_href_html($columnUrl ?: $recordUrl, $columnUrl ? $column->shouldOpenUrlInNewTab() : $openRecordUrlInNewTab, hasNestedClickEventHandler: true) }} @if (blank($columnUrl) && filled($recordUrl)) {{ $getExtraRecordLinkAttributeBag($record) }} @endif @elseif ($columnWrapperTag === 'button') type="button" wire:click.prevent.stop="{{ $columnWireClickAction }}" wire:loading.attr="disabled" wire:target="{{ $columnWireClickAction }}" @endif @class([ 'fi-ta-col', 'fi-ta-col-has-column-url' => $columnWrapperTag === 'a' && filled($columnUrl), ]) > {{ $column }} {!! $isStackedOnMobile ? '
' : '' !!}
'fi-align-center', Alignment::Start, Alignment::Left => 'fi-align-start', Alignment::Between, Alignment::Justify => 'fi-align-between', Alignment::End, Alignment::Right => '', default => is_string($recordActionsAlignment) ? $recordActionsAlignment : '', }, ])> @foreach ($recordActions as $action) {{ $action }} @endforeach
@if ($isRecordSelectable($record)) @endif
'fi-align-center', Alignment::Start, Alignment::Left => 'fi-align-start', Alignment::Between, Alignment::Justify => 'fi-align-between', Alignment::End, Alignment::Right => '', default => is_string($recordActionsAlignment) ? $recordActionsAlignment : '', }, ])> @foreach ($recordActions as $action) {{ $action }} @endforeach
@elseif ($records === null)
{{ \Filament\Support\generate_loading_indicator_html(size: \Filament\Support\Enums\IconSize::TwoExtraLarge) }}
@endif
@endif @if ($hasEmptyState) @if ($emptyState = $getEmptyState()) {{ $emptyState }} @else
{{ \Filament\Support\generate_icon_html($getEmptyStateIcon(), size: \Filament\Support\Enums\IconSize::Large) }}
<{{ $secondLevelHeadingTag }} class="fi-ta-empty-state-heading"> {{ $getEmptyStateHeading() }} @if (filled($emptyStateDescription = $getEmptyStateDescription()))

{{ $emptyStateDescription }}

@endif @if ( $emptyStateActions = array_filter( $getEmptyStateActions(), fn(\Filament\Actions\Action|\Filament\Actions\ActionGroup $action): bool => $action->isVisible()))
@foreach ($emptyStateActions as $action) {{ $action }} @endforeach
@endif
@endif @endif @if ($hasPagination) @php $hasExtremePaginationLinks = $hasExtremePaginationLinks(); $paginationPageOptions = $getPaginationPageOptions(); @endphp @endif @if ($hasFiltersBelowContent) @endif
@if ($hasFiltersAfterContent)
!$hasCollapsibleFilters, ($filtersFormWidth ??= Width::ExtraSmall) instanceof Width ? "fi-width-{$filtersFormWidth->value}" : (is_string($filtersFormWidth) ? $filtersFormWidth : null), ])>
@endif