Suggestion Misses' "Promote Selected" now opens the same bulk-add modal shape as Suggestions' "Create Many" (editable phrases textarea + lang/intent), prefilled with the selected misses' own text/language, and submits via batchCreateSuggestions() so edited/added lines are honored. Once that succeeds, the selected misses are deleted via the new batchDeleteSuggestionMisses() (DELETE /admin/suggestion-misses/batch) so they don't linger in the list now that they're suggestions. This is best-effort: a failed cleanup doesn't undo the promotion, just surfaces a separate warning notification.
3.6 KiB
paths
| paths | |
|---|---|
|
Pages
Non-Resource Filament pages need an explicit table-rendering view + deferLoading-aware tests
A Filament\Pages\Page implements HasTable (not a Resource) does NOT render its table automatically — it must set protected string $view = '<module>::filament.pages.<slug>'; pointing at a Blade file containing <x-filament-panels::page>{{ $this->table }}</x-filament-panels::page> (see ManageFaqs/ViewEvChatHistory/BookingsRevenueReport). Omitting this silently renders an empty page — no error, just a blank fi-page-content.
Filament v4 tables default to deferred loading. In Pest/Livewire tests, call ->loadTable() before any assertSee()/assertCanSeeTableRecords() on a freshly-mounted component, or the table body won't be in the rendered HTML yet.
For custom-data (->records()-backed, non-Eloquent) tables: use ->callTableAction($name, $record, data: [...]) / ->mountTableAction(...) (not the generic ->callAction(), which targets page-level actions and misses table header/record actions), and use ->assertMountedActionModalSee(...) to check ->modalContent() output — modal content is lazily rendered and won't appear in a plain ->html()/->assertSee() snapshot even after mounting the action. See [[project_internachi_modular]]-style module layout in app-modules/ai-agent.
Custom-data table bulk actions: fetchSelectedRecords(false) still hydrates full rows
On a Table::records()-backed (non-Eloquent) page, BulkAction::make(...)->fetchSelectedRecords(false) does NOT skip hydration the way it does for an Eloquent table — the Collection $records passed to ->action() still contains full row arrays (keyed by the record key), not bare ids. Use $records->keys()->all() to get just the selected ids; $records->all()/$records->values() gives you full row data instead. See ManageSuggestions::deleteSelectedBulkAction() / ManageSuggestionMisses::promoteBulkAction().
Also: BnfexpressAdminClient's non-2xx handling (errorMessage()) must handle detail being a list of {msg, ...} objects, not just a string — FastAPI's own request-validation failures (422s) return detail in that shape, and casting it straight to (string) silently produces the literal "Array".
"Promote" on ManageSuggestionMisses now reuses the Create Many bulk-add modal
ManageSuggestionMisses::promoteBulkAction() no longer calls promoteSuggestionMisses() (miss-id based). It opens the same modal shape as ManageSuggestions::createManyAction() — info text + editable items_raw textarea + lang/intent — prefilled via fillForm(fn (Collection $records) => ...) (auto-injected selected records, works in fillForm the same way it does in a bulk ->action()) from the selected misses' own text_norm/lang. Submits through batchCreateSuggestions(), so edited/added lines in the textarea are honored — the created rows no longer map 1:1 to the original miss ids, and the original miss rows are NOT auto-dismissed by this path (unlike the old promote endpoint).
assertNotified() pulls (and clears) ALL queued notifications on its first call
Filament's Notification::assertNotified() reads via session()->pull('filament.notifications'), which empties the session key. Chaining ->assertNotified('A')->assertNotified('B') after one action fails on the second call even if both were actually sent — the first call already drained the queue. To check two notifications from one action, assert only one (whichever isn't covered by another test) rather than chaining. See ManageSuggestionMisses's promote-cleanup-failure test.