correction in Role

This commit is contained in:
MohamedHasan07
2026-07-23 11:44:09 +05:30
parent 5be032cbeb
commit 4c147d6d85
3 changed files with 110 additions and 24 deletions
+89 -3
View File
@@ -56,6 +56,32 @@ export default function NewRoleForm() {
const [fetching, setFetching] = useState(isEdit);
const [fetchError, setFetchError] = useState<string | null>(null);
const [selectedGroup, setSelectedGroup] = useState<string>(() => {
return localStorage.getItem("pim_roles_last_group_filter") || "all";
});
const parentGroups = nodes.filter(
(node) =>
node.node_type === "group" ||
(node.node_type === "feature" && (node.parent_id === null || node.parent_id === undefined))
);
const featureNodes = nodes.filter((node) => node.node_type === "feature" || !node.node_type);
const handleGroupSelect = (groupId: string) => {
setSelectedGroup(groupId);
localStorage.setItem("pim_roles_last_group_filter", groupId);
};
const filteredNodes = selectedGroup === "all"
? featureNodes
: featureNodes.filter((node) => {
const selectedNode = nodes.find((n) => String(n.id) === selectedGroup);
if (selectedNode?.node_type === "group") {
return String(node.parent_id) === selectedGroup;
}
return String(node.id) === selectedGroup;
});
const setValuesRef = useRef<((values: any) => void) | null>(null);
const formik = useFormik({
@@ -467,8 +493,61 @@ export default function NewRoleForm() {
className="bg-surface rounded-lg border border-primary/10 shadow-sm overflow-hidden flex flex-col"
style={{ height: "520px" }}
>
<div className="shrink-0">
<style>{`
@keyframes fadeIn {
from { opacity: 0; transform: translateY(4px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-fade-in {
animation: fadeIn 0.25s ease-out forwards;
}
`}</style>
<div className="shrink-0 border-b border-border bg-surface">
<CardHeader title="Permissions Matrix" subtitle="Configure granular access levels for each module" />
{!nodesLoading && !nodesError && parentGroups.length > 0 && (
<div
role="tablist"
aria-label="Filter Permissions by Category"
className="flex items-center gap-2 px-6 py-3 border-t border-border overflow-x-auto scrollbar-none sticky top-0 bg-surface z-20"
>
<button
type="button"
role="tab"
aria-selected={selectedGroup === "all"}
onClick={() => handleGroupSelect("all")}
className={`px-3 py-1.5 rounded-lg text-xs font-semibold tracking-wide transition-all duration-200 cursor-pointer ${
selectedGroup === "all"
? "bg-primary text-white shadow-sm shadow-primary/20 scale-102"
: "bg-primary/5 hover:bg-primary-ghost text-subtle-foreground hover:text-primary-dark"
}`}
>
All ({featureNodes.length})
</button>
{parentGroups.map((g) => {
const count = g.node_type === "group"
? featureNodes.filter((node) => String(node.parent_id) === String(g.id)).length
: 1;
return (
<button
key={g.id}
type="button"
role="tab"
aria-selected={selectedGroup === String(g.id)}
onClick={() => handleGroupSelect(String(g.id))}
className={`px-3 py-1.5 rounded-lg text-xs font-semibold tracking-wide transition-all duration-200 cursor-pointer ${
selectedGroup === String(g.id)
? "bg-primary text-white shadow-sm shadow-primary/20 scale-102"
: "bg-primary/5 hover:bg-primary-ghost text-subtle-foreground hover:text-primary-dark"
}`}
>
{g.node_name} ({count})
</button>
);
})}
</div>
)}
</div>
{nodesLoading && (
@@ -493,10 +572,11 @@ export default function NewRoleForm() {
{!nodesLoading && !nodesError && (
<div
className="flex-1 overflow-y-auto divide-y divide-border"
key={selectedGroup}
className="flex-1 overflow-y-auto divide-y divide-border animate-fade-in"
style={{ scrollbarWidth: "none" }}
>
{nodes.map((node) => {
{filteredNodes.map((node) => {
const perm = permissions[node.id];
const supportedActions = getSupportedActions(node);
@@ -547,6 +627,12 @@ export default function NewRoleForm() {
</div>
);
})}
{filteredNodes.length === 0 && (
<div className="flex flex-col items-center justify-center py-12 text-center">
<p className="text-sm text-muted-foreground font-medium">No permissions available.</p>
</div>
)}
</div>
)}
</div>
+19 -18
View File
@@ -40,10 +40,10 @@ export interface SidebarItem {
}
export const sidebarConfig: SidebarItem[] = [
{
label: 'Dashboard',
href: '/dashboard',
icon: LayoutDashboard
{
label: 'Dashboard',
href: '/dashboard',
icon: LayoutDashboard
},
{
label: 'Products',
@@ -101,9 +101,9 @@ export const sidebarConfig: SidebarItem[] = [
{ label: 'Asset Families', href: '/asset-families', icon: Layers },
]
},
{
label: 'Workflow & Approvals',
href: '/workflow',
{
label: 'Workflow & Approvals',
href: '/workflow',
icon: Workflow
},
{
@@ -116,24 +116,25 @@ export const sidebarConfig: SidebarItem[] = [
{ label: 'Integration Hub', href: '/integrations', icon: Plug, permission: 'settings.integrations' },
]
},
{
label: 'Users & Roles',
href: '/users',
icon: Users,
{
label: 'Users & Roles',
href: '/users',
icon: Users,
children: [
{ label: 'Users', href: '/users', icon: Users, permission: 'settings.users' },
{ label: 'Tenants', href: '/users/tenants', icon: Database, permission: 'settings.tenants' },
{ label: 'Roles', href: '/users/roles', icon: Users, permission: 'settings.roles' }
]
},
{
label: 'Reports',
href: '/reports',
icon: BarChart
{
label: 'Reports',
href: '/reports',
icon: BarChart,
permission: 'reports'
},
{
label: 'Settings',
href: '/settings',
{
label: 'Settings',
href: '/settings',
icon: Settings
},
{
+2 -3
View File
@@ -10,7 +10,7 @@ export interface NodePermissions {
export type PermissionPayload = Record<string, NodePermissions>;
export type PermissionNodes =
export type PermissionNodes =
| 'products.items'
| 'products.families'
| 'products.categories'
@@ -27,7 +27,6 @@ export type PermissionNodes =
| 'settings.users'
| 'settings.roles'
| 'settings.integrations'
| 'reports.sales'
| 'reports.inventory';
| 'reports';
export type PermissionAction = keyof NodePermissions;