mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-07 08:25:43 +00:00
71 lines
2.0 KiB
TypeScript
71 lines
2.0 KiB
TypeScript
import React from "react";
|
|
|
|
type NavItemProps = {
|
|
to?: string;
|
|
children?: React.ReactNode;
|
|
[key: string]: any;
|
|
};
|
|
|
|
/**
|
|
* Filters navigation items based on user's roles & dynamic permission config.
|
|
*/
|
|
export const filterNavLinksByRole = (
|
|
navItems: React.ReactNode,
|
|
userRoles?: string[],
|
|
permissions?: Record<string, string[]>
|
|
): React.ReactNode => {
|
|
if (!userRoles || userRoles.length === 0) return null;
|
|
|
|
if (userRoles.includes("super_admin")) return navItems;
|
|
|
|
const filteredItems = React.Children.map(navItems, (item) => {
|
|
if (!React.isValidElement<NavItemProps>(item)) return null;
|
|
|
|
const props = item.props as NavItemProps;
|
|
const path = props.to;
|
|
const children = props.children;
|
|
|
|
if (children) {
|
|
const filteredChildren = React.Children.map(children, (child) => {
|
|
if (!React.isValidElement<NavItemProps>(child)) return null;
|
|
|
|
const childProps = child.props as NavItemProps;
|
|
const childPath = childProps.to;
|
|
|
|
return childPath && shouldShowItem(childPath, userRoles, permissions)
|
|
? child
|
|
: null;
|
|
})?.filter(Boolean);
|
|
|
|
if (filteredChildren?.length) {
|
|
// Cast item as ReactElement<NavItemProps> to allow children
|
|
return React.cloneElement<NavItemProps>(item, {
|
|
...props,
|
|
children: filteredChildren,
|
|
});
|
|
}
|
|
|
|
return path && shouldShowItem(path, userRoles, permissions) ? item : null;
|
|
}
|
|
|
|
return path && shouldShowItem(path, userRoles, permissions) ? item : null;
|
|
})?.filter(Boolean);
|
|
|
|
return filteredItems ?? null;
|
|
};
|
|
|
|
const shouldShowItem = (
|
|
path: string,
|
|
userRoles?: string[],
|
|
permissions?: Record<string, string[]>
|
|
): boolean => {
|
|
if (!userRoles || userRoles.length === 0) return false;
|
|
if (!permissions) return false;
|
|
|
|
const cleanPath = path.startsWith("/") ? path.slice(1) : path;
|
|
|
|
if (!permissions[cleanPath]) return false;
|
|
|
|
return userRoles.some((role) => permissions[cleanPath].includes(role));
|
|
};
|