Skip to content

Commit 535ae71

Browse files
author
Hatim EL OUFIR
committed
Company CRUD
1 parent 01fb47f commit 535ae71

11 files changed

Lines changed: 520 additions & 1 deletion

File tree

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<?php
2+
3+
namespace App\Http\Livewire\Administration;
4+
5+
use App\Models\Company;
6+
use Filament\Tables\Actions\Action;
7+
use Filament\Tables\Columns\ImageColumn;
8+
use Filament\Tables\Columns\TextColumn;
9+
use Filament\Tables\Concerns\InteractsWithTable;
10+
use Filament\Tables\Contracts\HasTable;
11+
use Illuminate\Database\Eloquent\Builder;
12+
use Illuminate\Database\Eloquent\Relations\Relation;
13+
use Illuminate\Support\HtmlString;
14+
use Livewire\Component;
15+
16+
class Companies extends Component implements HasTable
17+
{
18+
use InteractsWithTable;
19+
20+
public $selectedCompany;
21+
22+
protected $listeners = ['companySaved', 'companyDeleted'];
23+
24+
public function render()
25+
{
26+
return view('livewire.administration.companies');
27+
}
28+
29+
/**
30+
* Table query definition
31+
*
32+
* @return Builder|Relation
33+
*/
34+
protected function getTableQuery(): Builder|Relation
35+
{
36+
return Company::query();
37+
}
38+
39+
/**
40+
* Table definition
41+
*
42+
* @return array
43+
*/
44+
protected function getTableColumns(): array
45+
{
46+
return [
47+
ImageColumn::make('logo')
48+
->label(__('Logo'))
49+
->height(30),
50+
51+
TextColumn::make('name')
52+
->label(__('Company name'))
53+
->searchable()
54+
->sortable(),
55+
56+
TextColumn::make('created_at')
57+
->label(__('Created at'))
58+
->sortable()
59+
->searchable()
60+
->dateTime(),
61+
];
62+
}
63+
64+
/**
65+
* Table actions definition
66+
*
67+
* @return array
68+
*/
69+
protected function getTableActions(): array
70+
{
71+
return [
72+
Action::make('edit')
73+
->icon('heroicon-o-pencil')
74+
->link()
75+
->label(__('Edit company'))
76+
->action(fn(Company $record) => $this->updateCompany($record->id))
77+
];
78+
}
79+
80+
/**
81+
* Table default sort column definition
82+
*
83+
* @return string|null
84+
*/
85+
protected function getDefaultTableSortColumn(): ?string
86+
{
87+
return 'created_at';
88+
}
89+
90+
/**
91+
* Table default sort direction definition
92+
*
93+
* @return string|null
94+
*/
95+
protected function getDefaultTableSortDirection(): ?string
96+
{
97+
return 'desc';
98+
}
99+
100+
/**
101+
* Show update company dialog
102+
*
103+
* @param $id
104+
* @return void
105+
*/
106+
public function updateCompany($id)
107+
{
108+
$this->selectedCompany = Company::find($id);
109+
$this->dispatchBrowserEvent('toggleCompanyModal');
110+
}
111+
112+
/**
113+
* Show create company dialog
114+
*
115+
* @return void
116+
*/
117+
public function createCompany()
118+
{
119+
$this->selectedCompany = new Company();
120+
$this->dispatchBrowserEvent('toggleCompanyModal');
121+
}
122+
123+
/**
124+
* Cancel and close company create / update dialog
125+
*
126+
* @return void
127+
*/
128+
public function cancelCompany()
129+
{
130+
$this->selectedCompany = null;
131+
$this->dispatchBrowserEvent('toggleCompanyModal');
132+
}
133+
134+
/**
135+
* Event launched after a company is created / updated
136+
*
137+
* @return void
138+
*/
139+
public function companySaved()
140+
{
141+
$this->cancelCompany();
142+
}
143+
144+
/**
145+
* Event launched after a company is deleted
146+
*
147+
* @return void
148+
*/
149+
public function companyDeleted()
150+
{
151+
$this->companySaved();
152+
}
153+
}
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
<?php
2+
3+
namespace App\Http\Livewire\Administration;
4+
5+
use App\Models\Icon;
6+
use App\Models\Company;
7+
use App\Models\User;
8+
use Filament\Forms\Components\ColorPicker;
9+
use Filament\Forms\Components\FileUpload;
10+
use Filament\Forms\Components\Grid;
11+
use Filament\Forms\Components\RichEditor;
12+
use Filament\Forms\Components\Select;
13+
use Filament\Forms\Components\TextInput;
14+
use Filament\Forms\Components\Toggle;
15+
use Filament\Forms\Concerns\InteractsWithForms;
16+
use Filament\Forms\Contracts\HasForms;
17+
use Filament\Notifications\Actions\Action;
18+
use Filament\Notifications\Notification;
19+
use Illuminate\Support\HtmlString;
20+
use Illuminate\Support\Str;
21+
use Illuminate\Validation\Rules\Unique;
22+
use Livewire\Component;
23+
use Livewire\WithFileUploads;
24+
25+
class CompaniesDialog extends Component implements HasForms
26+
{
27+
use WithFileUploads, InteractsWithForms;
28+
29+
public Company $company;
30+
public bool $deleteConfirmationOpened = false;
31+
32+
protected $listeners = ['doDeleteCompany', 'cancelDeleteCompany'];
33+
34+
public function mount(): void
35+
{
36+
$this->form->fill([
37+
'name' => $this->company->name,
38+
'logo' => $this->company->logo,
39+
'description' => $this->company->description,
40+
'is_disabled' => $this->company->is_disabled,
41+
'responsible_id' => $this->company->responsible_id,
42+
]);
43+
}
44+
45+
46+
public function render()
47+
{
48+
return view('livewire.administration.companies-dialog');
49+
}
50+
51+
/**
52+
* Form schema definition
53+
*
54+
* @return array
55+
*/
56+
protected function getFormSchema(): array
57+
{
58+
return [
59+
Grid::make()
60+
->schema([
61+
FileUpload::make('logo')
62+
->image()
63+
->maxSize(10240)
64+
->label(__('Logo')),
65+
]),
66+
67+
TextInput::make('name')
68+
->label(__('Company name'))
69+
->maxLength(255)
70+
->unique(table: Company::class, column: 'name', ignorable: fn () => $this->company, callback: function (Unique $rule) {
71+
return $rule->withoutTrashed();
72+
})
73+
->required(),
74+
75+
RichEditor::make('description')
76+
->label(__('Description'))
77+
->fileAttachmentsDisk(config('filesystems.default'))
78+
->fileAttachmentsDirectory('companies')
79+
->fileAttachmentsVisibility('private'),
80+
81+
Select::make('responsible_id')
82+
->label(__('Responsible'))
83+
->searchable()
84+
->required()
85+
->options(User::all()->pluck('name', 'id')->toArray()),
86+
87+
Toggle::make('is_disabled')
88+
->label(__('Disable access to this company'))
89+
];
90+
}
91+
92+
/**
93+
* Create / Update the company
94+
*
95+
* @return void
96+
*/
97+
public function save(): void
98+
{
99+
$data = $this->form->getState();
100+
if (!$this->company?->id) {
101+
$company = Company::create([
102+
'name' => $data['name'],
103+
'logo' => $data['logo'] ?? null,
104+
'description' => $data['description'] ?? null,
105+
'is_disabled' => $data['is_disabled'] ?? false,
106+
'responsible_id' => $data['responsible_id'],
107+
]);
108+
Notification::make()
109+
->success()
110+
->title(__('Company created'))
111+
->body(__('The company has been created'))
112+
->send();
113+
} else {
114+
$this->company->name = $data['name'];
115+
$this->company->description = $data['description'];
116+
$this->company->logo = $data['logo'];
117+
$this->company->is_disabled = $data['is_disabled'];
118+
$this->company->responsible_id = $data['responsible_id'];
119+
$this->company->save();
120+
Notification::make()
121+
->success()
122+
->title(__('Company updated'))
123+
->body(__("The company's details has been updated"))
124+
->send();
125+
}
126+
$this->emit('companySaved');
127+
}
128+
129+
/**
130+
* Delete an existing company
131+
*
132+
* @return void
133+
*/
134+
public function doDeleteCompany(): void
135+
{
136+
$this->company->delete();
137+
$this->deleteConfirmationOpened = false;
138+
$this->emit('companyDeleted');
139+
Notification::make()
140+
->success()
141+
->title(__('Company deleted'))
142+
->body(__('The company has been deleted'))
143+
->send();
144+
}
145+
146+
/**
147+
* Cancel the deletion of a company
148+
*
149+
* @return void
150+
*/
151+
public function cancelDeleteCompany(): void
152+
{
153+
$this->deleteConfirmationOpened = false;
154+
}
155+
156+
/**
157+
* Show the delete company confirmation dialog
158+
*
159+
* @return void
160+
* @throws \Exception
161+
*/
162+
public function deleteCompany(): void
163+
{
164+
$this->deleteConfirmationOpened = true;
165+
Notification::make()
166+
->warning()
167+
->title(__('Company deletion'))
168+
->body(__('Are you sure you want to delete this company?'))
169+
->actions([
170+
Action::make('confirm')
171+
->label(__('Confirm'))
172+
->color('danger')
173+
->button()
174+
->close()
175+
->emit('doDeleteCompany'),
176+
Action::make('cancel')
177+
->label(__('Cancel'))
178+
->close()
179+
->emit('cancelDeleteCompany')
180+
])
181+
->persistent()
182+
->send();
183+
}
184+
}

app/Models/Company.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Illuminate\Database\Eloquent\Factories\HasFactory;
6+
use Illuminate\Database\Eloquent\Model;
7+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
8+
use Illuminate\Database\Eloquent\SoftDeletes;
9+
10+
class Company extends Model
11+
{
12+
use HasFactory, SoftDeletes;
13+
14+
protected $fillable = [
15+
'name',
16+
'logo',
17+
'description',
18+
'is_disabled',
19+
'responsible_id'
20+
];
21+
22+
public function responsible(): BelongsTo
23+
{
24+
return $this->belongsTo(User::class, 'responsible_id');
25+
}
26+
}

0 commit comments

Comments
 (0)