### Install filament-async-column via Composer Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Install the package via Composer. Requires PHP 8.2+ and filament/tables ^5.0. No build step or npm needed for panel users. ```bash composer require giacomomasseron/filament-async-column ``` -------------------------------- ### Add AsyncColumn with resolveUsing() Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Shows the minimal setup for AsyncColumn: add the column and provide a resolveUsing() callback. This is the only method every AsyncColumn needs. ```php use GiacomoMasseroni\AsyncColumn\Columns\AsyncColumn; use Filament\Tables\Table; use Illuminate\Support\Facades\Http; public function table(Table $table): Table { return $table->columns([ AsyncColumn::make('open_support_tickets') ->resolveUsing(fn ($record) => Http::get('https://support.example.com/api/tickets/count', [ 'customer_id' => $record->id, ])->json('count')), ]); } ``` -------------------------------- ### Publish Filament assets outside a panel Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Run this command after installing the package and after every composer update when using filament/tables outside a panel. It copies the package's assets to public/ so @filamentStyles and @filamentScripts can serve them. ```bash php artisan filament:assets ``` -------------------------------- ### Publish the filament-async-column config file Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Publishes the package's configuration file to the application's config directory. Run this command to customize the default settings. ```bash php artisan vendor:publish --tag="filament-async-column-config" ``` -------------------------------- ### Format AsyncColumn with money(), weight(), and color() Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Demonstrates that AsyncColumn extends TextColumn, so formatting methods like money(), weight(), and color() work on the resolved value. ```php AsyncColumn::make('lifetime_value') ->resolveUsing(fn ($record) => $this->billingService->lifetimeValue($record)) ->money('USD') ->weight('bold') ->color(fn (?float $state) => $state > 1000 ? 'success' : 'gray'); ``` -------------------------------- ### Run tests with composer test Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Runs the project's test suite using Composer. Use this command to execute all tests defined in the project. ```bash composer test ``` -------------------------------- ### Configure async-column cache and batch size Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Default configuration for the package. The cache_store uses the application's default store when null, cache_prefix is used for all cache keys, and max_batch_size caps the number of cell tokens per batch request, falling back to 200 for values <= 0. ```php // config/async-column.php return [ // Cache store used by ->cacheFor(). Null = the application's default store. 'cache_store' => env('ASYNC_COLUMN_CACHE_STORE'), // Prefix for every cache key this package writes. 'cache_prefix' => 'async-column', // Maximum number of cell tokens resolved in a single batch request. Extra // tokens beyond this cap are silently truncated, never an error. A value // <= 0 (including a malformed env value) falls back to the default of // 200 rather than disabling the cap. 'max_batch_size' => (int) env('ASYNC_COLUMN_MAX_BATCH_SIZE', 200), ]; ``` -------------------------------- ### Customize loading and error states Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Customize the loading and error states. Both loadingState() and errorState() accept a string, an Htmlable, or a closure. Defaults are a CSS skeleton and a translated 'Could not load'. ```php AsyncColumn::make('shipment_eta') ->resolveUsing(fn ($record) => $this->carrier->eta($record)) ->loadingState('Checking carrier...') ->errorState('Carrier unavailable'); ``` -------------------------------- ### Render AsyncColumn as raw HTML with ->html() Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Renders the resolved value as raw HTML using ->html(). Use when the resolver returns markup you trust. ```php AsyncColumn::make('status_badge') ->resolveUsing(fn ($record) => ''.$record->status.'') ->html(); ``` -------------------------------- ### Scope cache per viewer with cacheVersion Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Use when the resolver returns viewer-specific data. The cache key is shared across users, so scope it per viewer by setting a cache version based on the authenticated user's ID. ```php AsyncColumn::make('my_price') ->cacheFor(300) ->cacheVersion(fn () => auth()->id()) ``` -------------------------------- ### Render AsyncColumn with a custom view Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Renders the resolved value using a custom view via ->view(). The resolved state and record are available in the view. ```php AsyncColumn::make('status') ->resolveUsing(fn ($record) => $record->status) ->view('columns.status-pill'); ``` -------------------------------- ### Sort an AsyncColumn with a custom query closure Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Use this when the underlying data is sortable through a custom query. The `sortable()` method throws unless a `query:` closure is provided, because the resolver produces the value after the table's query has already run. The closure must order by a column that exists in SQL, such as a `withCount()` aggregate. ```php AsyncColumn::make('open_support_tickets') ->resolveUsing(fn ($record) => $this->ticketService->count($record)) ->sortable(query: fn (Builder $query, string $direction) => $query ->withCount('supportTickets') ->orderBy('support_tickets_count', $direction)) ``` -------------------------------- ### Cache expensive resolution with cacheFor() Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Cache the resolved value for a number of seconds with cacheFor(). Read the Caching section first: keys are shared across users, which is suitable for record-specific data but problematic for viewer-specific data. ```php AsyncColumn::make('open_support_tickets') ->resolveUsing(fn ($record) => $this->tickets->count($record)) ->cacheFor(300); // seconds ``` -------------------------------- ### Render AsyncColumn as plain text Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Renders the resolved value as plain text (the default). The value is cast to a string and HTML-escaped. ```php AsyncColumn::make('status')->resolveUsing(fn ($record) => $record->status); ``` -------------------------------- ### Handle exceptions with errorStateUsing() Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Use errorStateUsing() to access the underlying Throwable. The closure parameter must be named $exception for Filament to inject it. Never render $exception->getMessage() directly into the cell due to security risks. ```php ->errorStateUsing(fn (Throwable $exception) => $exception instanceof ConnectionException ? 'Carrier offline' : 'Could not load') ``` -------------------------------- ### Disable click-to-retry with retryable(false) Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Disable click-to-retry for failed cells by passing false to retryable(). Use when the resolver is not safe to repeat or costs money per call. ```php AsyncColumn::make('credit_check') ->resolveUsing(fn ($record) => $this->bureau->check($record)) ->retryable(false); ``` -------------------------------- ### Wait for cell visibility with whenVisible() Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Use whenVisible() to delay resolution until the cell scrolls into the viewport, using IntersectionObserver. By default, visible cells resolve as soon as the page paints. ```php AsyncColumn::make('inventory_level') ->resolveUsing(fn ($record) => $this->warehouse->stockFor($record)) ->whenVisible(); ``` -------------------------------- ### Clear cache in a model observer Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Typical usage in a model observer to clear the cached cell the moment the underlying data changes. The same call works in queued jobs or tinker. ```php class PostObserver { public function saved(Post $post): void { AsyncColumn::forget(ListPosts::class, 'stock_level', $post->getKey()); } } ``` -------------------------------- ### Invalidate cached cells with AsyncColumn::forget() Source: https://github.com/giacomomasseron/filament-async-column/blob/main/README.md Removes cached cells written by cacheFor(). Takes the key's parts rather than a column instance, so it can be called from anywhere. The record key must match the table's getTableRecordKey() and the version must match exactly; a Closure version cannot be forgotten and throws a LogicException. ```php use GiacomoMasseroni\AsyncColumn\Columns\AsyncColumn; // One cell. AsyncColumn::forget(ListPosts::class, 'stock_level', $post->getKey()); // Many cells of the same column, in one call. AsyncColumn::forget(ListPosts::class, 'stock_level', [1, 2, 3]); // A cell written under a ->cacheVersion(). AsyncColumn::forget(ListPosts::class, 'stock_level', $post->getKey(), version: 'v2'); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.