Next up, each of our Customers has to go in a Pipeline to advance from one status to another. For example, we start at Contact Made and then progress to Meeting Scheduled. To do this, we need to create a new resource Pipeline Stages:

In this lesson, we will:
- Create
pipeline_stagesDB structure: Model/Migration and ahasManyrelationship tocustomers - Create Seeds with semi-real data without factories
- Create a Filament Resource for Pipeline Stages
- Auto-assign the new position to a new Pipeline Stage
- Make the table reorderable with the
positionfield - Add a Custom Action
Set Defaultwith confirmation - Add a
DeleteActionto the table with validation if that record is used - Add pipeline stage information to the Customer Resource table/form
Creating Pipeline Stages Database
These are the fields for our DB:
-
id -
name -
position- Order of the stages -
is_default
This will be seeded by default workflow but can be changed by admins to suit their needs.
Let's start with our migration:
Migration
Schema::create('pipeline_stages', function (Blueprint $table) { $table->id(); $table->string('name'); $table->integer('position'); $table->boolean('is_default')->default(false); $table->timestamps();});
Then, we need to create a model:
app/Models/PipelineStage.php
use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\Relations\HasMany; class PipelineStage extends Model{ protected $fillable = [ 'name', 'position', 'is_default', ]; public function customers(): HasMany { return $this->hasMany(Customer::class); }}
Next, we will make sure that we have some Default data in our database:
database/seeders/DatabaseSeeder.php
public function run(): void{ User::factory()->create([ 'name' => 'Test Admin', ]); Customer::factory() ->count(10) ->create(); $leadSources = [ 'Website', 'Online AD', 'Twitter', 'LinkedIn', 'Webinar', 'Trade Show', 'Referral', ]; foreach ($leadSources as $leadSource) { LeadSource::create(['name' => $leadSource]); } $tags = [ 'Priority', 'VIP' ]; foreach ($tags as $tag) { Tag::create(['name' => $tag]); } $pipelineStages = [ [ 'name' => 'Lead', 'position' => 1, 'is_default' => true, ], [ 'name' => 'Contact Made', 'position' => 2, ], [ 'name' => 'Proposal Made', 'position' => 3, ], [ 'name' => 'Proposal Rejected', 'position' => 4, ], [ 'name' => 'Customer', 'position' => 5, ] ]; foreach ($pipelineStages as $stage) { PipelineStage::create($stage); } $defaultPipelineStage = PipelineStage::where('is_default', true)->first()->id; Customer::factory()->count(10)->create([ 'pipeline_stage_id' => $defaultPipelineStage, ]);}
One thing to note here is that we have...
Hi, thanks for this great tutorial. I learn a lot! There is an alterantive to make the "set default" action that I think is a bit simpler:
This works also, but the column "Is default" in the table still shows te wrong icon. There must be a refresh after save. How will we do that?