Download the PHP package coringawc/filament-action-approvals without Composer
On this page you can find all versions of the php package coringawc/filament-action-approvals. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download coringawc/filament-action-approvals
More information about coringawc/filament-action-approvals
Files in coringawc/filament-action-approvals
Package filament-action-approvals
Short Description Action-based approval flows for Filament with spatie/laravel-model-states integration.
License MIT
Homepage https://github.com/CoringaWc/filament-action-approvals
Informations about the package filament-action-approvals
Filament Action Approvals
Action-based approval workflows for Filament v5. Define multi-step approval flows with configurable approver resolvers, SLA enforcement, delegation, and lifecycle callbacks — all integrated into the Filament admin panel.
Features
- Multi-step approval flows — sequential steps with configurable approver resolution
- Polymorphic — any Eloquent model can be approvable via the
HasApprovalstrait - Pluggable approver resolvers —
UserResolver,RoleResolver,CustomRuleResolver, or create your own - Approvable actions — define domain-specific actions (submit, cancel, etc.) on your model, each with its own approval flow
- Native operation interception — opt in to intercept Filament
EditActionandDeleteActionwithApprovalOperationmetadata when a matching flow exists - Per-action submit buttons — create dedicated
SubmitForApprovalActioninstances locked to a specificactionKey - Delegation — approvers can delegate their step to another user
- SLA enforcement — per-step SLA deadlines with warning notifications and configurable escalation (notify, auto-approve, reject, reassign)
- Lifecycle callbacks — hook into
onApprovalSubmitted,onApprovalApproved,onApprovalRejected, etc. directly on your model - Resubmission policy — control whether models can be resubmitted after approval/rejection
- User display name — uses Filament's
getFilamentName()when available, falls back tonameattribute - Built-in Filament components:
ApprovalFlowResource— UI for managing approval flow definitionsApprovalResource— operational approvals listing with status tabs, filters, overview stats, and slide-over detail viewListApprovalsAction— contextual action that opens a slide-over table for approvals scoped to a model or recordApprovalsDashboard— opt-in global dashboard with period filters and operational widgetsApprovalsRelationManager— shows approval history with slide-over detailsApprovalStatusColumn— ready-to-use status badge columnApprovalStatusSection— infolist section with approval details and timeline- Grouped approval actions: Submit, Approve, Reject, Comment, Delegate (usable individually or through the
Aprovaçõesdropdown) - Widgets: Pending Approvals, Approval Analytics
- Multi-tenancy support — scope flows and approvers per tenant
- Event-driven — fires events for submitted, completed, rejected, step-completed, and escalated
- Notification system — notifies approvers, submitters, and escalation targets
- ACL integration — optional integration with
coringawc/filament-aclfor permission-aware resources
Requirements
- PHP 8.3+
- Laravel 12+
- Filament 5.x
Optional
coringawc/filament-acl^1.0 — enablesHasResourcePermissionsandPermissionSubjectintegrationspatie/laravel-permission^7.0 — required forRoleResolver
Installation
Publish and run the migrations:
Optionally publish the config file:
Configuration
The config file (config/filament-action-approvals.php) contains:
Plugin Registration
Register the plugin in your Filament panel provider:
Plugin Methods
| Method | Description |
|---|---|
flowResource(bool $enabled = true) |
Enable/disable the built-in ApprovalFlow resource |
approvalResource(bool $enabled = true) |
Enable/disable the built-in ApprovalResource |
dashboard(bool $enabled = true) |
Enable/disable the opt-in ApprovalsDashboard page |
widgets(bool $enabled = true) |
Enable/disable PendingApprovals and Analytics widgets |
interceptOperations(bool $enabled = true) |
Intercept native Edit/Delete operations when a flow exists |
operationModalCallout(bool $enabled = true) |
Enable/disable the automatic approval request callout in intercepted operation modals |
resolvers(array $resolvers) |
Override approver resolvers for this panel |
userModel(string $model) |
Override the user model for this panel |
navigationGroup(string $group) |
Override the navigation group label |
configureContextualApprovalsTableUsing(Closure $callback) |
Customize the contextual approvals table for the current panel |
scopeContextualApprovalsUsing(Closure $callback) |
Apply a current-panel query scope to contextual approval history |
If the dedicated ApprovalsDashboard page is enabled, global panel widgets are suppressed by default so the package dashboard stays independent from the panel's primary dashboard. Call ->widgets() explicitly if you want both.
Contextual approvals navigation
Use ListApprovalsAction when you want to open a slide-over table already scoped to a model type or a specific record:
For relation managers or nested contexts, pass the owner record instead:
The action opens a slide-over containing the approvals table already filtered to the relevant model or record. Use it on resource list pages or on headers of relation managers/nested resources that belong to an approvable model. Do not add it to ApprovalsRelationManager itself.
By default, ListApprovalsAction is hidden until the current panel user can approve or reject at least one pending approval in the scoped context. Use hideWhenNoActionableApprovals(false) when the trigger should stay visible as a history-only entry point:
The slide-over uses the package ContextualApprovalsTable by default. The widget keeps a single status filter defaulted to pending and explicit pagination page sizes, while your panel may still customize the underlying table columns/actions or apply an application-specific visible-history query scope:
Dashboard opt-in
ApprovalsDashboard is disabled by default. Enable it explicitly when your panel needs a global operational view:
The dashboard includes quick period actions (5d, 15d, 30d, All), an advanced filter slideover, status distribution, bottleneck visibility, stale pending approvals, and filtered analytics.
When this dedicated dashboard is enabled, the package no longer injects its global widgets into the panel's main dashboard unless you opt in with ->widgets().
Usage
1. Make Your Model Approvable
Add the HasApprovals trait to any Eloquent model:
2. Define Approvable Actions (Optional)
If your model has multiple domain actions that require approval (e.g., submit, cancel, reimburse), define them via approvableActions():
When approvableActions() is defined, the SubmitForApprovalAction will show a selector for the user to pick which action they are requesting. You can also create dedicated buttons per action — see Per-Action Submit Buttons.
Native Operation Interception
Enable interceptOperations() on the panel and declare model operations with ApprovableOperation. When a matching active flow exists, native Filament EditAction and DeleteAction submit an approval request instead of mutating the record. If no flow exists, the native action continues normally.
By default, intercepted operation modals show a Filament schema Callout explaining that the change will be submitted for approval. Disable it for a panel with ->operationModalCallout(false) or globally with operations.modal_callout => false when your action schema already contains contextual approval copy.
The interceptor runs before Filament persists relationship-backed form components, so native relationship() layouts and repeaters will not write related records while an approval request is being created. The default operation payload is intentionally simple and dirty-only for owner model fields declared in fields; if you need relationship payloads, override the model operation payload/apply methods and keep that metadata explicitly scoped.
New approval metadata uses operation.name, operation.fields, payload, and payload_diff. Update payloads are dirty-only and restricted to the declared fields allowlist.
3. Create an Approval Flow
Approval flows can be created via the admin panel UI (ApprovalFlow resource) or programmatically:
4. Add Approval Actions to Your Resource
Option A: All actions at once (quickstart)
Use the HasApprovalsResource trait to add the grouped approval menu as header actions:
The default grouped trigger uses the vertical ellipsis icon and the Aprovações label so it can be reused consistently in resource headers and in approval detail infolists.
Option B: Individual actions (fine-grained control)
Use each action individually when you need to customize visibility, labels, or only show specific actions:
Each action manages its own visibility automatically:
| Action | Visible When |
|---|---|
SubmitForApprovalAction |
Record can be submitted for the current action context (no pending approval, flows exist, model policy allows it) |
ApproveAction |
User is an assigned approver and hasn't acted yet |
RejectAction |
User is an assigned approver and hasn't acted yet |
CommentAction |
A pending approval exists and user can act on it |
DelegateAction |
User is an assigned approver (original, not delegate) |
Per-Action Submit Buttons
When your model defines approvableActions(), you can create dedicated submit buttons for each action using actionKey():
When actionKey() is set:
- The action key selector modal is skipped entirely
- The action is only visible when there are matching flows for that specific
actionKey - If there's exactly one matching flow, submission happens with just a confirmation dialog (no form)
- If there are multiple matching flows, only the flow selector is shown (without the action selector)
This gives you full control to place specific approval submission buttons anywhere in your UI — in the header, in a custom action group, or even as table row actions.
5. Add the Relation Manager
Add the ApprovalsRelationManager to show approval history on any resource:
The relation manager shows a table of all approvals for the record. Each row has a "View" action that opens a slide-over with:
- Approval details (flow, status, submitter, dates)
- Grouped approval actions at the top of the infolist when the current user can act
- Step-by-step progress with approver names and received/required counts
- Full audit trail (submitted, approved, rejected, commented, delegated, escalated)
6. Add the Status Column
Show the latest approval status in any table:
7. Add the Status Section to Infolists (Optional)
Use ApprovalStatusSection to display approval details inline on a View or Edit page. This is an alternative to the relation manager — useful when you want the approval details embedded directly in the page's infolist rather than in a separate tab or slide-over.
Note: When using
ApprovalsRelationManager, theApprovalStatusSectionmay be redundant since the RM's slide-over already shows full approval details.
8. Programmatic Usage
Interact with the approval engine directly:
User Display Names
The package uses UserDisplayName::resolve() to display user names throughout the UI (infolists, columns, selects, audit trail). The resolution order is:
- If the user model implements
Filament\Models\Contracts\HasName, callsgetFilamentName() - Falls back to the
nameattribute
This means if your User model uses Filament's HasName interface (which provides getFilamentName()), the package will automatically use the display name defined there (e.g., full name, username, or any custom format).
Approver Resolvers
UserResolver
Resolves specific user IDs as approvers:
RoleResolver
Resolves all users with a given role (requires spatie/laravel-permission):
CustomRuleResolver
Define model-scoped custom rules directly on your model via approvalCustomRules():
Use in a step:
The resolver is only available in the flow builder when the selected model defines approvalCustomRules(). Each key becomes a selectable option.
Custom Resolver
Implement the ApproverResolver contract:
Register it in the config or plugin:
Lifecycle Callbacks
Override these methods on your model to react to approval events:
| Method | Called When |
|---|---|
onApprovalSubmitted(Approval $approval) |
Model is submitted for approval |
onApprovalApproved(Approval $approval) |
All steps approved (approval complete) |
onApprovalRejected(Approval $approval) |
Approval rejected at any step |
onApprovalCancelled(Approval $approval) |
Approval is cancelled |
onApprovalCommented(ApprovalAction $action) |
Comment added |
onApprovalDelegated(ApprovalStepInstance $si, $from, $to) |
Step delegated |
onApprovalStepCompleted(ApprovalStepInstance $si) |
Individual step approved |
onApprovalEscalated(ApprovalStepInstance $si) |
SLA breach triggers escalation |
Resubmission Policy
Control whether a model can be resubmitted after a completed approval:
When you need different submit policies per approvable action, inspect the first parameter:
If you do not override canSubmitForApproval(), the package default allows submission only for users resolved as approvers in a matching approval flow.
If you do not override allowsApprovalResubmission(), the package default blocks a new submission after the latest approval ends as approved or cancelled, while still allowing retries after rejected.
SLA Enforcement
Configure per-step SLA deadlines:
Escalation Actions
| Action | Behavior |
|---|---|
Notify |
Sends an ApprovalEscalatedNotification |
AutoApprove |
Automatically approves the overdue step |
Reject |
Automatically rejects the approval |
Reassign |
Reassigns to new approvers using the step's resolver |
The SLA processor runs via the approval:process-sla command, automatically scheduled every minute when schedule_sla_command is true.
Events
| Event | Payload |
|---|---|
ApprovalSubmitted |
Approval $approval |
ApprovalCompleted |
Approval $approval |
ApprovalRejected |
Approval $approval |
ApprovalCancelled |
Approval $approval |
ApprovalCommented |
ApprovalAction $action |
ApprovalDelegated |
ApprovalStepInstance $stepInstance, int $fromUserId, int $toUserId |
ApprovalStepCompleted |
ApprovalStepInstance $stepInstance |
ApprovalEscalated |
ApprovalStepInstance $stepInstance |
Broadcasting
All events implement ShouldBroadcast but are disabled by default. Enable per-event broadcasting via config:
Events broadcast on the approval-events channel. The BroadcastsConditionally trait provides broadcastWhen() that checks the per-event config — zero overhead when disabled.
Super Admin Bypass
When enabled, super admins can see and act on all approval actions (Approve, Reject, Comment, Delegate) regardless of being an assigned approver:
Check programmatically:
When spatie/laravel-permission is not installed, only user_ids matching works. Role-based matching requires the package.
Enum-Based Approvable Actions
Instead of returning a plain array from approvableActions(), you can use a backed enum with HasLabel:
Then configure on your model using the #[ApprovableActions] attribute:
PHP 8.4 safety: The
#[ApprovableActions]attribute replaces the old$approvableActionsEnumproperty approach. PHP 8.4 fatals on trait property redefinition with different default values. Attributes are on the class, not the trait, avoiding this issue.
When an enum is configured, approvableActions() resolves labels from getLabel() automatically. You can also extract icon/color per action key:
Resource Customization
Customize the built-in ApprovalFlowResource appearance via config:
Multi-Tenancy
Enable tenant-scoped approval flows:
When enabled, ApprovalFlow::forModel() automatically scopes queries by the model's tenant column.
Database Schema
The package creates the following tables:
| Table | Purpose |
|---|---|
approval_flows |
Flow definitions (name, approvable_type, action_key, active status) |
approval_steps |
Step definitions within a flow (order, resolver, SLA, escalation) |
approvals |
Runtime approval instances (polymorphic to approvable model) |
approval_step_instances |
Runtime step instances (status, assigned approvers, SLA tracking) |
approval_actions |
Audit trail of all actions (submit, approve, reject, comment, delegate, escalate) |
approval_delegations |
Delegation records (from_user to_user per step instance) |
Integration with filament-acl (Optional)
If you use coringawc/filament-acl, you can extend the built-in ApprovalFlowResource to add permission-aware access control:
Create a custom resource that extends the package resource:
Then disable the built-in resource on the plugin and register your own:
Translations
The package uses filament-action-approvals::approval.* keys for all user-facing strings. Translation files are in resources/lang/{locale}/approval.php.
Key groups:
| Group | Description |
|---|---|
status.* |
Approval status labels (pending, approved, etc.) |
action_type.* |
Action type labels (submitted, approved, etc.) |
step_type.* |
Step type labels (single, sequential, parallel) |
step_status.* |
Step instance status labels |
escalation.* |
Escalation action labels |
actions.* |
UI action button labels and messages |
To publish translations for customization:
Testing
The package includes a workbench environment for development and testing:
Changelog
Please see CHANGELOG for more information on what has changed recently.
License
The MIT License (MIT). Please see License File for more information.