diff --git a/src/helpers/permissions.ts b/src/helpers/permissions.ts index f44a283..9e5d30c 100644 --- a/src/helpers/permissions.ts +++ b/src/helpers/permissions.ts @@ -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", diff --git a/src/langs/fa.json b/src/langs/fa.json index 9c11fac..e3f8897 100644 --- a/src/langs/fa.json +++ b/src/langs/fa.json @@ -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": "آیا ادمین است؟", diff --git a/src/pages/users/RoleCreate.tsx b/src/pages/users/RoleCreate.tsx index 2fd7491..73d0441 100644 --- a/src/pages/users/RoleCreate.tsx +++ b/src/pages/users/RoleCreate.tsx @@ -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')} -
- { - getPermissions.data?.data?.permissions?.map((item: { id: string, name: string }) => { - return ( -
- handleAdd(item.id)} - /> -
{item.name}
-
- ) - }) - } -
-
-
-
+ diff --git a/src/pages/users/RoleUpdate.tsx b/src/pages/users/RoleUpdate.tsx index c8414ec..522b859 100644 --- a/src/pages/users/RoleUpdate.tsx +++ b/src/pages/users/RoleUpdate.tsx @@ -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')} -
- { - getPermissions.data?.data?.permissions?.map((item: { id: string, name: string }) => { - return ( -
- handleAdd(item.id)} - /> -
{item.name}
-
- ) - }) - } -
-
-
-
+ diff --git a/src/pages/users/components/RolePermissionsSelector.tsx b/src/pages/users/components/RolePermissionsSelector.tsx new file mode 100644 index 0000000..ebfc4de --- /dev/null +++ b/src/pages/users/components/RolePermissionsSelector.tsx @@ -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 = ({ permissions, selectedIds, onToggle }) => { + const { t } = useTranslation('global') + const [activeGroup, setActiveGroup] = useState('') + + const groupedPermissions = useMemo(() => { + const groups = new Map() + + 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 ( +
+
+ {groupedPermissions.map(({ group }) => ( + + ))} +
+ +
+ {activeGroupPermissions.map((item) => ( +
+ onToggle(item.id)} + /> +
{item.title}
+
+ ))} +
+
+ ) +} + +export default RolePermissionsSelector diff --git a/src/pages/users/types/UserTypes.ts b/src/pages/users/types/UserTypes.ts index 9582ea7..56a0f60 100644 --- a/src/pages/users/types/UserTypes.ts +++ b/src/pages/users/types/UserTypes.ts @@ -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 = {