import { FaChevronRight, FaChevronDown } from 'react-icons/fa' import Container from '@/components/shared/Container' import { Button, Checkbox, Dialog, Input, Menu, toast } from '@/components/ui' import { useConfig } from '@/components/ui/ConfigProvider' import Notification from '@/components/ui/Notification' import { GetPermissionListResultDto, PermissionGrantInfoDto, PermissionGroupDto, PermissionWithGroupName, PermissionWithStyle, } from '@/proxy/admin/models' import { getPermissions, getRoles, updatePermissions } from '@/services/identity.service' import { useStoreActions, useStoreState } from '@/store' import { useLocalization } from '@/utils/hooks/useLocalization' import { ChangeEvent, useEffect, useMemo, useState } from 'react' type OpenState = Record function RolesPermission({ open, onDialogClose, name, }: { open: boolean onDialogClose: () => void name: string }) { // Collapse/expand state const [openPermissions, setOpenPermissions] = useState({}) // Parent izinleri aç/kapat const togglePermission = (permName: string) => { setOpenPermissions((prev) => ({ ...prev, [permName]: !prev[permName] })) } // Parent izin mi? function isParent(permission: PermissionWithStyle) { return selectedGroupPermissions.some((p) => p.parentName === permission.name) } // Belirli parent'ın alt izinleri function getChildren(parentName: string) { if (!parentName) return [] return selectedGroupPermissions.filter((p) => p.parentName === parentName) } const providerName = 'R' const { translate } = useLocalization() const { getConfig } = useStoreActions((a) => a.abpConfig) const [isLoading, setIsLoading] = useState(false) const [permissionList, setPermissionList] = useState() const [selectedGroup, setSelectedGroup] = useState() const [selectedGroupPermissions, setSelectedGroupPermissions] = useState( [], ) const [searchTerm, setSearchTerm] = useState('') const mode = useStoreState((state) => state.theme.mode) const tenant = useStoreState((state) => state.auth.tenant) const { direction } = useConfig() const className = `m${direction[0]}-` const fetchDataPermissions = async () => { if (!name) return const response = await getPermissions(providerName, name) const data = response.data const tenantGroup = tenant?.menuGroup?.trim() if (!tenantGroup) { console.warn('Tenant menuGroup boş, tüm izinler gösterilecek') setPermissionList(data) return } const filteredGroups = data.groups .map((group: any) => { const filteredPermissions = group.permissions.filter((perm: any) => { if (!perm.menuGroup) return false const groups = typeof perm.menuGroup === 'string' ? perm.menuGroup.split('|').map((g: string) => g.trim()) : perm.menuGroup return groups.includes(tenantGroup) }) return { ...group, permissions: filteredPermissions } }) .filter((group: any) => group.permissions.length > 0) const filteredData = { ...data, groups: filteredGroups } setPermissionList(filteredData) } const changeGroup = (groupName?: string) => { const group = permissionList?.groups.find((a: any) => a.name === groupName) if (!group) { setSelectedGroup(undefined) setSelectedGroupPermissions([]) return } setSelectedGroup(group) const selectedGroupPerm = group.permissions.map( (permission: any) => ({ ...permission, class: className + findMargin(group.permissions, permission) * 4, }) as PermissionWithStyle, ) setSelectedGroupPermissions(selectedGroupPerm) } const onDialogOk = async () => { try { setIsLoading(true) if (permissionList?.groups && name) { const listPermissions = await getPermissions(providerName, name) const unChangedPermissions = getPermissionsWithGroupName(listPermissions.data?.groups) const changedPermissions = getPermissionsWithGroupName(permissionList.groups) const updatePermList = changedPermissions .filter( (per) => (unChangedPermissions.find((unChanged) => unChanged.name === per.name) || {}) .isGranted !== per.isGranted, ) .map(({ name, isGranted }) => ({ name, isGranted })) // 🔴 KRİTİK NOKTA await updatePermissions(providerName, name, { permissions: updatePermList, }) // ✅ artık backend kesin güncel await getConfig(false) toast.push(, { placement: 'top-end', }) } onDialogClose() } catch (err) { console.error(err) } finally { setIsLoading(false) } } // --- Expand/Collapse All fonksiyonları (tüm state ve yardımcı fonksiyonlardan sonra) --- const handleExpandAll = () => { const expanded: OpenState = {} function expandRecursively(perms: PermissionWithStyle[]) { perms.forEach((perm) => { if (isParent(perm)) { expanded[perm.name || ''] = true // Alt parent'ları da recursive aç const children = getChildren(perm.name || '') expandRecursively(children) } }) } // Tüm parent ve alt parent'ları recursive olarak aç expandRecursively(selectedGroupPermissions) setOpenPermissions(expanded) } const handleCollapseAll = () => { setOpenPermissions({}) } function getPermissionsWithGroupName(groups: PermissionGroupDto[]): PermissionWithGroupName[] { return groups.reduce( (acc, val) => [ ...acc, ...val.permissions.map((p: any) => ({ ...p, groupName: val.name || '', })), ], [] as PermissionWithGroupName[], ) } function findMargin( permissions: PermissionGrantInfoDto[], permission: PermissionGrantInfoDto, level = 0, ): number { const parentPermission = permissions.find((per) => per.name === permission.parentName) if (parentPermission) { return findMargin(permissions, parentPermission, level + 1) } else { return level } } const isAllSelected = useMemo( () => permissionList?.groups.every((group: any) => group.permissions.every((permission: any) => permission.isGranted), ), [permissionList], ) const isAllSelectedForGroup = useMemo( () => selectedGroupPermissions.every((permission) => permission.isGranted), [selectedGroupPermissions], ) // Collapse/expand için recursive düzende izinleri döndür const filteredPermissions = useMemo(() => { const lowerTerm = searchTerm.toLowerCase() // Filtreli veya tüm parent izinler const parents = selectedGroupPermissions.filter( (p) => !p.parentName && (searchTerm === '' || translate('::' + p.displayName) .toLowerCase() .includes(lowerTerm)), ) // Recursive children builder (her seviye için doğru level) function buildTree( parent: PermissionWithStyle, level: number, ): (PermissionWithStyle & { level: number })[] { const arr = [{ ...parent, level }] const parentKey = parent.name || '' if (openPermissions[parentKey] || searchTerm) { const children = getChildren(parentKey) children.forEach((child) => { arr.push(...buildTree(child, level + 1)) }) } return arr } // Tüm parentlar ve altlarını sırayla ekle let result: (PermissionWithStyle & { level: number })[] = [] parents.forEach((parent) => { result = result.concat(buildTree(parent, 0)) }) return result }, [selectedGroupPermissions, searchTerm, translate, openPermissions]) const onSelectAll = (value: boolean, e: ChangeEvent) => { if (!permissionList) { return } const currentGroupName = selectedGroup?.name setSelectedGroup(undefined) setSelectedGroupPermissions([]) if (e.target.name === 'group') { permissionList?.groups .find((group: any) => group.name === selectedGroup?.name) ?.permissions.forEach((permission: any) => { permission.isGranted = value }) } else { permissionList?.groups.forEach((group: any) => { group.permissions.forEach((permission: any) => { permission.isGranted = value }) }) } setPermissionList({ ...permissionList }) changeGroup(currentGroupName) } function onClickCheckbox(clickedPermission: PermissionGrantInfoDto) { if (!permissionList) { return } const groupPerm = selectedGroupPermissions.map((per) => { if (clickedPermission.name === per.name) { return { ...per, isGranted: !per.isGranted } } else if (clickedPermission.name === per.parentName && clickedPermission.isGranted) { return { ...per, isGranted: false } } else if (clickedPermission.parentName === per.name && !clickedPermission.isGranted) { return { ...per, isGranted: true } } return per }) const permGroup = permissionList?.groups.find((a: any) => a.name === selectedGroup?.name) if (permGroup) { permGroup.permissions = groupPerm } setPermissionList({ ...permissionList }) setSelectedGroupPermissions(groupPerm) } useEffect(() => { fetchDataPermissions() }, [name]) // --- Copy Permissions State and Logic --- const [roleList, setRoleList] = useState([]) // --- Copy Permissions Dialog State --- const [copyDialogOpen, setCopyDialogOpen] = useState(false) const [copyDialogRole, setCopyDialogRole] = useState('') // Fetch all roles for select (except current) useEffect(() => { async function fetchRoles() { try { const res = await getRoles() setRoleList(res.data.items?.map((r: any) => r.name) || []) } catch (e) { setRoleList([]) } } fetchRoles() }, [copyDialogOpen]) // Dialog üzerinden kopyalama işlemi const handleCopyDialogConfirm = async () => { if (!copyDialogRole || !permissionList) return setIsLoading(true) try { const res = await getPermissions(providerName, copyDialogRole) const sourcePerms = getPermissionsWithGroupName(res.data?.groups) const grantedNames = new Set(sourcePerms.filter((p) => p.isGranted).map((p) => p.name)) permissionList.groups.forEach((group) => { group.permissions.forEach((perm) => { perm.isGranted = grantedNames.has(perm.name) }) }) setPermissionList({ ...permissionList }) changeGroup(selectedGroup?.name) toast.push(, { placement: 'top-end', }) setCopyDialogOpen(false) setCopyDialogRole('') } catch (e) { toast.push(, { placement: 'top-end', }) } finally { setIsLoading(false) } } return permissionList ? ( changeGroup(permissionList?.groups[0].name)} onClose={onDialogClose} onRequestClose={onDialogClose} >
{translate('::Permission')} - {name}

{translate('AbpPermissionManagement::SelectAllInAllTabs')}
{translate('AbpPermissionManagement::SelectAllInThisTab')}

{permissionList?.groups.map((group: any) => ( {translate('::' + group.displayName)} ( {group.permissions.filter((a: any) => a.isGranted).length}) ))}

setSearchTerm(e.target.value)} />
{filteredPermissions.map((permission) => { const isParentPerm = isParent(permission) const permKey = permission.name || '' const children = getChildren(permKey) return (
{/* Expand Icon */} {isParentPerm ? ( ) : (
)} {/* Checkbox */} onClickCheckbox(permission)} > {translate('::' + permission.displayName)}
) })}
{/* Copy Permissions Dialog */} setCopyDialogOpen(false)} >
{translate('::AbpIdentity.Roles.CopyPermissions')}
) : ( <> ) } export default RolesPermission