@asteby/metacore-runtime-react 30.0.1 → 30.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/permissions-manager.d.ts +17 -0
- package/dist/permissions-manager.d.ts.map +1 -1
- package/dist/permissions-manager.js +55 -6
- package/package.json +1 -1
- package/src/__tests__/permissions-manager.test.tsx +14 -0
- package/src/index.ts +1 -0
- package/src/permissions-manager.tsx +157 -19
package/CHANGELOG.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export * from './slot';
|
|
|
23
23
|
export * from './capability-gate';
|
|
24
24
|
export { PermissionsProvider, useCan, usePermissionsActive, makeCan, capabilityForActionKey, modelCapability, gateTableMetadata, resolveRowActions, type CanFn, type PermissionsProviderProps, } from './permissions-context';
|
|
25
25
|
export { useDynamicRowActions, type UseDynamicRowActionsParams, type DynamicRowActions, } from './dynamic-row-actions';
|
|
26
|
-
export { PermissionsManager, moduleActionCapability, moduleCapabilities, grantedCountForModule, capabilitySetsEqual, defaultActionIcon, normalizeCatalogGroups, flattenGroups, filterModuleGroups, type PermissionsManagerProps, type PermissionsCatalog, type GroupedPermissionsCatalog, type FlatPermissionsCatalog, type ModuleGroup, type PermissionModuleDef, type PermissionActionDef, type GeneralPermissionDef, type RoleDef, type RoleInput, } from './permissions-manager';
|
|
26
|
+
export { PermissionsManager, moduleActionCapability, moduleCapabilities, grantedCountForModule, capabilitySetsEqual, defaultActionIcon, normalizeCatalogGroups, flattenGroups, filterModuleGroups, groupModuleActions, type PermissionsManagerProps, type PermissionsCatalog, type GroupedPermissionsCatalog, type FlatPermissionsCatalog, type ModuleGroup, type PermissionModuleDef, type PermissionActionDef, type GeneralPermissionDef, type RoleDef, type RoleInput, } from './permissions-manager';
|
|
27
27
|
export * from './org-runtime-context';
|
|
28
28
|
export * from './org-runtime-provider';
|
|
29
29
|
export * from './navigation-builder';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -28,7 +28,7 @@ export * from './slot';
|
|
|
28
28
|
export * from './capability-gate';
|
|
29
29
|
export { PermissionsProvider, useCan, usePermissionsActive, makeCan, capabilityForActionKey, modelCapability, gateTableMetadata, resolveRowActions, } from './permissions-context';
|
|
30
30
|
export { useDynamicRowActions, } from './dynamic-row-actions';
|
|
31
|
-
export { PermissionsManager, moduleActionCapability, moduleCapabilities, grantedCountForModule, capabilitySetsEqual, defaultActionIcon, normalizeCatalogGroups, flattenGroups, filterModuleGroups, } from './permissions-manager';
|
|
31
|
+
export { PermissionsManager, moduleActionCapability, moduleCapabilities, grantedCountForModule, capabilitySetsEqual, defaultActionIcon, normalizeCatalogGroups, flattenGroups, filterModuleGroups, groupModuleActions, } from './permissions-manager';
|
|
32
32
|
export * from './org-runtime-context';
|
|
33
33
|
export * from './org-runtime-provider';
|
|
34
34
|
export * from './navigation-builder';
|
|
@@ -20,6 +20,12 @@ export interface PermissionActionDef {
|
|
|
20
20
|
* shortcuts without inventing `screen….product.index`.
|
|
21
21
|
*/
|
|
22
22
|
capability?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Optional section title for the action grid (e.g. "Catálogo", "Ventas").
|
|
25
|
+
* When any action on a module sets `group`, the right-hand panel renders
|
|
26
|
+
* collapsible sections instead of one flat checkbox grid.
|
|
27
|
+
*/
|
|
28
|
+
group?: string;
|
|
23
29
|
}
|
|
24
30
|
export interface PermissionModuleDef {
|
|
25
31
|
/**
|
|
@@ -109,6 +115,17 @@ export interface PermissionsManagerProps {
|
|
|
109
115
|
export declare function moduleActionCapability(moduleKey: string, actionKey: string, capability?: string): string;
|
|
110
116
|
/** All capabilities of one module. */
|
|
111
117
|
export declare function moduleCapabilities(module: PermissionModuleDef): string[];
|
|
118
|
+
export interface ActionGroupSection {
|
|
119
|
+
/** Empty string = ungrouped actions rendered above the collapsibles. */
|
|
120
|
+
title: string;
|
|
121
|
+
actions: PermissionActionDef[];
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Split a module's actions into an optional ungrouped prefix + named sections
|
|
125
|
+
* (first-seen order of `action.group`). Modules without any `group` yield a
|
|
126
|
+
* single untitled section (flat grid, backward compatible).
|
|
127
|
+
*/
|
|
128
|
+
export declare function groupModuleActions(actions: PermissionActionDef[]): ActionGroupSection[];
|
|
112
129
|
/** How many of the module's capabilities are in the granted set. */
|
|
113
130
|
export declare function grantedCountForModule(granted: ReadonlySet<string>, module: PermissionModuleDef): number;
|
|
114
131
|
export declare function capabilitySetsEqual(a: ReadonlySet<string>, b: ReadonlySet<string>): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions-manager.d.ts","sourceRoot":"","sources":["../src/permissions-manager.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"permissions-manager.d.ts","sourceRoot":"","sources":["../src/permissions-manager.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA6D9B,MAAM,WAAW,mBAAmB;IAChC,kFAAkF;IAClF,GAAG,EAAE,MAAM,CAAA;IACX,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAA;IACb,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,GAAG,MAAM,CAAA;IAC3D;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,mBAAmB;IAChC;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAA;IACX,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAA;IACb,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gEAAgE;IAChE,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;IACzB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,mBAAmB,EAAE,CAAA;CACjC;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,mBAAmB,EAAE,CAAA;CACjC;AAED,MAAM,WAAW,oBAAoB;IACjC,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,yBAAyB;IACtC,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,OAAO,EAAE,oBAAoB,EAAE,CAAA;CAClC;AAED,MAAM,WAAW,sBAAsB;IACnC,OAAO,EAAE,mBAAmB,EAAE,CAAA;IAC9B,OAAO,EAAE,oBAAoB,EAAE,CAAA;CAClC;AAED,MAAM,MAAM,kBAAkB,GAAG,yBAAyB,GAAG,sBAAsB,CAAA;AAEnF,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,uBAAuB;IACpC,0EAA0E;IAC1E,WAAW,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAC9C,mCAAmC;IACnC,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IACnC,0DAA0D;IAC1D,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IAC1D,0DAA0D;IAC1D,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9E,2DAA2D;IAC3D,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IAC1D,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IAC1E,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9C,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AAMD;;eAEe;AACf,wBAAgB,sBAAsB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,GACpB,MAAM,CAGR;AAED,sCAAsC;AACtC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAIxE;AAED,MAAM,WAAW,kBAAkB;IAC/B,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,mBAAmB,EAAE,CAAA;CACjC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,kBAAkB,EAAE,CAwBvF;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,CACjC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,EAC5B,MAAM,EAAE,mBAAmB,GAC5B,MAAM,CAER;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAI3F;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAsB1E;AAoCD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,EAAE,CA0BjF;AAED,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,mBAAmB,EAAE,CAE1E;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAYtF;AA+GD,wBAAgB,kBAAkB,CAAC,EAC/B,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,UAAU,EACV,UAAU,EACV,UAAU,EACV,KAA0B,EAC1B,SAAS,GACZ,EAAE,uBAAuB,qBAguBzB"}
|
|
@@ -25,10 +25,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
25
25
|
// state is tracked against the loaded baseline and surfaced next to the
|
|
26
26
|
// save button.
|
|
27
27
|
import * as React from 'react';
|
|
28
|
-
import { Check, ChevronsUpDown, CheckCheck, Eraser, Pencil, Plus, Save, Shield, Trash2, } from 'lucide-react';
|
|
28
|
+
import { Check, ChevronsUpDown, CheckCheck, ChevronDown, Eraser, Pencil, Plus, Save, Shield, Trash2, } from 'lucide-react';
|
|
29
29
|
import { toast } from 'sonner';
|
|
30
30
|
import { cn } from '@asteby/metacore-ui/lib';
|
|
31
|
-
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Checkbox, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, Input, Label, Popover, PopoverContent, PopoverTrigger, Separator, Skeleton, } from '@asteby/metacore-ui/primitives';
|
|
31
|
+
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Checkbox, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, Input, Label, Popover, PopoverContent, PopoverTrigger, Separator, Skeleton, Collapsible, CollapsibleContent, CollapsibleTrigger, } from '@asteby/metacore-ui/primitives';
|
|
32
32
|
import { DynamicIcon } from './dynamic-icon';
|
|
33
33
|
// ---------------------------------------------------------------------------
|
|
34
34
|
// Pure helpers (exported for hosts/tests)
|
|
@@ -45,6 +45,37 @@ export function moduleActionCapability(moduleKey, actionKey, capability) {
|
|
|
45
45
|
export function moduleCapabilities(module) {
|
|
46
46
|
return module.actions.map((a) => moduleActionCapability(module.key, a.key, a.capability));
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Split a module's actions into an optional ungrouped prefix + named sections
|
|
50
|
+
* (first-seen order of `action.group`). Modules without any `group` yield a
|
|
51
|
+
* single untitled section (flat grid, backward compatible).
|
|
52
|
+
*/
|
|
53
|
+
export function groupModuleActions(actions) {
|
|
54
|
+
const ungrouped = [];
|
|
55
|
+
const byTitle = new Map();
|
|
56
|
+
const order = [];
|
|
57
|
+
for (const action of actions) {
|
|
58
|
+
const title = (action.group ?? '').trim();
|
|
59
|
+
if (!title) {
|
|
60
|
+
ungrouped.push(action);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
let list = byTitle.get(title);
|
|
64
|
+
if (!list) {
|
|
65
|
+
list = [];
|
|
66
|
+
byTitle.set(title, list);
|
|
67
|
+
order.push(title);
|
|
68
|
+
}
|
|
69
|
+
list.push(action);
|
|
70
|
+
}
|
|
71
|
+
const out = [];
|
|
72
|
+
if (ungrouped.length > 0)
|
|
73
|
+
out.push({ title: '', actions: ungrouped });
|
|
74
|
+
for (const title of order) {
|
|
75
|
+
out.push({ title, actions: byTitle.get(title) });
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
48
79
|
/** How many of the module's capabilities are in the granted set. */
|
|
49
80
|
export function grantedCountForModule(granted, module) {
|
|
50
81
|
return moduleCapabilities(module).filter((c) => granted.has(c)).length;
|
|
@@ -450,10 +481,7 @@ export function PermissionsManager({ loadModules, loadRoles, loadRolePermissions
|
|
|
450
481
|
0 && (_jsxs(Badge, { variant: "secondary", className: "ml-auto shrink-0 tabular-nums", children: [grantedCountForModule(draft, mod), "/", mod.actions.length] })), mod.key === activeModuleKey && (_jsx(Check, { className: "ml-2 h-4 w-4 shrink-0" }))] }, mod.key))) }, group.title || `__untitled_${gi}`)))] })] }) })] }) })] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [activeModule && (_jsx(DynamicIcon, { name: activeModule.icon ||
|
|
451
482
|
(activeModule.kind === 'screen' ? 'Eye' : 'Square'), className: "h-4 w-4 shrink-0 text-primary" })), _jsx("span", { className: "truncate", children: activeModule ? activeModule.label : 'Acciones permitidas' })] }), _jsx(CardDescription, { children: activeModule
|
|
452
483
|
? `${activeModuleGroupTitle || 'Sistema'} · configura las acciones permitidas`
|
|
453
|
-
: 'Configura los permisos del módulo seleccionado.' })] }), activeRole && activeModule && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Badge, { variant: "secondary", className: "tabular-nums", children: [moduleGranted, "/", moduleTotal] }), _jsxs(Button, { variant: "outline", size: "sm", className: "h-8", disabled: checksDisabled || moduleGranted === moduleTotal, onClick: () => setModuleAll(true), children: [_jsx(CheckCheck, { className: "mr-1.5 h-3.5 w-3.5" }), " Marcar todo"] }), _jsxs(Button, { variant: "outline", size: "sm", className: "h-8", disabled: checksDisabled || moduleGranted === 0, onClick: () => setModuleAll(false), children: [_jsx(Eraser, { className: "mr-1.5 h-3.5 w-3.5" }), " Limpiar"] })] }))] }) }), _jsx(CardContent, { children: !activeRole ? (_jsx(EmptyHint, { text: "Selecciona un rol para configurar sus permisos." })) : loadingPerms ? (_jsx("div", { className: "grid gap-2 sm:grid-cols-2 xl:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsx(Skeleton, { className: "h-11 w-full" }, i))) })) : !activeModule ? (_jsx(EmptyHint, { text: "Selecciona un m\u00F3dulo de la lista para ver sus acciones." })) : (_jsx(
|
|
454
|
-
const cap = moduleActionCapability(activeModule.key, action.key, action.capability);
|
|
455
|
-
return (_jsx(CapabilityCheck, { checked: draft?.has(cap) ?? false, disabled: checksDisabled, onToggle: () => toggleCapability(cap), icon: action.icon || defaultActionIcon(action.key, action.kind), label: action.label }, action.capability ?? action.key));
|
|
456
|
-
}) })) })] })] }), _jsx(AlertDialog, { open: pendingRoleId !== null, onOpenChange: (open) => !open && setPendingRoleId(null), children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Cambios sin guardar" }), _jsx(AlertDialogDescription, { children: "Tienes cambios sin guardar en este rol. Si cambias de rol se descartar\u00E1n." })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Cancelar" }), _jsx(AlertDialogAction, { onClick: () => {
|
|
484
|
+
: 'Configura los permisos del módulo seleccionado.' })] }), activeRole && activeModule && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Badge, { variant: "secondary", className: "tabular-nums", children: [moduleGranted, "/", moduleTotal] }), _jsxs(Button, { variant: "outline", size: "sm", className: "h-8", disabled: checksDisabled || moduleGranted === moduleTotal, onClick: () => setModuleAll(true), children: [_jsx(CheckCheck, { className: "mr-1.5 h-3.5 w-3.5" }), " Marcar todo"] }), _jsxs(Button, { variant: "outline", size: "sm", className: "h-8", disabled: checksDisabled || moduleGranted === 0, onClick: () => setModuleAll(false), children: [_jsx(Eraser, { className: "mr-1.5 h-3.5 w-3.5" }), " Limpiar"] })] }))] }) }), _jsx(CardContent, { children: !activeRole ? (_jsx(EmptyHint, { text: "Selecciona un rol para configurar sus permisos." })) : loadingPerms ? (_jsx("div", { className: "grid gap-2 sm:grid-cols-2 xl:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsx(Skeleton, { className: "h-11 w-full" }, i))) })) : !activeModule ? (_jsx(EmptyHint, { text: "Selecciona un m\u00F3dulo de la lista para ver sus acciones." })) : (_jsx(ModuleActionsPanel, { module: activeModule, draft: draft, checksDisabled: checksDisabled, onToggle: toggleCapability })) })] })] }), _jsx(AlertDialog, { open: pendingRoleId !== null, onOpenChange: (open) => !open && setPendingRoleId(null), children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Cambios sin guardar" }), _jsx(AlertDialogDescription, { children: "Tienes cambios sin guardar en este rol. Si cambias de rol se descartar\u00E1n." })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Cancelar" }), _jsx(AlertDialogAction, { onClick: () => {
|
|
457
485
|
setActiveRoleId(pendingRoleId);
|
|
458
486
|
setPendingRoleId(null);
|
|
459
487
|
}, children: "Descartar y cambiar" })] })] }) }), _jsx(Dialog, { open: roleDialog.open, onOpenChange: (open) => setRoleDialog((d) => ({ ...d, open })), children: _jsxs(DialogContent, { className: "sm:max-w-md", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: roleDialog.mode === 'create' ? 'Nuevo rol' : 'Editar rol' }) }), _jsxs("div", { className: "flex flex-col gap-4 py-2", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "pm-role-name", children: "Nombre del rol" }), _jsx(Input, { id: "pm-role-name", value: roleDialog.label, placeholder: "Ej. Cajero", onChange: (e) => setRoleDialog((d) => ({ ...d, label: e.target.value })) })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Color" }), _jsx("div", { className: "flex flex-wrap gap-2", children: ROLE_COLORS.map((c) => (_jsx("button", { type: "button", "aria-label": `Color ${c}`, onClick: () => setRoleDialog((d) => ({ ...d, color: c })), className: cn('h-7 w-7 rounded-full border-2 transition-transform', roleDialog.color === c
|
|
@@ -467,6 +495,27 @@ export function PermissionsManager({ loadModules, loadRoles, loadRolePermissions
|
|
|
467
495
|
handleDeleteRole();
|
|
468
496
|
}, children: deleting ? 'Eliminando…' : 'Eliminar' })] })] }) })] }));
|
|
469
497
|
}
|
|
498
|
+
function ActionCheckGrid({ moduleKey, actions, draft, checksDisabled, onToggle, }) {
|
|
499
|
+
return (_jsx("div", { className: "grid gap-2 sm:grid-cols-2 xl:grid-cols-3", children: actions.map((action) => {
|
|
500
|
+
const cap = moduleActionCapability(moduleKey, action.key, action.capability);
|
|
501
|
+
return (_jsx(CapabilityCheck, { checked: draft?.has(cap) ?? false, disabled: checksDisabled, onToggle: () => onToggle(cap), icon: action.icon || defaultActionIcon(action.key, action.kind), label: action.label }, action.capability ?? action.key));
|
|
502
|
+
}) }));
|
|
503
|
+
}
|
|
504
|
+
/** Flat grid, or collapsible sections when actions declare `group`. */
|
|
505
|
+
function ModuleActionsPanel({ module, draft, checksDisabled, onToggle, }) {
|
|
506
|
+
const sections = React.useMemo(() => groupModuleActions(module.actions), [module.actions]);
|
|
507
|
+
const hasNamedGroups = sections.some((s) => s.title.length > 0);
|
|
508
|
+
if (!hasNamedGroups) {
|
|
509
|
+
return (_jsx(ActionCheckGrid, { moduleKey: module.key, actions: module.actions, draft: draft, checksDisabled: checksDisabled, onToggle: onToggle }));
|
|
510
|
+
}
|
|
511
|
+
return (_jsx("div", { className: "flex flex-col gap-3", children: sections.map((section) => {
|
|
512
|
+
if (!section.title) {
|
|
513
|
+
return (_jsx(ActionCheckGrid, { moduleKey: module.key, actions: section.actions, draft: draft, checksDisabled: checksDisabled, onToggle: onToggle }, "__ungrouped"));
|
|
514
|
+
}
|
|
515
|
+
const granted = section.actions.filter((a) => draft?.has(moduleActionCapability(module.key, a.key, a.capability))).length;
|
|
516
|
+
return (_jsxs(Collapsible, { defaultOpen: true, className: "rounded-md border border-border/60", children: [_jsxs(CollapsibleTrigger, { className: "flex w-full items-center gap-2 px-3 py-2.5 text-left text-sm font-medium hover:bg-muted/40 [&[data-state=open]>svg]:rotate-180", children: [_jsx(ChevronDown, { className: "h-4 w-4 shrink-0 text-muted-foreground transition-transform" }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: section.title }), _jsxs(Badge, { variant: "secondary", className: "tabular-nums", children: [granted, "/", section.actions.length] })] }), _jsx(CollapsibleContent, { className: "border-t border-border/60 px-3 py-3", children: _jsx(ActionCheckGrid, { moduleKey: module.key, actions: section.actions, draft: draft, checksDisabled: checksDisabled, onToggle: onToggle }) })] }, section.title));
|
|
517
|
+
}) }));
|
|
518
|
+
}
|
|
470
519
|
function EmptyHint({ text }) {
|
|
471
520
|
return (_jsxs("div", { className: "flex flex-col items-center justify-center gap-2 py-12 text-muted-foreground", children: [_jsx(Shield, { className: "h-8 w-8 opacity-40" }), _jsx("p", { className: "text-sm", children: text })] }));
|
|
472
521
|
}
|
package/package.json
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
flattenGroups,
|
|
15
15
|
filterModuleGroups,
|
|
16
16
|
defaultActionIcon,
|
|
17
|
+
groupModuleActions,
|
|
17
18
|
type PermissionsCatalog,
|
|
18
19
|
type GroupedPermissionsCatalog,
|
|
19
20
|
type FlatPermissionsCatalog,
|
|
@@ -142,6 +143,19 @@ describe('helpers puros', () => {
|
|
|
142
143
|
])
|
|
143
144
|
})
|
|
144
145
|
|
|
146
|
+
it('groupModuleActions keeps Acceder ungrouped and sections by group', () => {
|
|
147
|
+
const sections = groupModuleActions([
|
|
148
|
+
{ key: 'access', label: 'Acceder', kind: 'screen' },
|
|
149
|
+
{ key: 'product.index', label: 'Productos', group: 'Catálogo', capability: 'product.index' },
|
|
150
|
+
{ key: 'stock.index', label: 'Stock', group: 'Catálogo', capability: 'stock.index' },
|
|
151
|
+
{ key: 'salesorder.create', label: 'Venta', group: 'Ventas', capability: 'salesorder.create' },
|
|
152
|
+
])
|
|
153
|
+
expect(sections.map((s) => s.title)).toEqual(['', 'Catálogo', 'Ventas'])
|
|
154
|
+
expect(sections[0].actions).toHaveLength(1)
|
|
155
|
+
expect(sections[1].actions).toHaveLength(2)
|
|
156
|
+
expect(sections[2].actions).toHaveLength(1)
|
|
157
|
+
})
|
|
158
|
+
|
|
145
159
|
it('moduleCapabilities y grantedCountForModule', () => {
|
|
146
160
|
const mod = grouped.groups[1].modules[0] // pos_orders
|
|
147
161
|
expect(moduleCapabilities(mod)).toEqual([
|
package/src/index.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
Check,
|
|
29
29
|
ChevronsUpDown,
|
|
30
30
|
CheckCheck,
|
|
31
|
+
ChevronDown,
|
|
31
32
|
Eraser,
|
|
32
33
|
Pencil,
|
|
33
34
|
Plus,
|
|
@@ -73,6 +74,9 @@ import {
|
|
|
73
74
|
PopoverTrigger,
|
|
74
75
|
Separator,
|
|
75
76
|
Skeleton,
|
|
77
|
+
Collapsible,
|
|
78
|
+
CollapsibleContent,
|
|
79
|
+
CollapsibleTrigger,
|
|
76
80
|
} from '@asteby/metacore-ui/primitives'
|
|
77
81
|
import { DynamicIcon } from './dynamic-icon'
|
|
78
82
|
|
|
@@ -101,6 +105,12 @@ export interface PermissionActionDef {
|
|
|
101
105
|
* shortcuts without inventing `screen….product.index`.
|
|
102
106
|
*/
|
|
103
107
|
capability?: string
|
|
108
|
+
/**
|
|
109
|
+
* Optional section title for the action grid (e.g. "Catálogo", "Ventas").
|
|
110
|
+
* When any action on a module sets `group`, the right-hand panel renders
|
|
111
|
+
* collapsible sections instead of one flat checkbox grid.
|
|
112
|
+
*/
|
|
113
|
+
group?: string
|
|
104
114
|
}
|
|
105
115
|
|
|
106
116
|
export interface PermissionModuleDef {
|
|
@@ -217,6 +227,43 @@ export function moduleCapabilities(module: PermissionModuleDef): string[] {
|
|
|
217
227
|
)
|
|
218
228
|
}
|
|
219
229
|
|
|
230
|
+
export interface ActionGroupSection {
|
|
231
|
+
/** Empty string = ungrouped actions rendered above the collapsibles. */
|
|
232
|
+
title: string
|
|
233
|
+
actions: PermissionActionDef[]
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Split a module's actions into an optional ungrouped prefix + named sections
|
|
238
|
+
* (first-seen order of `action.group`). Modules without any `group` yield a
|
|
239
|
+
* single untitled section (flat grid, backward compatible).
|
|
240
|
+
*/
|
|
241
|
+
export function groupModuleActions(actions: PermissionActionDef[]): ActionGroupSection[] {
|
|
242
|
+
const ungrouped: PermissionActionDef[] = []
|
|
243
|
+
const byTitle = new Map<string, PermissionActionDef[]>()
|
|
244
|
+
const order: string[] = []
|
|
245
|
+
for (const action of actions) {
|
|
246
|
+
const title = (action.group ?? '').trim()
|
|
247
|
+
if (!title) {
|
|
248
|
+
ungrouped.push(action)
|
|
249
|
+
continue
|
|
250
|
+
}
|
|
251
|
+
let list = byTitle.get(title)
|
|
252
|
+
if (!list) {
|
|
253
|
+
list = []
|
|
254
|
+
byTitle.set(title, list)
|
|
255
|
+
order.push(title)
|
|
256
|
+
}
|
|
257
|
+
list.push(action)
|
|
258
|
+
}
|
|
259
|
+
const out: ActionGroupSection[] = []
|
|
260
|
+
if (ungrouped.length > 0) out.push({ title: '', actions: ungrouped })
|
|
261
|
+
for (const title of order) {
|
|
262
|
+
out.push({ title, actions: byTitle.get(title)! })
|
|
263
|
+
}
|
|
264
|
+
return out
|
|
265
|
+
}
|
|
266
|
+
|
|
220
267
|
/** How many of the module's capabilities are in the granted set. */
|
|
221
268
|
export function grantedCountForModule(
|
|
222
269
|
granted: ReadonlySet<string>,
|
|
@@ -1068,25 +1115,12 @@ export function PermissionsManager({
|
|
|
1068
1115
|
) : !activeModule ? (
|
|
1069
1116
|
<EmptyHint text="Selecciona un módulo de la lista para ver sus acciones." />
|
|
1070
1117
|
) : (
|
|
1071
|
-
<
|
|
1072
|
-
{activeModule
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
)
|
|
1078
|
-
return (
|
|
1079
|
-
<CapabilityCheck
|
|
1080
|
-
key={action.capability ?? action.key}
|
|
1081
|
-
checked={draft?.has(cap) ?? false}
|
|
1082
|
-
disabled={checksDisabled}
|
|
1083
|
-
onToggle={() => toggleCapability(cap)}
|
|
1084
|
-
icon={action.icon || defaultActionIcon(action.key, action.kind)}
|
|
1085
|
-
label={action.label}
|
|
1086
|
-
/>
|
|
1087
|
-
)
|
|
1088
|
-
})}
|
|
1089
|
-
</div>
|
|
1118
|
+
<ModuleActionsPanel
|
|
1119
|
+
module={activeModule}
|
|
1120
|
+
draft={draft}
|
|
1121
|
+
checksDisabled={checksDisabled}
|
|
1122
|
+
onToggle={toggleCapability}
|
|
1123
|
+
/>
|
|
1090
1124
|
)}
|
|
1091
1125
|
</CardContent>
|
|
1092
1126
|
</Card>
|
|
@@ -1217,6 +1251,110 @@ export function PermissionsManager({
|
|
|
1217
1251
|
)
|
|
1218
1252
|
}
|
|
1219
1253
|
|
|
1254
|
+
function ActionCheckGrid({
|
|
1255
|
+
moduleKey,
|
|
1256
|
+
actions,
|
|
1257
|
+
draft,
|
|
1258
|
+
checksDisabled,
|
|
1259
|
+
onToggle,
|
|
1260
|
+
}: {
|
|
1261
|
+
moduleKey: string
|
|
1262
|
+
actions: PermissionActionDef[]
|
|
1263
|
+
draft: ReadonlySet<string> | null | undefined
|
|
1264
|
+
checksDisabled: boolean
|
|
1265
|
+
onToggle: (cap: string) => void
|
|
1266
|
+
}) {
|
|
1267
|
+
return (
|
|
1268
|
+
<div className="grid gap-2 sm:grid-cols-2 xl:grid-cols-3">
|
|
1269
|
+
{actions.map((action) => {
|
|
1270
|
+
const cap = moduleActionCapability(moduleKey, action.key, action.capability)
|
|
1271
|
+
return (
|
|
1272
|
+
<CapabilityCheck
|
|
1273
|
+
key={action.capability ?? action.key}
|
|
1274
|
+
checked={draft?.has(cap) ?? false}
|
|
1275
|
+
disabled={checksDisabled}
|
|
1276
|
+
onToggle={() => onToggle(cap)}
|
|
1277
|
+
icon={action.icon || defaultActionIcon(action.key, action.kind)}
|
|
1278
|
+
label={action.label}
|
|
1279
|
+
/>
|
|
1280
|
+
)
|
|
1281
|
+
})}
|
|
1282
|
+
</div>
|
|
1283
|
+
)
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
/** Flat grid, or collapsible sections when actions declare `group`. */
|
|
1287
|
+
function ModuleActionsPanel({
|
|
1288
|
+
module,
|
|
1289
|
+
draft,
|
|
1290
|
+
checksDisabled,
|
|
1291
|
+
onToggle,
|
|
1292
|
+
}: {
|
|
1293
|
+
module: PermissionModuleDef
|
|
1294
|
+
draft: ReadonlySet<string> | null | undefined
|
|
1295
|
+
checksDisabled: boolean
|
|
1296
|
+
onToggle: (cap: string) => void
|
|
1297
|
+
}) {
|
|
1298
|
+
const sections = React.useMemo(
|
|
1299
|
+
() => groupModuleActions(module.actions),
|
|
1300
|
+
[module.actions],
|
|
1301
|
+
)
|
|
1302
|
+
const hasNamedGroups = sections.some((s) => s.title.length > 0)
|
|
1303
|
+
if (!hasNamedGroups) {
|
|
1304
|
+
return (
|
|
1305
|
+
<ActionCheckGrid
|
|
1306
|
+
moduleKey={module.key}
|
|
1307
|
+
actions={module.actions}
|
|
1308
|
+
draft={draft}
|
|
1309
|
+
checksDisabled={checksDisabled}
|
|
1310
|
+
onToggle={onToggle}
|
|
1311
|
+
/>
|
|
1312
|
+
)
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
return (
|
|
1316
|
+
<div className="flex flex-col gap-3">
|
|
1317
|
+
{sections.map((section) => {
|
|
1318
|
+
if (!section.title) {
|
|
1319
|
+
return (
|
|
1320
|
+
<ActionCheckGrid
|
|
1321
|
+
key="__ungrouped"
|
|
1322
|
+
moduleKey={module.key}
|
|
1323
|
+
actions={section.actions}
|
|
1324
|
+
draft={draft}
|
|
1325
|
+
checksDisabled={checksDisabled}
|
|
1326
|
+
onToggle={onToggle}
|
|
1327
|
+
/>
|
|
1328
|
+
)
|
|
1329
|
+
}
|
|
1330
|
+
const granted = section.actions.filter((a) =>
|
|
1331
|
+
draft?.has(moduleActionCapability(module.key, a.key, a.capability)),
|
|
1332
|
+
).length
|
|
1333
|
+
return (
|
|
1334
|
+
<Collapsible key={section.title} defaultOpen className="rounded-md border border-border/60">
|
|
1335
|
+
<CollapsibleTrigger className="flex w-full items-center gap-2 px-3 py-2.5 text-left text-sm font-medium hover:bg-muted/40 [&[data-state=open]>svg]:rotate-180">
|
|
1336
|
+
<ChevronDown className="h-4 w-4 shrink-0 text-muted-foreground transition-transform" />
|
|
1337
|
+
<span className="min-w-0 flex-1 truncate">{section.title}</span>
|
|
1338
|
+
<Badge variant="secondary" className="tabular-nums">
|
|
1339
|
+
{granted}/{section.actions.length}
|
|
1340
|
+
</Badge>
|
|
1341
|
+
</CollapsibleTrigger>
|
|
1342
|
+
<CollapsibleContent className="border-t border-border/60 px-3 py-3">
|
|
1343
|
+
<ActionCheckGrid
|
|
1344
|
+
moduleKey={module.key}
|
|
1345
|
+
actions={section.actions}
|
|
1346
|
+
draft={draft}
|
|
1347
|
+
checksDisabled={checksDisabled}
|
|
1348
|
+
onToggle={onToggle}
|
|
1349
|
+
/>
|
|
1350
|
+
</CollapsibleContent>
|
|
1351
|
+
</Collapsible>
|
|
1352
|
+
)
|
|
1353
|
+
})}
|
|
1354
|
+
</div>
|
|
1355
|
+
)
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1220
1358
|
function EmptyHint({ text }: { text: string }) {
|
|
1221
1359
|
return (
|
|
1222
1360
|
<div className="flex flex-col items-center justify-center gap-2 py-12 text-muted-foreground">
|