permission group

This commit is contained in:
hamid zarghami
2026-07-20 15:10:30 +03:30
parent 70e159cefc
commit 2af7323a6a
6 changed files with 146 additions and 38 deletions
+26
View File
@@ -1,3 +1,29 @@
export enum PermissionGroupEnum {
SERVICES = "services",
CUSTOMERS = "customers",
USERS = "users",
FINANCIAL = "financial",
CONTENT = "content",
SUPPORT = "support",
OTHER = "other",
PRODUCTS = "products",
REPRESENTATIVES = "representatives",
TASK_MANAGER = "task_manager",
}
export const PERMISSION_GROUP_ORDER: PermissionGroupEnum[] = [
PermissionGroupEnum.SERVICES,
PermissionGroupEnum.CUSTOMERS,
PermissionGroupEnum.USERS,
PermissionGroupEnum.FINANCIAL,
PermissionGroupEnum.CONTENT,
PermissionGroupEnum.SUPPORT,
PermissionGroupEnum.OTHER,
PermissionGroupEnum.PRODUCTS,
PermissionGroupEnum.REPRESENTATIVES,
PermissionGroupEnum.TASK_MANAGER,
];
export enum PermissionEnum {
SERVICES_CREATE = "services_create",
SERVICES_READ = "services_read",
+12
View File
@@ -727,6 +727,18 @@
"submit_role": "ثبت نقش",
"title_role": "عنوان نقش",
"permissions": "دسترسی ها",
"permission_groups": {
"services": "سرویس‌ها",
"customers": "مشتریان",
"users": "کاربران",
"financial": "مالی",
"content": "محتوا",
"support": "پشتیبانی",
"other": "سایر",
"products": "محصولات",
"representatives": "نمایندگان",
"task_manager": "مدیریت وظایف"
},
"status_role": "وضعیت نقش",
"error_count_permission": "حداقل به دسترسی رو باید انتخاب کنید",
"is_admin": "آیا ادمین است؟",
+6 -19
View File
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'
import Button from '../../components/Button'
import { TickCircle } from 'iconsax-react'
import Input from '../../components/Input'
import CheckBoxComponent from '../../components/CheckBoxComponent'
import RolePermissionsSelector from './components/RolePermissionsSelector'
import { useCreateRole, useGetPermissions } from './hooks/useUserData'
import PageLoading from '../../components/PageLoading'
import { useFormik } from 'formik'
@@ -98,24 +98,11 @@ const RoleCreate: FC = () => {
{t('user.permissions')}
</div>
<div className='mt-5 text-sm flex flex-wrap gap-5'>
{
getPermissions.data?.data?.permissions?.map((item: { id: string, name: string }) => {
return (
<div key={item.id} className='flex flex-1 min-w-[23%] items-center'>
<CheckBoxComponent
checked={permissions.includes(item.id)}
onChange={() => handleAdd(item.id)}
/>
<div>{item.name}</div>
</div>
)
})
}
<div className='flex flex-1 min-w-[23%] items-center'></div>
<div className='flex flex-1 min-w-[23%] items-center'></div>
<div className='flex flex-1 min-w-[23%] items-center'></div>
</div>
<RolePermissionsSelector
permissions={getPermissions.data?.data?.permissions ?? []}
selectedIds={permissions}
onToggle={handleAdd}
/>
</div>
</div>
+6 -19
View File
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'
import Button from '../../components/Button'
import { TickCircle } from 'iconsax-react'
import Input from '../../components/Input'
import CheckBoxComponent from '../../components/CheckBoxComponent'
import RolePermissionsSelector from './components/RolePermissionsSelector'
import { useGetPermissions, useGetRoleDetail, useUpdateRole } from './hooks/useUserData'
import PageLoading from '../../components/PageLoading'
import { useFormik } from 'formik'
@@ -112,24 +112,11 @@ const RoleUpdate: FC = () => {
{t('user.permissions')}
</div>
<div className='mt-5 text-sm flex flex-wrap gap-5'>
{
getPermissions.data?.data?.permissions?.map((item: { id: string, name: string }) => {
return (
<div key={item.id} className='flex flex-1 min-w-[23%] items-center'>
<CheckBoxComponent
checked={permissions.includes(item.id)}
onChange={() => handleAdd(item.id)}
/>
<div>{item.name}</div>
</div>
)
})
}
<div className='flex flex-1 min-w-[23%] items-center'></div>
<div className='flex flex-1 min-w-[23%] items-center'></div>
<div className='flex flex-1 min-w-[23%] items-center'></div>
</div>
<RolePermissionsSelector
permissions={getPermissions.data?.data?.permissions ?? []}
selectedIds={permissions}
onToggle={handleAdd}
/>
</div>
</div>
@@ -0,0 +1,85 @@
import { FC, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import CheckBoxComponent from '../../../components/CheckBoxComponent'
import { PERMISSION_GROUP_ORDER } from '../../../helpers/permissions'
import { PermissionType } from '../types/UserTypes'
type Props = {
permissions: PermissionType[]
selectedIds: string[]
onToggle: (id: string) => void
}
const RolePermissionsSelector: FC<Props> = ({ permissions, selectedIds, onToggle }) => {
const { t } = useTranslation('global')
const [activeGroup, setActiveGroup] = useState<string>('')
const groupedPermissions = useMemo(() => {
const groups = new Map<string, PermissionType[]>()
PERMISSION_GROUP_ORDER.forEach((group) => {
groups.set(group, [])
})
permissions.forEach((permission) => {
const groupItems = groups.get(permission.group)
if (groupItems) {
groupItems.push(permission)
}
})
return PERMISSION_GROUP_ORDER
.map((group) => ({
group,
items: groups.get(group) ?? [],
}))
.filter(({ items }) => items.length > 0)
}, [permissions])
useEffect(() => {
if (groupedPermissions.length === 0) {
setActiveGroup('')
return
}
if (!groupedPermissions.some(({ group }) => group === activeGroup)) {
setActiveGroup(groupedPermissions[0].group)
}
}, [activeGroup, groupedPermissions])
const activeGroupPermissions = groupedPermissions.find(({ group }) => group === activeGroup)?.items ?? []
return (
<div className='mt-5'>
<div className='flex flex-wrap items-center gap-2 pb-2'>
{groupedPermissions.map(({ group }) => (
<button
key={group}
type='button'
className={`px-4 py-2 rounded-xl text-sm whitespace-nowrap border transition-all ${activeGroup === group
? 'bg-primary text-white border-primary'
: 'bg-white text-gray-700 border-gray-200'
}`}
onClick={() => setActiveGroup(group)}
>
{t(`user.permission_groups.${group}`)}
</button>
))}
</div>
<div className='mt-6 text-sm flex flex-wrap gap-5'>
{activeGroupPermissions.map((item) => (
<div key={item.id} className='flex flex-1 min-w-[23%] items-center'>
<CheckBoxComponent
checked={selectedIds.includes(item.id)}
onChange={() => onToggle(item.id)}
/>
<div>{item.title}</div>
</div>
))}
</div>
</div>
)
}
export default RolePermissionsSelector
+11
View File
@@ -1,3 +1,12 @@
import { PermissionGroupEnum } from "../../../helpers/permissions";
export type PermissionType = {
id: string;
name: string;
title: string;
group: PermissionGroupEnum;
};
export type CreateRoleType = {
name: string;
permissions: string[];
@@ -15,6 +24,8 @@ export type RoleItemType = {
export type RolePermissionType = {
id: string;
name: string;
title?: string;
group?: PermissionGroupEnum;
};
export type RoleDetailType = {