> */ public array $settingsRows = []; public string $context = 'policy'; /** * @param array> $settingsRows */ public function mount(array $settingsRows = [], string $context = 'policy'): void { $this->settingsRows = $settingsRows; $this->context = $context; } public function table(Table $table): Table { return $table ->queryStringIdentifier('settingsCatalog'.Str::studly($this->context)) ->records(function (?string $search, int|string $page, int|string $recordsPerPage, ?string $sortColumn, ?string $sortDirection): LengthAwarePaginator { $records = collect($this->settingsRows); if (filled($search)) { $needle = Str::lower($search); $records = $records->filter(function (array $row) use ($needle): bool { $haystack = implode(' ', [ (string) ($row['definition'] ?? ''), (string) ($row['category'] ?? ''), (string) ($row['data_type'] ?? ''), (string) ($row['value'] ?? ''), (string) ($row['description'] ?? ''), (string) ($row['path'] ?? ''), ]); return Str::contains(Str::lower($haystack), $needle); }); } if (filled($sortColumn)) { $direction = Str::lower((string) ($sortDirection ?? 'asc')) === 'desc' ? 'desc' : 'asc'; $records = $records->sortBy( fn (array $row) => (string) ($row[$sortColumn] ?? ''), SORT_NATURAL | SORT_FLAG_CASE, $direction === 'desc' ); } $perPage = is_numeric($recordsPerPage) ? max(1, (int) $recordsPerPage) : 25; $currentPage = is_numeric($page) ? max(1, (int) $page) : 1; $total = $records->count(); $items = $records->forPage($currentPage, $perPage)->values(); return new LengthAwarePaginator( $items, $total, $perPage, $currentPage ); }) ->paginated([25, 50, 100]) ->defaultPaginationPageOption(25) ->searchable() ->searchPlaceholder('Search definition/value…') ->striped() ->deferLoading(! app()->runningUnitTests()) ->columns([ TextColumn::make('definition') ->label('Definition') ->limit(50) ->tooltip(fn (?string $state): ?string => filled($state) ? $state : null) ->searchable() ->sortable() ->wrap(), TextColumn::make('category') ->label('Category') ->limit(30) ->tooltip(fn (?string $state): ?string => filled($state) ? $state : null) ->searchable() ->sortable() ->toggleable() ->wrap(), TextColumn::make('data_type') ->label('Data Type') ->badge() ->color(fn (?string $state): string => match ($state) { 'Number' => 'info', 'Boolean' => 'success', 'Choice' => 'warning', 'Text' => 'gray', default => 'gray', }) ->searchable() ->sortable() ->toggleable(), TextColumn::make('value') ->label('Value') ->badge(fn (?string $state): bool => $state === '(group)') ->color(fn (?string $state): string => $state === '(group)' ? 'gray' : 'primary') ->limit(40) ->tooltip(fn (?string $state): ?string => filled($state) ? $state : null) ->searchable() ->wrap(), TextColumn::make('description') ->label('Description') ->limit(60) ->tooltip(fn (?string $state): ?string => filled($state) ? $state : null) ->searchable() ->toggleable(isToggledHiddenByDefault: true) ->wrap(), TextColumn::make('path') ->label('Path') ->limit(80) ->tooltip(fn (?string $state): ?string => filled($state) ? $state : null) ->toggleable(isToggledHiddenByDefault: true) ->extraAttributes(['class' => 'font-mono text-xs']), ]) ->actions([ Action::make('details') ->label('Details') ->icon('heroicon-m-eye') ->slideOver() ->modalSubmitAction(false) ->modalCancelActionLabel('Close') ->modalHeading(fn (array $record): string => (string) ($record['definition'] ?? 'Setting details')) ->modalContent(fn (array $record): View => view('filament.modals.settings-catalog-setting-details', ['record' => $record])), ]); } public function render(): View { return view('livewire.settings-catalog-settings-table'); } }