From dce0f918efb9c774d868b03197d449309fd727b3 Mon Sep 17 00:00:00 2001 From: hossein taromi Date: Sun, 27 Jul 2025 14:45:01 +0330 Subject: [PATCH] feat(admin-users): enhance admin user management with permissions and roles - Add permissions and roles multi-select to admin user form - Update admin user models to include permissions and roles arrays - Make permissions list page read-only by removing CRUD actions - Integrate MultiSelectAutocomplete for better UX --- .../admin-user-form/AdminUserFormPage.tsx | 50 +++++++- src/pages/admin-users/core/_models.ts | 2 + .../permissions-list/PermissionsListPage.tsx | 108 +----------------- src/types/auth.ts | 4 + 4 files changed, 60 insertions(+), 104 deletions(-) diff --git a/src/pages/admin-users/admin-user-form/AdminUserFormPage.tsx b/src/pages/admin-users/admin-user-form/AdminUserFormPage.tsx index be11323..bc2c06c 100644 --- a/src/pages/admin-users/admin-user-form/AdminUserFormPage.tsx +++ b/src/pages/admin-users/admin-user-form/AdminUserFormPage.tsx @@ -5,9 +5,12 @@ import { yupResolver } from '@hookform/resolvers/yup'; import * as yup from 'yup'; import { useAdminUser, useCreateAdminUser, useUpdateAdminUser } from '../core/_hooks'; import { AdminUserFormData } from '../core/_models'; +import { usePermissions } from '../../permissions/core/_hooks'; +import { useRoles } from '../../roles/core/_hooks'; import { Button } from "@/components/ui/Button"; import { Input } from "@/components/ui/Input"; import { LoadingSpinner } from "@/components/ui/LoadingSpinner"; +import { MultiSelectAutocomplete, Option } from "@/components/ui/MultiSelectAutocomplete"; import { ArrowRight } from "lucide-react"; const adminUserSchema = yup.object({ @@ -22,6 +25,8 @@ const adminUserSchema = yup.object({ }) }), status: yup.string().required('وضعیت الزامی است').oneOf(['active', 'deactive'], 'وضعیت نامعتبر است'), + permissions: yup.array().of(yup.number()).default([]), + roles: yup.array().of(yup.number()).default([]), isEdit: yup.boolean().default(false) }); @@ -33,6 +38,9 @@ const AdminUserFormPage = () => { const { data: user, isLoading: isLoadingUser } = useAdminUser(id || '', isEdit); const { mutate: createUser, isPending: isCreating } = useCreateAdminUser(); const { mutate: updateUser, isPending: isUpdating } = useUpdateAdminUser(); + + const { data: permissions, isLoading: isLoadingPermissions } = usePermissions(); + const { data: roles, isLoading: isLoadingRoles } = useRoles(); const isLoading = isCreating || isUpdating; @@ -51,6 +59,8 @@ const AdminUserFormPage = () => { username: '', password: '', status: 'active' as 'active' | 'deactive', + permissions: [], + roles: [], isEdit: isEdit } }); @@ -69,6 +79,8 @@ const AdminUserFormPage = () => { setValue('last_name', user.last_name, { shouldValidate: true }); setValue('username', user.username, { shouldValidate: true }); setValue('status', user.status, { shouldValidate: true }); + setValue('permissions', user.permissions?.map(p => p.id) || [], { shouldValidate: true }); + setValue('roles', user.roles?.map(r => r.id) || [], { shouldValidate: true }); setValue('isEdit', true, { shouldValidate: true }); } }, [isEdit, user, setValue]); @@ -83,7 +95,9 @@ const AdminUserFormPage = () => { last_name: data.last_name, username: data.username, password: data.password && data.password.trim() ? data.password : undefined, - status: data.status + status: data.status, + permissions: data.permissions, + roles: data.roles } }, { onSuccess: () => { @@ -97,7 +111,9 @@ const AdminUserFormPage = () => { last_name: data.last_name, username: data.username, password: data.password || '', - status: data.status + status: data.status, + permissions: data.permissions, + roles: data.roles }, { onSuccess: (result) => { console.log('✅ Admin user created successfully:', result); @@ -178,6 +194,36 @@ const AdminUserFormPage = () => { placeholder={isEdit ? "رمز عبور جدید (در صورت تمایل به تغییر)" : "رمز عبور"} /> +
+ ({ + id: permission.id, + title: permission.title, + description: permission.description + }))} + selectedValues={watch('permissions') || []} + onChange={(values) => setValue('permissions', values, { shouldValidate: true })} + placeholder="انتخاب دسترسی‌ها..." + isLoading={isLoadingPermissions} + error={errors.permissions?.message} + /> + + ({ + id: role.id, + title: role.title, + description: role.description + }))} + selectedValues={watch('roles') || []} + onChange={(values) => setValue('roles', values, { shouldValidate: true })} + placeholder="انتخاب نقش‌ها..." + isLoading={isLoadingRoles} + error={errors.roles?.message} + /> +
+
{/* Filters */} @@ -213,24 +178,6 @@ const PermissionsListPage = () => { {new Date(permission.created_at).toLocaleDateString('fa-IR')} - -
- - -
- ))} @@ -252,59 +199,16 @@ const PermissionsListPage = () => {

-
+
تاریخ ایجاد: {new Date(permission.created_at).toLocaleDateString('fa-IR')}
-
- - -
))} )} - {/* Delete Confirmation Modal */} - setDeletePermissionId(null)} - title="حذف دسترسی" - > -
-

- آیا از حذف این دسترسی اطمینان دارید؟ این عمل قابل بازگشت نیست و ممکن است بر نقش‌هایی که از این دسترسی استفاده می‌کنند تأثیر بگذارد. -

-
- - -
-
-
+ ); }; diff --git a/src/types/auth.ts b/src/types/auth.ts index ab6944c..8600f8c 100644 --- a/src/types/auth.ts +++ b/src/types/auth.ts @@ -45,6 +45,8 @@ export interface CreateAdminUserRequest { username: string; password: string; status: string; + permissions?: number[]; + roles?: number[]; } export interface UpdateAdminUserRequest { @@ -54,6 +56,8 @@ export interface UpdateAdminUserRequest { username: string; password?: string; status: string; + permissions?: number[]; + roles?: number[]; } export interface AdminUsersListResponse {