diff --git a/app/Data/Role/CreateRoleData.php b/app/Data/Role/CreateRoleData.php index b7dc0ca..3727e7a 100644 --- a/app/Data/Role/CreateRoleData.php +++ b/app/Data/Role/CreateRoleData.php @@ -10,5 +10,6 @@ final class CreateRoleData extends Data { public function __construct( public string $name, + public int $priority, ) {} } diff --git a/app/Data/Role/RoleData.php b/app/Data/Role/RoleData.php index 33e6a4f..7569917 100644 --- a/app/Data/Role/RoleData.php +++ b/app/Data/Role/RoleData.php @@ -13,6 +13,7 @@ final class RoleData extends Data public function __construct( public int $id, public string $name, + public int $priority = 0, #[DataCollectionOf(class: RoleAppData::class)] public ?DataCollection $apps = null, #[DataCollectionOf(class: RoleUserData::class)] diff --git a/app/Data/Role/UpdateRolePriorityData.php b/app/Data/Role/UpdateRolePriorityData.php new file mode 100644 index 0000000..91cd31f --- /dev/null +++ b/app/Data/Role/UpdateRolePriorityData.php @@ -0,0 +1,15 @@ + Role::query()->create([ 'name' => $data->name, + 'priority' => $data->priority, 'guard_name' => 'web', ])); @@ -93,8 +94,32 @@ public function getPermissionsGroupedByRole(array $roleIds): ?DataCollection $roles = Role::query() ->with('permissions:id,name') ->whereIn('id', $roleIds) - ->get(['id', 'name']); + ->get(['id', 'name', 'priority']); return RoleData::collect($roles, DataCollection::class); } + + /** + * Update the priority of a role. + * + * @throws InvalidArgumentException when roleId is invalid. + * @throws Throwable when an error occurs during the update. + */ + public function updatePriority(UpdateRolePriorityData $data): RoleData + { + if ($data->roleId <= 0) { + throw new InvalidArgumentException('Invalid role id'); + } + + $role = DB::transaction(function () use ($data) { + $role = Role::query()->findOrFail($data->roleId); + $role->update([ + 'priority' => $data->priority, + ]); + + return $role; + }); + + return RoleData::from($role); + } } diff --git a/database/migrations/2026_05_25_050110_add_priority_to_roles_table.php b/database/migrations/2026_05_25_050110_add_priority_to_roles_table.php new file mode 100644 index 0000000..9b0d5a3 --- /dev/null +++ b/database/migrations/2026_05_25_050110_add_priority_to_roles_table.php @@ -0,0 +1,24 @@ +unsignedInteger('priority')->default(100)->after('guard_name'); + }); + } + + public function down(): void + { + Schema::table('roles', function (Blueprint $table): void { + $table->dropColumn('priority'); + }); + } +}; diff --git a/resources/views/pages/access-manager/roles-and-apps/⚡index.blade.php b/resources/views/pages/access-manager/roles-and-apps/⚡index.blade.php index 21dc554..d5ebc9e 100644 --- a/resources/views/pages/access-manager/roles-and-apps/⚡index.blade.php +++ b/resources/views/pages/access-manager/roles-and-apps/⚡index.blade.php @@ -37,6 +37,7 @@ public function mount(): void { $this->headers = TableHeader::collect([ new TableHeader(key: 'name', label: 'Name'), + new TableHeader(key: 'priority', label: 'Priority'), new TableHeader(key: 'apps', label: 'Apps'), new TableHeader(key: 'users', label: 'Users'), ], DataCollection::class); @@ -85,7 +86,10 @@ public function save(): void $this->form->validate(); $this->attempt( action: function (): void { - $role = $this->roleService->create(new CreateRoleData(name: $this->form->name)); + $role = $this->roleService->create(new CreateRoleData( + name: $this->form->name, + priority: (int) $this->form->priority, + )); $this->appRoleService->assign(new AssignAppsToRoleData( roleId: $role->id, validUpto: $this->form->isUnlimited ? now()->addYears(15) : $this->form->validUpto, @@ -128,6 +132,10 @@ public function delete(int $roleId): void {{ $row->name }} @endscope + @scope('cell_priority', $row) + {{ $row->priority }} + @endscope + @scope('cell_apps', $row) @foreach($row->apps as $app) @php /** @var RoleAppData $app */ @endphp @@ -178,6 +186,14 @@ class="btn-sm btn-circle btn-error btn-soft" autofocus /> + + appRoleService = $appRoleService; + $this->roleService = $roleService; } public function mount(int $id): void @@ -62,6 +68,7 @@ public function mount(int $id): void $role = Role::query()->findOrFail($id); $this->roleId = $role->id; $this->roleName = $role->name; + $this->rolePriority = $role->priority; }, onError: function (): void { $this->redirectRoute('access-manager.roles-and-apps.index', navigate: true); @@ -253,6 +260,32 @@ public function detachUser(int $userId): void successMessage: 'User removed from role.', ); } + + public function openEditPriorityModal(): void + { + $this->newPriority = $this->rolePriority; + $this->resetErrorBag(); + $this->showEditPriorityModal = true; + } + + public function savePriority(): void + { + $this->validate([ + 'newPriority' => 'required|integer|min:0', + ]); + + $this->attempt( + action: function (): void { + $this->roleService->updatePriority(new UpdateRolePriorityData( + roleId: $this->roleId, + priority: (int) $this->newPriority, + )); + $this->rolePriority = (int) $this->newPriority; + $this->showEditPriorityModal = false; + }, + successMessage: 'Role priority updated successfully!', + ); + } }; ?> @@ -268,6 +301,16 @@ class="btn-sm btn-ghost" tooltip-right="Back To Roles & Apps" />

{{ $roleName }}

+
+ + +
@@ -440,4 +483,26 @@ class="toggle-secondary" + + + + + + + + Cancel + + + Save + + + +