Skip to content

Commit

Permalink
Pipeline Stages Resource: Reorderable
Browse files Browse the repository at this point in the history
  • Loading branch information
tqt97 committed Oct 15, 2023
1 parent c226770 commit d2ad402
Show file tree
Hide file tree
Showing 10 changed files with 284 additions and 10 deletions.
9 changes: 9 additions & 0 deletions app/Filament/Resources/CustomerResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Filament\Resources\CustomerResource\Pages;
use App\Filament\Resources\CustomerResource\RelationManagers;
use App\Models\Customer;
use App\Models\PipelineStage;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
Expand Down Expand Up @@ -41,6 +42,13 @@ public static function form(Form $form): Form
->relationship('tags', 'name')
->preload()
->multiple(),
Forms\Components\Select::make('pipeline_stage_id')
->relationship('pipelineStage', 'name', function ($query) {
// It is important to order by position to display the correct order
$query->orderBy('position', 'asc');
})
// We are setting the default value to the default Pipeline Stage
->default(PipelineStage::where('is_default', true)->first()?->id),
]);
}

Expand All @@ -62,6 +70,7 @@ public static function table(Table $table): Table
Tables\Columns\TextColumn::make('phone_number')
->searchable(),
Tables\Columns\TextColumn::make('leadSource.name'),
Tables\Columns\TextColumn::make('pipelineStage.name'),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
Expand Down
114 changes: 114 additions & 0 deletions app/Filament/Resources/PipelineStageResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?php

namespace App\Filament\Resources;

use App\Filament\Resources\PipelineStageResource\Pages;
use App\Filament\Resources\PipelineStageResource\RelationManagers;
use App\Models\PipelineStage;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;

class PipelineStageResource extends Resource
{
protected static ?string $model = PipelineStage::class;

protected static ?string $navigationGroup = 'Settings';

public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')
->required()
->maxLength(255),
]);
}

public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name')
->searchable(),
Tables\Columns\IconColumn::make('is_default')
->boolean(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->defaultSort('position')
->reorderable('position')
->filters([
//
])
->actions([
Tables\Actions\Action::make('Set Default')
->icon('heroicon-o-star')
->hidden(fn ($record) => $record->is_default)
->requiresConfirmation(function (Tables\Actions\Action $action, $record) {
$action->modalDescription('Are you sure you want to set this as the default pipeline stage?');
$action->modalHeading('Set "' . $record->name . '" as Default');

return $action;
})
->action(function (PipelineStage $record) {
PipelineStage::where('is_default', true)->update(['is_default' => false]);

$record->is_default = true;
$record->save();
}),
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make()
->action(function ($data, $record) {
if ($record->customers()->count() > 0) {
Notification::make()
->danger()
->title('Pipeline Stage is in use')
->body('Pipeline Stage is in use by customers.')
->send();

return;
}

Notification::make()
->success()
->title('Pipeline Stage deleted')
->body('Pipeline Stage has been deleted.')
->send();

$record->delete();
})
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}

public static function getRelations(): array
{
return [
//
];
}

public static function getPages(): array
{
return [
'index' => Pages\ListPipelineStages::route('/'),
'create' => Pages\CreatePipelineStage::route('/create'),
'edit' => Pages\EditPipelineStage::route('/{record}/edit'),
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Filament\Resources\PipelineStageResource\Pages;

use App\Filament\Resources\PipelineStageResource;
use App\Models\PipelineStage;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;

class CreatePipelineStage extends CreateRecord
{
protected static string $resource = PipelineStageResource::class;

protected function mutateFormDataBeforeCreate(array $data): array
{
$data['position'] = PipelineStage::max('position') + 1;

return $data;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Filament\Resources\PipelineStageResource\Pages;

use App\Filament\Resources\PipelineStageResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;

class EditPipelineStage extends EditRecord
{
protected static string $resource = PipelineStageResource::class;

protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Filament\Resources\PipelineStageResource\Pages;

use App\Filament\Resources\PipelineStageResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;

class ListPipelineStages extends ListRecords
{
protected static string $resource = PipelineStageResource::class;

protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}
8 changes: 7 additions & 1 deletion app/Models/Customer.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ class Customer extends Model
'email',
'phone_number',
'description',
'lead_source_id'
'lead_source_id',
'pipeline_stage_id'
];

public function leadSource(): BelongsTo
Expand All @@ -30,4 +31,9 @@ public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class);
}

public function pipelineStage(): BelongsTo
{
return $this->belongsTo(PipelineStage::class);
}
}
23 changes: 23 additions & 0 deletions app/Models/PipelineStage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class PipelineStage extends Model
{
use HasFactory;

protected $fillable = [
'name',
'position',
'is_default',
];

public function customers(): HasMany
{
return $this->hasMany(Customer::class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('pipeline_stages', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->integer('position');
$table->boolean('is_default')->default(false);
$table->timestamps();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('pipeline_stages');
}
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use App\Models\LeadSource;
use App\Models\PipelineStage;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Expand All @@ -20,6 +21,7 @@ public function up(): void
$table->string('phone_number')->nullable();
$table->text('description')->nullable();
$table->foreignIdFor(LeadSource::class)->nullable()->constrained();
$table->foreignIdFor(PipelineStage::class)->nullable()->constrained();
$table->timestamps();
$table->softDeletes();

Expand Down
50 changes: 41 additions & 9 deletions database/seeders/DatabaseSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use App\Models\Customer;
use App\Models\LeadSource;
use App\Models\PipelineStage;
use App\Models\Tag;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;

Expand All @@ -15,14 +20,12 @@ public function run(): void
{
// \App\Models\User::factory(10)->create();

\App\Models\User::factory()->create([
User::factory()->create([
'name' => 'tuantq',
'email' => '[email protected]',
'password' => Hash::make('12341234'),
]);



$leadSources = [
'Website',
'Online AD',
Expand All @@ -33,20 +36,49 @@ public function run(): void
'Referral',
];
foreach ($leadSources as $leadSource) {
\App\Models\LeadSource::create(['name' => $leadSource]);
LeadSource::create(['name' => $leadSource]);
}

\App\Models\Customer::factory()
->count(10)
->create();

$tags = [
'Priority',
'VIP'
];

foreach ($tags as $tag) {
\App\Models\Tag::create(['name' => $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,
]);
}
}

0 comments on commit d2ad402

Please sign in to comment.