From 0b78ea4d0333200e8d7140fb7e101798a72ffc47 Mon Sep 17 00:00:00 2001 From: Alexander Gabriel Date: Tue, 2 Jun 2026 15:46:00 +0000 Subject: [PATCH] groups and roles --- .../Resources/Groups/GroupResource.php | 50 +++++++++++++++++++ .../Resources/Groups/Pages/CreateGroup.php | 11 ++++ .../Resources/Groups/Pages/EditGroup.php | 19 +++++++ .../Resources/Groups/Pages/ListGroups.php | 19 +++++++ .../Resources/Groups/Schemas/GroupForm.php | 20 ++++++++ .../Resources/Groups/Tables/GroupsTable.php | 42 ++++++++++++++++ .../Resources/Users/Pages/ViewUser.php | 19 ------- .../Resources/Users/Schemas/UserForm.php | 20 +++++++- .../Resources/Users/Schemas/UserInfolist.php | 4 ++ .../Resources/Users/Tables/UsersTable.php | 8 ++- app/Filament/Resources/Users/UserResource.php | 2 - app/Models/Group.php | 17 +++++++ app/Models/Role.php | 17 +++++++ app/Models/User.php | 18 ++++++- app/Observers/OrderObserver.php | 3 +- app/Providers/AppServiceProvider.php | 4 ++ .../2026_06_02_135203_create_roles_table.php | 31 ++++++++++++ .../2026_06_02_135210_create_groups_table.php | 29 +++++++++++ ...6_06_02_135310_create_group_user_table.php | 31 ++++++++++++ ...26_06_02_135355_create_role_user_table.php | 31 ++++++++++++ ...2026_06_02_140729_migrate_ordermanager.php | 44 ++++++++++++++++ 21 files changed, 412 insertions(+), 27 deletions(-) create mode 100644 app/Filament/Resources/Groups/GroupResource.php create mode 100644 app/Filament/Resources/Groups/Pages/CreateGroup.php create mode 100644 app/Filament/Resources/Groups/Pages/EditGroup.php create mode 100644 app/Filament/Resources/Groups/Pages/ListGroups.php create mode 100644 app/Filament/Resources/Groups/Schemas/GroupForm.php create mode 100644 app/Filament/Resources/Groups/Tables/GroupsTable.php delete mode 100644 app/Filament/Resources/Users/Pages/ViewUser.php create mode 100644 app/Models/Group.php create mode 100644 app/Models/Role.php create mode 100644 database/migrations/2026_06_02_135203_create_roles_table.php create mode 100644 database/migrations/2026_06_02_135210_create_groups_table.php create mode 100644 database/migrations/2026_06_02_135310_create_group_user_table.php create mode 100644 database/migrations/2026_06_02_135355_create_role_user_table.php create mode 100644 database/migrations/2026_06_02_140729_migrate_ordermanager.php diff --git a/app/Filament/Resources/Groups/GroupResource.php b/app/Filament/Resources/Groups/GroupResource.php new file mode 100644 index 0000000..bb69985 --- /dev/null +++ b/app/Filament/Resources/Groups/GroupResource.php @@ -0,0 +1,50 @@ + ListGroups::route('/'), + 'create' => CreateGroup::route('/create'), + 'edit' => EditGroup::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/Groups/Pages/CreateGroup.php b/app/Filament/Resources/Groups/Pages/CreateGroup.php new file mode 100644 index 0000000..2ecdcfe --- /dev/null +++ b/app/Filament/Resources/Groups/Pages/CreateGroup.php @@ -0,0 +1,11 @@ +components([ + TextInput::make('name') + ->required(), + TextInput::make('description') + ->label('Beschreibung'), + ]); + } +} diff --git a/app/Filament/Resources/Groups/Tables/GroupsTable.php b/app/Filament/Resources/Groups/Tables/GroupsTable.php new file mode 100644 index 0000000..2ac1135 --- /dev/null +++ b/app/Filament/Resources/Groups/Tables/GroupsTable.php @@ -0,0 +1,42 @@ +columns([ + TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + TextColumn::make('updated_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + TextColumn::make('name') + ->searchable(), + TextColumn::make('description') + ->searchable(), + ]) + ->filters([ + // + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/Users/Pages/ViewUser.php b/app/Filament/Resources/Users/Pages/ViewUser.php deleted file mode 100644 index d793fc5..0000000 --- a/app/Filament/Resources/Users/Pages/ViewUser.php +++ /dev/null @@ -1,19 +0,0 @@ -email() ->required(), DateTimePicker::make('email_verified_at'), - Checkbox::make('ordermanager'), TextInput::make('password') ->password() - ->required(), + ->required() + ->visibleOn(['create']), + Select::make('roles') + ->relationship('roles', 'title') + ->label('Rollen') + ->preload() + ->multiple(), + Select::make('groups') + ->relationship('groups', 'name') + ->label('Gruppen') + ->preload() + ->createOptionForm(function(Schema $schema) { + return GroupForm::configure($schema); + }) + ->multiple(), ]); } } diff --git a/app/Filament/Resources/Users/Schemas/UserInfolist.php b/app/Filament/Resources/Users/Schemas/UserInfolist.php index b06c779..6e83c83 100644 --- a/app/Filament/Resources/Users/Schemas/UserInfolist.php +++ b/app/Filament/Resources/Users/Schemas/UserInfolist.php @@ -14,6 +14,10 @@ class UserInfolist TextEntry::make('name'), TextEntry::make('email') ->label('Email address'), + TextEntry::make('groups.title') + ->label('Gruppen'), + TextEntry::make('roles.title') + ->label('Rollen'), TextEntry::make('email_verified_at') ->dateTime() ->placeholder('-'), diff --git a/app/Filament/Resources/Users/Tables/UsersTable.php b/app/Filament/Resources/Users/Tables/UsersTable.php index 6ac8f45..0e8ec24 100644 --- a/app/Filament/Resources/Users/Tables/UsersTable.php +++ b/app/Filament/Resources/Users/Tables/UsersTable.php @@ -6,7 +6,6 @@ use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteBulkAction; use Filament\Actions\EditAction; use Filament\Actions\ViewAction; -use Filament\Tables\Columns\CheckboxColumn; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; @@ -24,7 +23,12 @@ class UsersTable TextColumn::make('email_verified_at') ->dateTime() ->sortable(), - CheckboxColumn::make('ordermanager'), + TextColumn::make('roles.title') + ->label("Rollen") + ->toggleable(), + TextColumn::make('groups.name') + ->label("Gruppen") + ->toggleable(), TextColumn::make('created_at') ->dateTime() ->sortable() diff --git a/app/Filament/Resources/Users/UserResource.php b/app/Filament/Resources/Users/UserResource.php index e21f085..f117325 100644 --- a/app/Filament/Resources/Users/UserResource.php +++ b/app/Filament/Resources/Users/UserResource.php @@ -5,7 +5,6 @@ namespace App\Filament\Resources\Users; use App\Filament\Resources\Users\Pages\CreateUser; use App\Filament\Resources\Users\Pages\EditUser; use App\Filament\Resources\Users\Pages\ListUsers; -use App\Filament\Resources\Users\Pages\ViewUser; use App\Filament\Resources\Users\Schemas\UserForm; use App\Filament\Resources\Users\Schemas\UserInfolist; use App\Filament\Resources\Users\Tables\UsersTable; @@ -54,7 +53,6 @@ class UserResource extends Resource return [ 'index' => ListUsers::route('/'), 'create' => CreateUser::route('/create'), - 'view' => ViewUser::route('/{record}'), 'edit' => EditUser::route('/{record}/edit'), ]; } diff --git a/app/Models/Group.php b/app/Models/Group.php new file mode 100644 index 0000000..1baec13 --- /dev/null +++ b/app/Models/Group.php @@ -0,0 +1,17 @@ +belongsToMany(User::class); + } + +} diff --git a/app/Models/Role.php b/app/Models/Role.php new file mode 100644 index 0000000..596b5b6 --- /dev/null +++ b/app/Models/Role.php @@ -0,0 +1,17 @@ +belongsToMany(User::class); + } + +} diff --git a/app/Models/User.php b/app/Models/User.php index 2ad6518..6ebeabe 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -10,10 +10,11 @@ use Database\Factories\UserFactory; use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Attributes\Hidden; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; -#[Fillable(['name', 'email', 'password', 'ordermanager'])] +#[Fillable(['name', 'email', 'password'])] #[Hidden(['password', 'remember_token'])] class User extends Authenticatable implements FilamentUser { @@ -37,4 +38,19 @@ class User extends Authenticatable implements FilamentUser 'password' => 'hashed', ]; } + + public function roles(): BelongsToMany + { + return $this->belongsToMany(Role::class); + } + + public function groups(): BelongsToMany + { + return $this->belongsToMany(Group::class); + } + + public function hasRole(string $role): bool + { + return in_array($role, $this->roles()->pluck('name')->toArray()); + } } diff --git a/app/Observers/OrderObserver.php b/app/Observers/OrderObserver.php index 50b0797..4022cc7 100644 --- a/app/Observers/OrderObserver.php +++ b/app/Observers/OrderObserver.php @@ -5,6 +5,7 @@ namespace App\Observers; use App\Mail\OrderArrived; use App\Mail\OrderRegistered; use App\Models\Order; +use App\Models\Role; use App\Models\User; use Illuminate\Support\Facades\Mail; use Illuminate\Support\Str; @@ -18,7 +19,7 @@ class OrderObserver { $order->public_uuid = (string) Str::uuid(); $order->save(); - $users = User::where("ordermanager", 1)->get(); + $users = Role::where("name", "ordermanager")->users()->get(); foreach ($users as $user) { Mail::to($user)->send(new OrderRegistered($order)); } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 7c1c613..2956912 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use Filament\Tables\Columns\Column; use Filament\Tables\Table; use Illuminate\Support\ServiceProvider; @@ -31,5 +32,8 @@ class AppServiceProvider extends ServiceProvider ->selectable() ->defaultPaginationPageOption(50); }); + Column::configureUsing(function (Column $column): void { + $column->toggleable(); + }); } } diff --git a/database/migrations/2026_06_02_135203_create_roles_table.php b/database/migrations/2026_06_02_135203_create_roles_table.php new file mode 100644 index 0000000..3044d40 --- /dev/null +++ b/database/migrations/2026_06_02_135203_create_roles_table.php @@ -0,0 +1,31 @@ +id(); + $table->timestamps(); + $table->string('name'); + $table->string('title'); + $table->string('description')->nullable(); + }); + + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('roles'); + } +}; diff --git a/database/migrations/2026_06_02_135210_create_groups_table.php b/database/migrations/2026_06_02_135210_create_groups_table.php new file mode 100644 index 0000000..9a6c75e --- /dev/null +++ b/database/migrations/2026_06_02_135210_create_groups_table.php @@ -0,0 +1,29 @@ +id(); + $table->timestamps(); + $table->string('name'); + $table->string('description')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('groups'); + } +}; diff --git a/database/migrations/2026_06_02_135310_create_group_user_table.php b/database/migrations/2026_06_02_135310_create_group_user_table.php new file mode 100644 index 0000000..2551f9c --- /dev/null +++ b/database/migrations/2026_06_02_135310_create_group_user_table.php @@ -0,0 +1,31 @@ +id(); + $table->timestamps(); + $table->foreignIdFor(User::class); + $table->foreignIdFor(Group::class); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('group_user'); + } +}; diff --git a/database/migrations/2026_06_02_135355_create_role_user_table.php b/database/migrations/2026_06_02_135355_create_role_user_table.php new file mode 100644 index 0000000..1ada21f --- /dev/null +++ b/database/migrations/2026_06_02_135355_create_role_user_table.php @@ -0,0 +1,31 @@ +id(); + $table->timestamps(); + $table->foreignIdFor(Role::class); + $table->foreignIdFor(User::class); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('role_user'); + } +}; diff --git a/database/migrations/2026_06_02_140729_migrate_ordermanager.php b/database/migrations/2026_06_02_140729_migrate_ordermanager.php new file mode 100644 index 0000000..f24c6ab --- /dev/null +++ b/database/migrations/2026_06_02_140729_migrate_ordermanager.php @@ -0,0 +1,44 @@ + "ordermanager", 'title' => 'Ordermanager', 'description' => 'Verwaltet Bestellungen'])->save(); + $users = User::all(); + foreach($users as $user) { + if($user->ordermanager) $user->roles()->attach($ordermanager); + } + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('ordermanager'); + }); + + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->boolean("ordermanager")->default(false); + }); + $users = User::all(); + foreach($users as $user) { + if($user->hasRole("ordermanager")) { + $user->ordermanager = 1; + $user->save(); + } + } + + } +};