import * as React from 'react'; export interface PermissionActionDef { /** Canonical action key (`index`, `create`, …, a custom `pagar`, or `access`). */ key: string; /** Localized label ("Listar", "Pagar", "Acceder"). */ label: string; /** * Optional secondary line under the label (e.g. action name when the label * is the module — used by screen → API shortcut checkboxes). */ description?: string; /** Lucide icon name from the manifest action (optional). */ icon?: string; /** * `crud` for the derived CRUD set, `custom` for manifest actions, * `screen` for the single `access` action of a non-model screen. * `dependency` for a shortcut to another module's capability (see * {@link capability}). */ kind?: 'crud' | 'custom' | 'screen' | 'dependency' | string; /** * Full capability string override. When set, the grant uses this exact key * instead of `${moduleKey}.${key}` — hosts use it so a screen (Terminal) * can show checkboxes for other modules' caps (`product.index`, …) as * shortcuts without inventing `screen….product.index`. */ capability?: string; /** * Optional section title for the action grid (e.g. "Catálogo", "Ventas"). * When any action on a module sets `group`, the right-hand panel renders * collapsible sections instead of one flat checkbox grid. */ group?: string; } export interface PermissionModuleDef { /** * Module key. * - model: lowercase model table (`pos_orders`). * - screen: `screen.` (the host prefixes it). */ key: string; /** Localized module label ("Pedidos POS", "Terminal"). */ label: string; /** Module icon (lucide name) — mirrors the sidebar entry. */ icon?: string; /** Whether this entry is a data model or a non-model screen. */ kind?: 'model' | 'screen'; /** Owning addon key (`pos`) — legacy shape only, used for grouping. */ addon_key?: string; /** Localized addon label ("Punto de venta") — legacy shape only. */ addon_label?: string; actions: PermissionActionDef[]; } /** * A sidebar-style group: a grey (non-collapsible) header + its modules. * `title === ''` → no header (e.g. core/infra modules). */ export interface ModuleGroup { title: string; modules: PermissionModuleDef[]; } export interface GeneralPermissionDef { /** Full capability key (`general.work_after_hours`). */ key: string; label: string; description?: string; } /** * What `loadModules()` may return. * * New (preferred) shape — pre-grouped flat list, mirrors the host sidebar: * { groups: ModuleGroup[], general } * * Legacy shape (still accepted, wrapped into a single untitled group) — * { modules: PermissionModuleDef[], general } */ export interface GroupedPermissionsCatalog { groups: ModuleGroup[]; general: GeneralPermissionDef[]; } export interface FlatPermissionsCatalog { modules: PermissionModuleDef[]; general: GeneralPermissionDef[]; } export type PermissionsCatalog = GroupedPermissionsCatalog | FlatPermissionsCatalog; export interface RoleDef { id: string; /** Stable role key ("cashier"). */ name: string; /** Human label ("Cajero"). Falls back to `name` when omitted. */ label?: string; /** Accent color (hex) for the role chip. */ color?: string; /** Lucide PascalCase name (or image path) for the role chip. */ icon?: string; } export interface RoleInput { name: string; label?: string; color?: string; icon?: string; } export interface PermissionsManagerProps { /** Loads the module×action universe + general flags (grouped or flat). */ loadModules: () => Promise; /** Loads every assignable role. */ loadRoles: () => Promise; /** Loads the capabilities currently granted to a role. */ loadRolePermissions: (roleId: string) => Promise; /** Persists the FULL granted capability set of a role. */ syncRolePermissions: (roleId: string, capabilities: string[]) => Promise; /** Optional role CRUD — omitting one hides its control. */ createRole?: (input: RoleInput) => Promise; updateRole?: (roleId: string, input: RoleInput) => Promise; deleteRole?: (roleId: string) => Promise; /** Page heading. Defaults to "Permisos y Roles". */ title?: string; className?: string; } /** Capability for a catalog module action: `lowercase(moduleKey).actionKey`, * or {@link PermissionActionDef.capability} when the action is a cross-module * shortcut. */ export declare function moduleActionCapability(moduleKey: string, actionKey: string, capability?: string): string; /** All capabilities of one module. */ export declare function moduleCapabilities(module: PermissionModuleDef): string[]; export interface ActionGroupSection { /** Empty string = ungrouped actions rendered above the collapsibles. */ title: string; actions: PermissionActionDef[]; } /** * Split a module's actions into an optional ungrouped prefix + named sections * (first-seen order of `action.group`). Modules without any `group` yield a * single untitled section (flat grid, backward compatible). */ export declare function groupModuleActions(actions: PermissionActionDef[]): ActionGroupSection[]; /** How many of the module's capabilities are in the granted set. */ export declare function grantedCountForModule(granted: ReadonlySet, module: PermissionModuleDef): number; export declare function capabilitySetsEqual(a: ReadonlySet, b: ReadonlySet): boolean; /** Default lucide icon when the manifest action doesn't declare one. */ export declare function defaultActionIcon(actionKey: string, kind?: string): string; /** Suggest a Lucide icon from the role label (create-dialog default). */ export declare function suggestRoleIcon(label: string): string; /** * Normalize whatever `loadModules` returned into the canonical grouped shape. * * - New shape (`{ groups }`): passed through (modules default to kind:'model'). * - Legacy flat shape (`{ modules }`): grouped by `addon_label`/`addon_key` * (falling back to "Sistema") so old hosts keep their familiar buckets, * every module defaulting to kind:'model'. The grey headers still render, * just derived from the addon instead of the sidebar group. */ export declare function normalizeCatalogGroups(catalog: PermissionsCatalog): ModuleGroup[]; /** Flat list of every module across groups, in render order. */ export declare function flattenGroups(groups: ModuleGroup[]): PermissionModuleDef[]; /** Filter the grouped flat list by a folded query against module + group titles. */ export declare function filterModuleGroups(groups: ModuleGroup[], query: string): ModuleGroup[]; export declare function PermissionsManager({ loadModules, loadRoles, loadRolePermissions, syncRolePermissions, createRole, updateRole, deleteRole, title, className, }: PermissionsManagerProps): React.JSX.Element; //# sourceMappingURL=permissions-manager.d.ts.map