marshmallow / resource-progress
A Laravel Nova field.
Package info
github.com/marshmallow-packages/nova-resource-progress
pkg:composer/marshmallow/resource-progress
Requires
- php: ^8.3
- marshmallow/metadata: ^v1.2.0
Requires (Dev)
- laravel/nova: ^4.33.0|^5.0
This package is auto-updated.
Last update: 2026-06-11 15:53:14 UTC
README
Nova Resource Progress
A Laravel Nova field that visualises how "complete" a resource is. You define one or more suites of actions (checks) on your model, and the field renders a progress indicator per suite based on how many of those checks pass. Progress is recalculated automatically whenever a tracked model is created, updated or restored, and can be recalculated in bulk from Nova index actions.
Installation
Install the package via Composer:
composer require marshmallow/resource-progress
The package is auto-discovered through its FieldServiceProvider, so no manual
provider registration is required.
Optionally publish the config file:
php artisan vendor:publish --provider="Marshmallow\ResourceProgress\FieldServiceProvider"
Configuration
The published config/resource-progress.php exposes the following options:
| Key | Default | Description |
|---|---|---|
progress |
[\Marshmallow\ResourceProgress\Actions\FieldFilled::class] |
The default actions run for the progress suite. Add config keys named after other suites to give them default actions too. |
after_commit |
false |
When true, progress updates triggered by the model observer are dispatched after all database transactions have committed. |
Usage
1. Track a model
Add the TrackResourceProgress trait to any Eloquent model you want to track, and
declare one or more suites with the ResourceProgressSuite attribute. The attribute
is repeatable, so a model can have several suites.
use Marshmallow\ResourceProgress\Traits\TrackResourceProgress; use Marshmallow\ResourceProgress\Attributes\ResourceProgressSuite; #[ResourceProgressSuite(suite: 'progress', name: 'Progress')] #[ResourceProgressSuite(suite: 'publish', name: 'Publish', fields: ['name', 'intro'])] class Product extends Model { use TrackResourceProgress; }
The package registers a model observer for every model that uses the
TrackResourceProgress trait. Progress is recalculated on created, updated and
restored events and stored on the model's resource_progress attribute.
2. Define the checks for a suite
Each suite resolves its actions in this order:
- The actions configured under
config('resource-progress.{suite}'). - The actions returned by a
set{Suite}Actions()method on the model.
So to add checks to the publish suite, add a setPublishActions() method:
use Marshmallow\ResourceProgress\Actions\FieldFilled; public function setPublishActions(): array { return [ FieldFilled::class, ]; }
The built-in FieldFilled action checks that a list of fields is filled. It reads the
fields from the suite's fields argument, or — if present — from a
get{Suite}RequiredFields() method on the model:
public function getProgressRequiredFields(): array { return ['name', 'intro', 'description', 'supplier_id', 'product_category_id']; }
3. Add the field to your Nova resource
Add the field to your Nova resource's fields() method. It reads the suites declared
on the underlying model automatically:
use Marshmallow\ResourceProgress\ResourceProgress; ResourceProgress::make(__('Progress')),
The field has no editable value; it only displays progress. Its appearance can be tuned with the following fluent setters (defaults shown):
ResourceProgress::make(__('Progress')) ->setCircleSize(20) ->setStrokeWidth(3) ->setProgressBarHeight(15) ->setColorRanges([ 0 => '#ef4444', 50 => '#facc15', 100 => '#16a34a', ]);
setColorRanges() maps a percentage threshold to the colour used at or above it.
4. Recalculate progress in bulk (optional)
Two Nova actions are provided to recalculate progress from the index:
use Marshmallow\ResourceProgress\Nova\Actions\IndexResourceProgress; use Marshmallow\ResourceProgress\Nova\Actions\IndexResourcesProgress; public function actions(NovaRequest $request): array { return [ // Recalculate the selected resources immediately. IndexResourceProgress::make(), // Recalculate every record of the resource on the queue. IndexResourcesProgress::make(self::class)->standalone(), ]; }
IndexResourcesProgress queues an UpdateResourceProgressJob per record, so it is
suited to large tables.
Writing your own checks
Generate a custom action or suite with the included Artisan commands:
php artisan make:resource-progress-action MissingTranslationsAction php artisan make:resource-progress-suite SeoSuite
A custom action extends ResourceProgressAction and implements handle(). Call
incrementCheckCount() for every check performed and fail() (with a message) for
every check that does not pass:
use Marshmallow\ResourceProgress\Actions\ResourceProgressAction; use Marshmallow\ResourceProgress\Contracts\ResourceProgressSuiteInterface; class HasIntroAction extends ResourceProgressAction { public function handle(ResourceProgressSuiteInterface $suite): void { $this->incrementCheckCount(); if (! $this->resource->intro) { $this->fail(__('The intro is missing.')); } } }
Events
A Marshmallow\ResourceProgress\Events\ProgressUpdated event is dispatched each time
a suite's progress is recalculated. It carries the $model, the $suite and the full
$current_progress array, so you can listen for it to react to progress changes.
Credits
Security Vulnerabilities
Please report security vulnerabilities by email to security@marshmallow.dev rather than via the public issue tracker.
License
The MIT License (MIT). Please see the License File for more information.