valtech-components 4.0.20 → 4.0.22

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.
@@ -6,4 +6,65 @@ export function resolveRoleLabel(role, lang) {
6
6
  const label = role.displayName?.[lang] ?? role.displayName?.['es'] ?? role.displayName?.['en'];
7
7
  return label ?? role.name;
8
8
  }
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL29yZy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF1R0E7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLElBQWEsRUFBRSxJQUFZO0lBQzFELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9GLE9BQU8sS0FBSyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDNUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIE9yZ1R5cGUgPSAnUFJJVkFURScgfCAnUFVCTElDJyB8ICdQRVJTT05BTCcgfCAnQlVTSU5FU1MnO1xuZXhwb3J0IHR5cGUgT3JnUGxhbiA9ICdmcmVlJyB8ICdwcm8nIHwgJ2VudGVycHJpc2UnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE9yZ2FuaXphdGlvbiB7XG4gIGlkOiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIHR5cGU6IE9yZ1R5cGU7XG4gIHBsYW46IE9yZ1BsYW47XG4gIG93bmVySWQ6IHN0cmluZztcbiAgaXNBY3RpdmU6IGJvb2xlYW47XG4gIGNyZWF0ZWRBdDogc3RyaW5nO1xuICB1cGRhdGVkQXQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdE15T3Jnc1Jlc3BvbnNlIHtcbiAgb3BlcmF0aW9uSWQ6IHN0cmluZztcbiAgb3JnYW5pemF0aW9uczogT3JnYW5pemF0aW9uW107XG4gIG5leHRUb2tlbj86IHN0cmluZztcbiAgY291bnQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcmdSZXNwb25zZSB7XG4gIG9wZXJhdGlvbklkOiBzdHJpbmc7XG4gIG9yZ2FuaXphdGlvbjogT3JnYW5pemF0aW9uO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZU9yZ1JlcXVlc3Qge1xuICBuYW1lOiBzdHJpbmc7XG4gIHR5cGU6IE9yZ1R5cGU7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVwZGF0ZU9yZ1JlcXVlc3Qge1xuICBuYW1lPzogc3RyaW5nO1xuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbnZpdGVVc2VyUmVxdWVzdCB7XG4gIGVtYWlsPzogc3RyaW5nO1xuICB1c2VySWQ/OiBzdHJpbmc7XG4gIHJvbGVJZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEludml0ZVVzZXJSZXNwb25zZSB7XG4gIG9wZXJhdGlvbklkOiBzdHJpbmc7XG4gIGludml0ZVVybDogc3RyaW5nO1xuICBleHBpcmVzQXQ6IHN0cmluZztcbiAgZW1haWw6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMZWF2ZU9yZ1Jlc3BvbnNlIHtcbiAgb3BlcmF0aW9uSWQ6IHN0cmluZztcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBsZWZ0QXQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcmdNZW1iZXIge1xuICB1c2VySWQ6IHN0cmluZztcbiAgZW1haWw/OiBzdHJpbmc7XG4gIG5hbWU/OiBzdHJpbmc7XG4gIHJvbGVzOiBzdHJpbmdbXTtcbiAgYXNzaWduZWRBdD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMaXN0T3JnTWVtYmVyc1Jlc3BvbnNlIHtcbiAgb3BlcmF0aW9uSWQ6IHN0cmluZztcbiAgbWVtYmVyczogT3JnTWVtYmVyW107XG4gIG5leHRUb2tlbj86IHN0cmluZztcbiAgY291bnQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQZW5kaW5nSW52aXRhdGlvbiB7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIG9yZ05hbWU6IHN0cmluZztcbiAgcm9sZUlkOiBzdHJpbmc7XG4gIGludml0ZXJJZDogc3RyaW5nO1xuICBpbnZpdGVyTmFtZTogc3RyaW5nO1xuICBleHBpcmVzQXQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMaXN0UGVuZGluZ0ludml0YXRpb25zUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICBpdGVtczogUGVuZGluZ0ludml0YXRpb25bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBY2NlcHRJbnZpdGF0aW9uUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICBvcmdJZDogc3RyaW5nO1xuICBvcmdOYW1lOiBzdHJpbmc7XG4gIHJvbGVJZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9yZ1JvbGUge1xuICBpZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBwZXJtaXNzaW9ucz86IHN0cmluZ1tdO1xuICBpc1N5c3RlbT86IGJvb2xlYW47XG4gIC8qKiBOb21icmUgbGVnaWJsZSBwb3IgaWRpb21hLiBCYWNrZW5kIGF1dG9yaXRhdGl2byAoQURSLTAyNCkuIG5pbCBwYXJhIHJvbGVzIGN1c3RvbS4gKi9cbiAgZGlzcGxheU5hbWU/OiB7IGVzPzogc3RyaW5nOyBlbj86IHN0cmluZzsgW2xhbmc6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZCB9O1xufVxuXG4vKipcbiAqIFJlc3VlbHZlIGVsIGxhYmVsIGxlZ2libGUgZGUgdW4gcm9sIHBhcmEgZWwgaWRpb21hIGRhZG8uXG4gKiBGYWxsYmFjazogZGlzcGxheU5hbWUgZW4gb3RybyBpZGlvbWEg4oaSIHJvbGUubmFtZSAoc25ha2VfY2FzZSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlUm9sZUxhYmVsKHJvbGU6IE9yZ1JvbGUsIGxhbmc6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGxhYmVsID0gcm9sZS5kaXNwbGF5TmFtZT8uW2xhbmddID8/IHJvbGUuZGlzcGxheU5hbWU/LlsnZXMnXSA/PyByb2xlLmRpc3BsYXlOYW1lPy5bJ2VuJ107XG4gIHJldHVybiBsYWJlbCA/PyByb2xlLm5hbWU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdE9yZ1JvbGVzUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICByb2xlczogT3JnUm9sZVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENoYW5nZU1lbWJlclJvbGVSZXF1ZXN0IHtcbiAgcm9sZUlkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhbmdlTWVtYmVyUm9sZVJlc3BvbnNlIHtcbiAgb3BlcmF0aW9uSWQ6IHN0cmluZztcbiAgdXNlcklkOiBzdHJpbmc7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIHJvbGVJZDogc3RyaW5nO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gTWVtYmVyIGltcG9ydCAoQURSLTAyMykg4oCUIGNyZWFjacOzbiBkZSB1c3VhcmlvcyBwb3Igb3JnLCBzaW5nbGUgKyBidWxrLlxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IHR5cGUgSW1wb3J0T25Db25mbGljdCA9ICdhc3NpZ25Sb2xlJyB8ICdza2lwJyB8ICdlcnJvcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1wb3J0VXNlclJvdyB7XG4gIGVtYWlsOiBzdHJpbmc7XG4gIG5hbWU/OiBzdHJpbmc7XG4gIHJvbGVOYW1lOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1wb3J0TWVtYmVyc1JlcXVlc3Qge1xuICB1c2VyczogSW1wb3J0VXNlclJvd1tdO1xuICBvbkNvbmZsaWN0PzogSW1wb3J0T25Db25mbGljdDtcbiAgc2VuZEFjdGl2YXRpb24/OiBib29sZWFuO1xufVxuXG5leHBvcnQgdHlwZSBJbXBvcnRSb3dTdGF0dXMgPSAnY3JlYXRlZCcgfCAnYXNzaWduZWQnIHwgJ3NraXBwZWQnIHwgJ2Vycm9yJztcblxuZXhwb3J0IGludGVyZmFjZSBJbXBvcnRSb3dSZXN1bHQge1xuICBlbWFpbDogc3RyaW5nO1xuICBzdGF0dXM6IEltcG9ydFJvd1N0YXR1cztcbiAgdXNlcklkPzogc3RyaW5nO1xuICBhY3RpdmF0aW9uPzogJ3NlbnQnIHwgJ3BlbmRpbmcnO1xuICByZWFzb24/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1wb3J0U3VtbWFyeSB7XG4gIGNyZWF0ZWQ6IG51bWJlcjtcbiAgYXNzaWduZWQ6IG51bWJlcjtcbiAgc2tpcHBlZDogbnVtYmVyO1xuICBmYWlsZWQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbXBvcnRNZW1iZXJzUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICBzdW1tYXJ5OiBJbXBvcnRTdW1tYXJ5O1xuICByZXN1bHRzOiBJbXBvcnRSb3dSZXN1bHRbXTtcbn1cbiJdfQ==
9
+ /**
10
+ * Resuelve el label de un rol a partir de una lista de roles disponibles.
11
+ * Busca por id o name → usa resolveRoleLabel → fallback: humaniza el name.
12
+ *
13
+ * Función canónica de resolución. Reemplaza los keyMaps manuales en org-view y
14
+ * member-detail-modal. Cubre roles del sistema Y roles custom de app.
15
+ */
16
+ export function resolveRoleLabelFromList(roleIdOrName, roles, lang) {
17
+ const found = roles.find(r => r.id === roleIdOrName || r.name === roleIdOrName);
18
+ if (found)
19
+ return resolveRoleLabel(found, lang);
20
+ // Humaniza el nombre técnico como último recurso (ej. "bingo_taquilla" → "Bingo Taquilla")
21
+ return roleIdOrName
22
+ .split(/[_-]/)
23
+ .filter(Boolean)
24
+ .map(w => w.charAt(0).toUpperCase() + w.slice(1))
25
+ .join(' ');
26
+ }
27
+ /**
28
+ * Roles del sistema con displayName (es/en). Espejo de SystemRoleLabels (backend Go).
29
+ * Backend es autoritativo — esto es un seed para renders previos a la carga de la API.
30
+ */
31
+ export const SYSTEM_ROLE_DEFAULTS = [
32
+ {
33
+ id: 'viewer',
34
+ name: 'viewer',
35
+ isSystem: true,
36
+ displayName: { es: 'Visualizador', en: 'Viewer' },
37
+ },
38
+ { id: 'editor', name: 'editor', isSystem: true, displayName: { es: 'Editor', en: 'Editor' } },
39
+ {
40
+ id: 'admin',
41
+ name: 'admin',
42
+ isSystem: true,
43
+ displayName: { es: 'Administrador', en: 'Administrator' },
44
+ },
45
+ {
46
+ id: 'bingo_admin',
47
+ name: 'bingo_admin',
48
+ isSystem: true,
49
+ displayName: { es: 'Admin Bingo', en: 'Bingo Admin' },
50
+ },
51
+ {
52
+ id: 'bingo_tesorero',
53
+ name: 'bingo_tesorero',
54
+ isSystem: true,
55
+ displayName: { es: 'Tesorero', en: 'Treasurer' },
56
+ },
57
+ {
58
+ id: 'bingo_taquilla',
59
+ name: 'bingo_taquilla',
60
+ isSystem: true,
61
+ displayName: { es: 'Taquilla', en: 'Box Office' },
62
+ },
63
+ {
64
+ id: 'bingo_operator',
65
+ name: 'bingo_operator',
66
+ isSystem: true,
67
+ displayName: { es: 'Operador', en: 'Operator' },
68
+ },
69
+ ];
70
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL29yZy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF1R0E7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLElBQWEsRUFBRSxJQUFZO0lBQzFELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9GLE9BQU8sS0FBSyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDNUIsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSx3QkFBd0IsQ0FDdEMsWUFBb0IsRUFDcEIsS0FBZ0IsRUFDaEIsSUFBWTtJQUVaLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLFlBQVksSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLFlBQVksQ0FBQyxDQUFDO0lBQ2hGLElBQUksS0FBSztRQUFFLE9BQU8sZ0JBQWdCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2hELDJGQUEyRjtJQUMzRixPQUFPLFlBQVk7U0FDaEIsS0FBSyxDQUFDLE1BQU0sQ0FBQztTQUNiLE1BQU0sQ0FBQyxPQUFPLENBQUM7U0FDZixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDaEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2YsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFjO0lBQzdDO1FBQ0UsRUFBRSxFQUFFLFFBQVE7UUFDWixJQUFJLEVBQUUsUUFBUTtRQUNkLFFBQVEsRUFBRSxJQUFJO1FBQ2QsV0FBVyxFQUFFLEVBQUUsRUFBRSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFO0tBQ2xEO0lBQ0QsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsRUFBRTtJQUM3RjtRQUNFLEVBQUUsRUFBRSxPQUFPO1FBQ1gsSUFBSSxFQUFFLE9BQU87UUFDYixRQUFRLEVBQUUsSUFBSTtRQUNkLFdBQVcsRUFBRSxFQUFFLEVBQUUsRUFBRSxlQUFlLEVBQUUsRUFBRSxFQUFFLGVBQWUsRUFBRTtLQUMxRDtJQUNEO1FBQ0UsRUFBRSxFQUFFLGFBQWE7UUFDakIsSUFBSSxFQUFFLGFBQWE7UUFDbkIsUUFBUSxFQUFFLElBQUk7UUFDZCxXQUFXLEVBQUUsRUFBRSxFQUFFLEVBQUUsYUFBYSxFQUFFLEVBQUUsRUFBRSxhQUFhLEVBQUU7S0FDdEQ7SUFDRDtRQUNFLEVBQUUsRUFBRSxnQkFBZ0I7UUFDcEIsSUFBSSxFQUFFLGdCQUFnQjtRQUN0QixRQUFRLEVBQUUsSUFBSTtRQUNkLFdBQVcsRUFBRSxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLFdBQVcsRUFBRTtLQUNqRDtJQUNEO1FBQ0UsRUFBRSxFQUFFLGdCQUFnQjtRQUNwQixJQUFJLEVBQUUsZ0JBQWdCO1FBQ3RCLFFBQVEsRUFBRSxJQUFJO1FBQ2QsV0FBVyxFQUFFLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsWUFBWSxFQUFFO0tBQ2xEO0lBQ0Q7UUFDRSxFQUFFLEVBQUUsZ0JBQWdCO1FBQ3BCLElBQUksRUFBRSxnQkFBZ0I7UUFDdEIsUUFBUSxFQUFFLElBQUk7UUFDZCxXQUFXLEVBQUUsRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUU7S0FDaEQ7Q0FDRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgT3JnVHlwZSA9ICdQUklWQVRFJyB8ICdQVUJMSUMnIHwgJ1BFUlNPTkFMJyB8ICdCVVNJTkVTUyc7XG5leHBvcnQgdHlwZSBPcmdQbGFuID0gJ2ZyZWUnIHwgJ3BybycgfCAnZW50ZXJwcmlzZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3JnYW5pemF0aW9uIHtcbiAgaWQ6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgdHlwZTogT3JnVHlwZTtcbiAgcGxhbjogT3JnUGxhbjtcbiAgb3duZXJJZDogc3RyaW5nO1xuICBpc0FjdGl2ZTogYm9vbGVhbjtcbiAgY3JlYXRlZEF0OiBzdHJpbmc7XG4gIHVwZGF0ZWRBdD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMaXN0TXlPcmdzUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICBvcmdhbml6YXRpb25zOiBPcmdhbml6YXRpb25bXTtcbiAgbmV4dFRva2VuPzogc3RyaW5nO1xuICBjb3VudDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9yZ1Jlc3BvbnNlIHtcbiAgb3BlcmF0aW9uSWQ6IHN0cmluZztcbiAgb3JnYW5pemF0aW9uOiBPcmdhbml6YXRpb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlT3JnUmVxdWVzdCB7XG4gIG5hbWU6IHN0cmluZztcbiAgdHlwZTogT3JnVHlwZTtcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXBkYXRlT3JnUmVxdWVzdCB7XG4gIG5hbWU/OiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEludml0ZVVzZXJSZXF1ZXN0IHtcbiAgZW1haWw/OiBzdHJpbmc7XG4gIHVzZXJJZD86IHN0cmluZztcbiAgcm9sZUlkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW52aXRlVXNlclJlc3BvbnNlIHtcbiAgb3BlcmF0aW9uSWQ6IHN0cmluZztcbiAgaW52aXRlVXJsOiBzdHJpbmc7XG4gIGV4cGlyZXNBdDogc3RyaW5nO1xuICBlbWFpbDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExlYXZlT3JnUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIGxlZnRBdDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9yZ01lbWJlciB7XG4gIHVzZXJJZDogc3RyaW5nO1xuICBlbWFpbD86IHN0cmluZztcbiAgbmFtZT86IHN0cmluZztcbiAgcm9sZXM6IHN0cmluZ1tdO1xuICBhc3NpZ25lZEF0Pzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpc3RPcmdNZW1iZXJzUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICBtZW1iZXJzOiBPcmdNZW1iZXJbXTtcbiAgbmV4dFRva2VuPzogc3RyaW5nO1xuICBjb3VudDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBlbmRpbmdJbnZpdGF0aW9uIHtcbiAgb3JnSWQ6IHN0cmluZztcbiAgb3JnTmFtZTogc3RyaW5nO1xuICByb2xlSWQ6IHN0cmluZztcbiAgaW52aXRlcklkOiBzdHJpbmc7XG4gIGludml0ZXJOYW1lOiBzdHJpbmc7XG4gIGV4cGlyZXNBdDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpc3RQZW5kaW5nSW52aXRhdGlvbnNSZXNwb25zZSB7XG4gIG9wZXJhdGlvbklkOiBzdHJpbmc7XG4gIGl0ZW1zOiBQZW5kaW5nSW52aXRhdGlvbltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFjY2VwdEludml0YXRpb25SZXNwb25zZSB7XG4gIG9wZXJhdGlvbklkOiBzdHJpbmc7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIG9yZ05hbWU6IHN0cmluZztcbiAgcm9sZUlkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3JnUm9sZSB7XG4gIGlkOiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIHBlcm1pc3Npb25zPzogc3RyaW5nW107XG4gIGlzU3lzdGVtPzogYm9vbGVhbjtcbiAgLyoqIE5vbWJyZSBsZWdpYmxlIHBvciBpZGlvbWEuIEJhY2tlbmQgYXV0b3JpdGF0aXZvIChBRFItMDI0KS4gbmlsIHBhcmEgcm9sZXMgY3VzdG9tLiAqL1xuICBkaXNwbGF5TmFtZT86IHsgZXM/OiBzdHJpbmc7IGVuPzogc3RyaW5nOyBbbGFuZzogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkIH07XG59XG5cbi8qKlxuICogUmVzdWVsdmUgZWwgbGFiZWwgbGVnaWJsZSBkZSB1biByb2wgcGFyYSBlbCBpZGlvbWEgZGFkby5cbiAqIEZhbGxiYWNrOiBkaXNwbGF5TmFtZSBlbiBvdHJvIGlkaW9tYSDihpIgcm9sZS5uYW1lIChzbmFrZV9jYXNlKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVSb2xlTGFiZWwocm9sZTogT3JnUm9sZSwgbGFuZzogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgbGFiZWwgPSByb2xlLmRpc3BsYXlOYW1lPy5bbGFuZ10gPz8gcm9sZS5kaXNwbGF5TmFtZT8uWydlcyddID8/IHJvbGUuZGlzcGxheU5hbWU/LlsnZW4nXTtcbiAgcmV0dXJuIGxhYmVsID8/IHJvbGUubmFtZTtcbn1cblxuLyoqXG4gKiBSZXN1ZWx2ZSBlbCBsYWJlbCBkZSB1biByb2wgYSBwYXJ0aXIgZGUgdW5hIGxpc3RhIGRlIHJvbGVzIGRpc3BvbmlibGVzLlxuICogQnVzY2EgcG9yIGlkIG8gbmFtZSDihpIgdXNhIHJlc29sdmVSb2xlTGFiZWwg4oaSIGZhbGxiYWNrOiBodW1hbml6YSBlbCBuYW1lLlxuICpcbiAqIEZ1bmNpw7NuIGNhbsOzbmljYSBkZSByZXNvbHVjacOzbi4gUmVlbXBsYXphIGxvcyBrZXlNYXBzIG1hbnVhbGVzIGVuIG9yZy12aWV3IHlcbiAqIG1lbWJlci1kZXRhaWwtbW9kYWwuIEN1YnJlIHJvbGVzIGRlbCBzaXN0ZW1hIFkgcm9sZXMgY3VzdG9tIGRlIGFwcC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVSb2xlTGFiZWxGcm9tTGlzdChcbiAgcm9sZUlkT3JOYW1lOiBzdHJpbmcsXG4gIHJvbGVzOiBPcmdSb2xlW10sXG4gIGxhbmc6IHN0cmluZ1xuKTogc3RyaW5nIHtcbiAgY29uc3QgZm91bmQgPSByb2xlcy5maW5kKHIgPT4gci5pZCA9PT0gcm9sZUlkT3JOYW1lIHx8IHIubmFtZSA9PT0gcm9sZUlkT3JOYW1lKTtcbiAgaWYgKGZvdW5kKSByZXR1cm4gcmVzb2x2ZVJvbGVMYWJlbChmb3VuZCwgbGFuZyk7XG4gIC8vIEh1bWFuaXphIGVsIG5vbWJyZSB0w6ljbmljbyBjb21vIMO6bHRpbW8gcmVjdXJzbyAoZWouIFwiYmluZ29fdGFxdWlsbGFcIiDihpIgXCJCaW5nbyBUYXF1aWxsYVwiKVxuICByZXR1cm4gcm9sZUlkT3JOYW1lXG4gICAgLnNwbGl0KC9bXy1dLylcbiAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgLm1hcCh3ID0+IHcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyB3LnNsaWNlKDEpKVxuICAgIC5qb2luKCcgJyk7XG59XG5cbi8qKlxuICogUm9sZXMgZGVsIHNpc3RlbWEgY29uIGRpc3BsYXlOYW1lIChlcy9lbikuIEVzcGVqbyBkZSBTeXN0ZW1Sb2xlTGFiZWxzIChiYWNrZW5kIEdvKS5cbiAqIEJhY2tlbmQgZXMgYXV0b3JpdGF0aXZvIOKAlCBlc3RvIGVzIHVuIHNlZWQgcGFyYSByZW5kZXJzIHByZXZpb3MgYSBsYSBjYXJnYSBkZSBsYSBBUEkuXG4gKi9cbmV4cG9ydCBjb25zdCBTWVNURU1fUk9MRV9ERUZBVUxUUzogT3JnUm9sZVtdID0gW1xuICB7XG4gICAgaWQ6ICd2aWV3ZXInLFxuICAgIG5hbWU6ICd2aWV3ZXInLFxuICAgIGlzU3lzdGVtOiB0cnVlLFxuICAgIGRpc3BsYXlOYW1lOiB7IGVzOiAnVmlzdWFsaXphZG9yJywgZW46ICdWaWV3ZXInIH0sXG4gIH0sXG4gIHsgaWQ6ICdlZGl0b3InLCBuYW1lOiAnZWRpdG9yJywgaXNTeXN0ZW06IHRydWUsIGRpc3BsYXlOYW1lOiB7IGVzOiAnRWRpdG9yJywgZW46ICdFZGl0b3InIH0gfSxcbiAge1xuICAgIGlkOiAnYWRtaW4nLFxuICAgIG5hbWU6ICdhZG1pbicsXG4gICAgaXNTeXN0ZW06IHRydWUsXG4gICAgZGlzcGxheU5hbWU6IHsgZXM6ICdBZG1pbmlzdHJhZG9yJywgZW46ICdBZG1pbmlzdHJhdG9yJyB9LFxuICB9LFxuICB7XG4gICAgaWQ6ICdiaW5nb19hZG1pbicsXG4gICAgbmFtZTogJ2JpbmdvX2FkbWluJyxcbiAgICBpc1N5c3RlbTogdHJ1ZSxcbiAgICBkaXNwbGF5TmFtZTogeyBlczogJ0FkbWluIEJpbmdvJywgZW46ICdCaW5nbyBBZG1pbicgfSxcbiAgfSxcbiAge1xuICAgIGlkOiAnYmluZ29fdGVzb3Jlcm8nLFxuICAgIG5hbWU6ICdiaW5nb190ZXNvcmVybycsXG4gICAgaXNTeXN0ZW06IHRydWUsXG4gICAgZGlzcGxheU5hbWU6IHsgZXM6ICdUZXNvcmVybycsIGVuOiAnVHJlYXN1cmVyJyB9LFxuICB9LFxuICB7XG4gICAgaWQ6ICdiaW5nb190YXF1aWxsYScsXG4gICAgbmFtZTogJ2JpbmdvX3RhcXVpbGxhJyxcbiAgICBpc1N5c3RlbTogdHJ1ZSxcbiAgICBkaXNwbGF5TmFtZTogeyBlczogJ1RhcXVpbGxhJywgZW46ICdCb3ggT2ZmaWNlJyB9LFxuICB9LFxuICB7XG4gICAgaWQ6ICdiaW5nb19vcGVyYXRvcicsXG4gICAgbmFtZTogJ2JpbmdvX29wZXJhdG9yJyxcbiAgICBpc1N5c3RlbTogdHJ1ZSxcbiAgICBkaXNwbGF5TmFtZTogeyBlczogJ09wZXJhZG9yJywgZW46ICdPcGVyYXRvcicgfSxcbiAgfSxcbl07XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdE9yZ1JvbGVzUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICByb2xlczogT3JnUm9sZVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENoYW5nZU1lbWJlclJvbGVSZXF1ZXN0IHtcbiAgcm9sZUlkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhbmdlTWVtYmVyUm9sZVJlc3BvbnNlIHtcbiAgb3BlcmF0aW9uSWQ6IHN0cmluZztcbiAgdXNlcklkOiBzdHJpbmc7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIHJvbGVJZDogc3RyaW5nO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gTWVtYmVyIGltcG9ydCAoQURSLTAyMykg4oCUIGNyZWFjacOzbiBkZSB1c3VhcmlvcyBwb3Igb3JnLCBzaW5nbGUgKyBidWxrLlxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IHR5cGUgSW1wb3J0T25Db25mbGljdCA9ICdhc3NpZ25Sb2xlJyB8ICdza2lwJyB8ICdlcnJvcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1wb3J0VXNlclJvdyB7XG4gIGVtYWlsOiBzdHJpbmc7XG4gIG5hbWU/OiBzdHJpbmc7XG4gIHJvbGVOYW1lOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1wb3J0TWVtYmVyc1JlcXVlc3Qge1xuICB1c2VyczogSW1wb3J0VXNlclJvd1tdO1xuICBvbkNvbmZsaWN0PzogSW1wb3J0T25Db25mbGljdDtcbiAgc2VuZEFjdGl2YXRpb24/OiBib29sZWFuO1xufVxuXG5leHBvcnQgdHlwZSBJbXBvcnRSb3dTdGF0dXMgPSAnY3JlYXRlZCcgfCAnYXNzaWduZWQnIHwgJ3NraXBwZWQnIHwgJ2Vycm9yJztcblxuZXhwb3J0IGludGVyZmFjZSBJbXBvcnRSb3dSZXN1bHQge1xuICBlbWFpbDogc3RyaW5nO1xuICBzdGF0dXM6IEltcG9ydFJvd1N0YXR1cztcbiAgdXNlcklkPzogc3RyaW5nO1xuICBhY3RpdmF0aW9uPzogJ3NlbnQnIHwgJ3BlbmRpbmcnO1xuICByZWFzb24/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1wb3J0U3VtbWFyeSB7XG4gIGNyZWF0ZWQ6IG51bWJlcjtcbiAgYXNzaWduZWQ6IG51bWJlcjtcbiAgc2tpcHBlZDogbnVtYmVyO1xuICBmYWlsZWQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbXBvcnRNZW1iZXJzUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICBzdW1tYXJ5OiBJbXBvcnRTdW1tYXJ5O1xuICByZXN1bHRzOiBJbXBvcnRSb3dSZXN1bHRbXTtcbn1cbiJdfQ==
@@ -2,5 +2,5 @@
2
2
  * Current version of valtech-components.
3
3
  * This is automatically updated during the publish process.
4
4
  */
5
- export const VERSION = '4.0.20';
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDdXJyZW50IHZlcnNpb24gb2YgdmFsdGVjaC1jb21wb25lbnRzLlxuICogVGhpcyBpcyBhdXRvbWF0aWNhbGx5IHVwZGF0ZWQgZHVyaW5nIHRoZSBwdWJsaXNoIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gJzQuMC4yMCc7XG4iXX0=
5
+ export const VERSION = '4.0.22';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDdXJyZW50IHZlcnNpb24gb2YgdmFsdGVjaC1jb21wb25lbnRzLlxuICogVGhpcyBpcyBhdXRvbWF0aWNhbGx5IHVwZGF0ZWQgZHVyaW5nIHRoZSBwdWJsaXNoIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gJzQuMC4yMic7XG4iXX0=
@@ -56,7 +56,7 @@ import { BrowserMultiFormatReader } from '@zxing/browser';
56
56
  * Current version of valtech-components.
57
57
  * This is automatically updated during the publish process.
58
58
  */
59
- const VERSION = '4.0.20';
59
+ const VERSION = '4.0.22';
60
60
 
61
61
  // Control de estado de refresco (singleton a nivel de módulo)
62
62
  let isRefreshing = false;
@@ -45342,7 +45342,9 @@ class ModalService {
45342
45342
  // content) or fights the breakpoint height. So when it's a sheet we skip
45343
45343
  // the size preset entirely.
45344
45344
  const isSheet = !!options.breakpoints?.breakpoints?.length;
45345
- const size = isSheet ? undefined : MODAL_SIZES[options.size || 'medium'];
45345
+ // Only apply a size preset when explicitly requested callers that rely on
45346
+ // CSS class sizing (e.g. openAdaptive) must not have inline styles overriding them.
45347
+ const size = isSheet ? undefined : options.size ? MODAL_SIZES[options.size] : undefined;
45346
45348
  const cssClasses = this.buildCssClasses(options);
45347
45349
  const modal = await this.modalController.create({
45348
45350
  component: options.component,
@@ -48470,6 +48472,76 @@ function provideValtechAccountRoutes(opts) {
48470
48472
  ];
48471
48473
  }
48472
48474
 
48475
+ /**
48476
+ * Resuelve el label legible de un rol para el idioma dado.
48477
+ * Fallback: displayName en otro idioma → role.name (snake_case).
48478
+ */
48479
+ function resolveRoleLabel(role, lang) {
48480
+ const label = role.displayName?.[lang] ?? role.displayName?.['es'] ?? role.displayName?.['en'];
48481
+ return label ?? role.name;
48482
+ }
48483
+ /**
48484
+ * Resuelve el label de un rol a partir de una lista de roles disponibles.
48485
+ * Busca por id o name → usa resolveRoleLabel → fallback: humaniza el name.
48486
+ *
48487
+ * Función canónica de resolución. Reemplaza los keyMaps manuales en org-view y
48488
+ * member-detail-modal. Cubre roles del sistema Y roles custom de app.
48489
+ */
48490
+ function resolveRoleLabelFromList(roleIdOrName, roles, lang) {
48491
+ const found = roles.find(r => r.id === roleIdOrName || r.name === roleIdOrName);
48492
+ if (found)
48493
+ return resolveRoleLabel(found, lang);
48494
+ // Humaniza el nombre técnico como último recurso (ej. "bingo_taquilla" → "Bingo Taquilla")
48495
+ return roleIdOrName
48496
+ .split(/[_-]/)
48497
+ .filter(Boolean)
48498
+ .map(w => w.charAt(0).toUpperCase() + w.slice(1))
48499
+ .join(' ');
48500
+ }
48501
+ /**
48502
+ * Roles del sistema con displayName (es/en). Espejo de SystemRoleLabels (backend Go).
48503
+ * Backend es autoritativo — esto es un seed para renders previos a la carga de la API.
48504
+ */
48505
+ const SYSTEM_ROLE_DEFAULTS = [
48506
+ {
48507
+ id: 'viewer',
48508
+ name: 'viewer',
48509
+ isSystem: true,
48510
+ displayName: { es: 'Visualizador', en: 'Viewer' },
48511
+ },
48512
+ { id: 'editor', name: 'editor', isSystem: true, displayName: { es: 'Editor', en: 'Editor' } },
48513
+ {
48514
+ id: 'admin',
48515
+ name: 'admin',
48516
+ isSystem: true,
48517
+ displayName: { es: 'Administrador', en: 'Administrator' },
48518
+ },
48519
+ {
48520
+ id: 'bingo_admin',
48521
+ name: 'bingo_admin',
48522
+ isSystem: true,
48523
+ displayName: { es: 'Admin Bingo', en: 'Bingo Admin' },
48524
+ },
48525
+ {
48526
+ id: 'bingo_tesorero',
48527
+ name: 'bingo_tesorero',
48528
+ isSystem: true,
48529
+ displayName: { es: 'Tesorero', en: 'Treasurer' },
48530
+ },
48531
+ {
48532
+ id: 'bingo_taquilla',
48533
+ name: 'bingo_taquilla',
48534
+ isSystem: true,
48535
+ displayName: { es: 'Taquilla', en: 'Box Office' },
48536
+ },
48537
+ {
48538
+ id: 'bingo_operator',
48539
+ name: 'bingo_operator',
48540
+ isSystem: true,
48541
+ displayName: { es: 'Operador', en: 'Operator' },
48542
+ },
48543
+ ];
48544
+
48473
48545
  /**
48474
48546
  * Defaults i18n (es/en) embebidos en `val-edit-org-modal`. Auto-registrados en
48475
48547
  * el constructor del componente si el consumer no proveyó el namespace
@@ -48722,15 +48794,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
48722
48794
  type: Input
48723
48795
  }] } });
48724
48796
 
48725
- /**
48726
- * Resuelve el label legible de un rol para el idioma dado.
48727
- * Fallback: displayName en otro idioma → role.name (snake_case).
48728
- */
48729
- function resolveRoleLabel(role, lang) {
48730
- const label = role.displayName?.[lang] ?? role.displayName?.['es'] ?? role.displayName?.['en'];
48731
- return label ?? role.name;
48732
- }
48733
-
48734
48797
  /**
48735
48798
  * Defaults i18n (es/en) embebidos en `val-invite-member-modal`. Auto-registrados
48736
48799
  * en el constructor del componente si el consumer no proveyó el namespace
@@ -48823,11 +48886,7 @@ class InviteMemberModalComponent {
48823
48886
  this.selectedUsers = signal([]);
48824
48887
  this.sending = signal(false);
48825
48888
  this.selectedRole = signal('viewer');
48826
- this.availableRoles = signal([
48827
- { id: 'viewer', name: 'viewer' },
48828
- { id: 'editor', name: 'editor' },
48829
- { id: 'admin', name: 'admin' },
48830
- ]);
48889
+ this.availableRoles = signal(SYSTEM_ROLE_DEFAULTS);
48831
48890
  this.roleControl = new FormControl('viewer');
48832
48891
  this.roleSelectProps = computed(() => ({
48833
48892
  control: this.roleControl,
@@ -48866,7 +48925,6 @@ class InviteMemberModalComponent {
48866
48925
  if (!this.i18n.hasNamespace(DEFAULT_NAMESPACE$b)) {
48867
48926
  this.i18n.registerContent(DEFAULT_NAMESPACE$b, INVITE_MEMBER_MODAL_I18N);
48868
48927
  }
48869
- this.loadRoles();
48870
48928
  this.roleSub = this.roleControl.valueChanges.subscribe(v => {
48871
48929
  if (v)
48872
48930
  this.selectedRole.set(v);
@@ -49013,6 +49071,11 @@ class InviteMemberModalComponent {
49013
49071
  this.sending.set(false);
49014
49072
  }
49015
49073
  }
49074
+ ngOnInit() {
49075
+ // loadRoles aquí (no en constructor) para que @Input() orgId ya esté asignado
49076
+ // por ModalController antes de que corra el hook de inicialización.
49077
+ this.loadRoles();
49078
+ }
49016
49079
  ngOnDestroy() {
49017
49080
  this.roleSub?.unsubscribe();
49018
49081
  }
@@ -49649,18 +49712,7 @@ class MemberDetailModalComponent {
49649
49712
  }
49650
49713
  }
49651
49714
  roleLabel(roleIdOrName) {
49652
- // Try to find by id first (post-change, UUID stored), then by name (initial load)
49653
- const found = this.availableRoles.find(r => r.id === roleIdOrName || r.name === roleIdOrName);
49654
- const name = found?.name ?? roleIdOrName;
49655
- const keyMap = {
49656
- viewer: 'roleViewer',
49657
- editor: 'roleEditor',
49658
- admin: 'roleAdmin',
49659
- super_admin: 'roleSuperAdmin',
49660
- };
49661
- const key = keyMap[name] ?? name;
49662
- const label = this.t(key);
49663
- return label && !label.startsWith('[') ? label : name;
49715
+ return resolveRoleLabelFromList(roleIdOrName, this.availableRoles, this.i18n.lang());
49664
49716
  }
49665
49717
  ngOnDestroy() {
49666
49718
  this.roleSub?.unsubscribe();
@@ -50927,11 +50979,7 @@ class OrganizationViewComponent {
50927
50979
  this.showAllMembers = signal(false);
50928
50980
  this.visibleMembers = computed(() => (this.showAllMembers() ? this.members() : this.members().slice(0, 3)));
50929
50981
  this.transferring = signal(false);
50930
- this.availableRoles = signal([
50931
- { id: 'viewer', name: 'viewer' },
50932
- { id: 'editor', name: 'editor' },
50933
- { id: 'admin', name: 'admin' },
50934
- ]);
50982
+ this.availableRoles = signal(SYSTEM_ROLE_DEFAULTS);
50935
50983
  this.activeOrgId = computed(() => {
50936
50984
  const u = this.auth.user();
50937
50985
  return u?.activeOrgId ?? u?.activeOrg ?? '';
@@ -51330,31 +51378,7 @@ class OrganizationViewComponent {
51330
51378
  });
51331
51379
  }
51332
51380
  roleLabel(roleIdOrName) {
51333
- // Try to find by id first (UUID), then by name
51334
- const found = this.availableRoles().find(r => r.id === roleIdOrName || r.name === roleIdOrName);
51335
- const name = found?.name ?? roleIdOrName;
51336
- const keyMap = {
51337
- viewer: 'roleViewer',
51338
- editor: 'roleEditor',
51339
- admin: 'roleAdmin',
51340
- super_admin: 'roleSuperAdmin',
51341
- };
51342
- // 1) Rol genérico conocido → label i18n. 2) displayName/descripción del backend.
51343
- // 3) Fallback: humanizar el nombre crudo (ej. "bingo_admin" → "Bingo Admin")
51344
- // para no mostrar el código técnico a app-specific roles.
51345
- const mapped = keyMap[name];
51346
- if (mapped) {
51347
- const label = this.tt(mapped);
51348
- if (label && !label.startsWith('['))
51349
- return label;
51350
- }
51351
- if (found?.description)
51352
- return found.description;
51353
- return name
51354
- .split(/[_-]/)
51355
- .filter(Boolean)
51356
- .map(w => w.charAt(0).toUpperCase() + w.slice(1))
51357
- .join(' ');
51381
+ return resolveRoleLabelFromList(roleIdOrName, this.availableRoles(), this.i18n.lang());
51358
51382
  }
51359
51383
  onViewMember(member) {
51360
51384
  void this.modalService.openAdaptive({