Try approval in this demo
An import that needs approval is not written until someone else approves it. In this demo the demo user asks, and the Manager approves.
- Press “Import with approval” and import customers.csv. In the review, clear the errors next to Country and Rank with “Choose…”, then press “Request approval for … rows”.
- Choose “Act as the manager” in the user menu at the top right. You are now the Manager, and a notification asking for approval is waiting under the bell at the top right.
- Press “Review” in the notification, check what will change and press “Approve and import … rows” or “Send back…”. Switch back with “Act as the demo user” in the user menu: a notification with the result is waiting.
Who approves, how they are told, how they approve
An import that needs approval is not written until someone else approves it. This is who approves, how they find out and how they approve.
1. Choose who approves
Add ->requireApproval() to the import action. approvers: lists who can approve, and when: says who needs approval. The approvers are set by the developer in code, so the person importing never picks them on screen. The person who asks can never approve their own import, even if they are in the list.
use Qalainau\FilamentWarpImport\Actions\WarpImportAction;
WarpImportAction::make()
->importer(CustomerImporter::class)
->requireApproval(
// Who can approve: any users (a query, a collection or an array)
approvers: fn () => User::query()->where('role', 'manager')->get(),
// Who needs approval (default: everyone). Here managers import directly
when: fn (User $user): bool => $user->role !== 'manager',
),
2. Ask for approval
The person importing goes through the review as usual. The import button becomes “Request approval for … rows”, with an optional note for the approver. Once asked, nothing is written and the review becomes read only. “Withdraw request” takes it back so the rows can be edited again.
Clerk Check 42 rows
→ Request approval for 42 rows (note: "Prices for October")
→ Waiting for approval: nothing is written, the review is read only
→ Withdraw request (to edit the rows again)
3. Tell the approvers
Approvers get a Filament database notification (the bell at the top right). “Review” in the notification opens the review of that import. It is also listed as “Waiting for approval” in the import history, so a missed notification is not a lost import. The panel needs ->databaseNotifications() and the user model Laravel’s Notifiable. To also send an email or a Slack message, listen to ImportApprovalRequested, ImportApproved and ImportRejected.
// app/Providers/Filament/AdminPanelProvider.php: the bell at the top right
$panel->databaseNotifications();
// app/Models/User.php
class User extends Authenticatable
{
use Notifiable;
}
// Also by email or Slack: listen to the events (each has the ImportRun as $run)
use Qalainau\FilamentWarpImport\Events\ImportApprovalRequested;
use Qalainau\FilamentWarpImport\Events\ImportApproved;
use Qalainau\FilamentWarpImport\Events\ImportRejected;
Event::listen(ImportApprovalRequested::class, function (ImportApprovalRequested $event) {
Mail::to('managers@example.com')->send(new ImportWaitingForApproval($event->run));
});
4. Approve or send back
The approver sees the same review as the person who asked: the new rows, the changed rows (before and after) and the saved data that is not in the imported data. “Approve and import … rows” writes them, only then (through the queue for many rows). “Send back…” returns it with a reason. Approvers cannot change rows. Either way the person who asked is notified; a sent-back import shows the reason in the review, so they fix it and ask again. After importing, both can undo it.
Manager (bell) "Clerk asks you to approve an import" → Review
→ the same review: new rows, changes (before → after), records not in the data
→ Approve and import 42 rows → written; Clerk is notified
→ Send back… "The mug costs 900" → nothing written; Clerk is notified,
fixes the rows and asks again
5. In this demo
Only the Manager (manager@example.com) can approve “Import with approval” on Customers, and the Manager imports without approval. Switch between the demo user and the Manager in the user menu at the top right.
// app/Filament/Resources/Customers/Pages/ListCustomers.php
WarpImportAction::make('warpImportApproval')
->label('Import with approval')
->importer(CustomerImporter::class)
->requireApproval(
approvers: fn () => User::query()->where('email', 'manager@example.com')->get(),
when: fn (User $user): bool => $user->email !== 'manager@example.com',
),
Columns
| Phone | Country | Rank | |||
|---|---|---|---|---|---|
|
C0001
|
斉藤 晃
|
customer1@example.com
|
090-1335-0841
|
Japan
|
Silver
|
|
C0002
|
Tyreek Johns
|
customer2@example.com
|
+1-651-972-0065
|
Japan
|
Gold
|
|
C0003
|
Giles Fay
|
customer3@example.com
|
+1-254-721-6651
|
France
|
Gold
|
|
C0004
|
Dr. Chelsey Dietrich PhD
|
customer4@example.com
|
512-203-4733
|
United Kingdom
|
Regular
|
|
C0005
|
Norval Windler Jr.
|
customer5@example.com
|
283.216.6412
|
United Kingdom
|
Silver
|
|
C0006
|
Greyson Johnson
|
customer6@example.com
|
+19809463387
|
Canada
|
Gold
|
|
C0007
|
Aric Cole
|
customer7@example.com
|
484-682-4479
|
Australia
|
Gold
|
|
C0008
|
Vita Johnson
|
customer8@example.com
|
+1 (321) 681-9928
|
Germany
|
Silver
|
|
C0009
|
Cale Nader
|
customer9@example.com
|
+18043179595
|
France
|
Silver
|
|
C0010
|
Cleora Stiedemann
|
customer10@example.com
|
1-540-869-8409
|
United States
|
Regular
|