@elasticias/core 1.0.39 → 1.0.41

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, Injector, signal, PLATFORM_ID, computed, effect, InjectionToken, DestroyRef } from '@angular/core';
2
+ import { Injectable, inject, Injector, signal, InjectionToken, PLATFORM_ID, computed, DestroyRef, effect } from '@angular/core';
3
3
  import { BehaviorSubject } from 'rxjs';
4
4
  import { StorageUtils } from '@elasticias/utils';
5
5
  import { TranslateService, TranslateLoader } from '@ngx-translate/core';
@@ -481,6 +481,55 @@ function hasScreenPermission(screenCode, permission, grantsStorageKey = 'CURRENT
481
481
  return grant?.permissions?.includes(permission) ?? false;
482
482
  }
483
483
 
484
+ /** localStorage key of the app-shell side-panel fold ('1' collapsed, '0' open). Not prefixed. */
485
+ const EF_SIDE_COLLAPSED_KEY = 'ef.shell.side-collapsed';
486
+ /** Key for a preference that StorageUtils has always stored under its prefix (`Elasticias_` by default). */
487
+ function efPrefKey(name) {
488
+ return `${StorageUtils.prefix}${name}`;
489
+ }
490
+ /** Prefix of the per-table key family: `efTablePrefsKey(tableKey)` is the full key. */
491
+ const EF_TABLE_PREFS_PREFIX = 'TABLE_PREFS_';
492
+ /** Full key of one table's density / hidden-columns preference (`Elasticias_TABLE_PREFS_<tableKey>`). */
493
+ function efTablePrefsKey(tableKey) {
494
+ return efPrefKey(`${EF_TABLE_PREFS_PREFIX}${tableKey}`);
495
+ }
496
+ /** localStorage, never throwing: a private window or blocked site data just means nothing is remembered. */
497
+ class LocalStoragePreferenceStore {
498
+ get(key) {
499
+ try {
500
+ return localStorage.getItem(key);
501
+ }
502
+ catch {
503
+ return null;
504
+ }
505
+ }
506
+ set(key, value) {
507
+ try {
508
+ localStorage.setItem(key, value);
509
+ }
510
+ catch {
511
+ /* the preference holds for this visit only */
512
+ }
513
+ }
514
+ remove(key) {
515
+ try {
516
+ localStorage.removeItem(key);
517
+ }
518
+ catch {
519
+ /* nothing to remove from */
520
+ }
521
+ }
522
+ }
523
+ /**
524
+ * Preference store. Defaults to localStorage with the historical keys, so
525
+ * nothing changes unless an app provides its own:
526
+ * `{ provide: EF_PREFERENCE_STORE, useClass: ServerPreferenceStore }`.
527
+ */
528
+ const EF_PREFERENCE_STORE = new InjectionToken('EF_PREFERENCE_STORE', {
529
+ providedIn: 'root',
530
+ factory: () => new LocalStoragePreferenceStore(),
531
+ });
532
+
484
533
  const DEFAULT_APP_STATE = {
485
534
  preset: 'Lara',
486
535
  primary: 'noir',
@@ -499,7 +548,10 @@ const DEFAULT_APP_STATE = {
499
548
  * Apps can extend this service or use it directly.
500
549
  */
501
550
  class EfThemeConfigService {
502
- STORAGE_KEY = 'APP_CONFIG_STATE';
551
+ STORAGE_NAME = 'APP_CONFIG_STATE';
552
+ prefs = inject(EF_PREFERENCE_STORE);
553
+ /** Serialized state last adopted from the store; saving it back would only echo. */
554
+ fromStore = null;
503
555
  appState = signal(null, ...(ngDevMode ? [{ debugName: "appState" }] : /* istanbul ignore next */ []));
504
556
  designerActive = signal(false, ...(ngDevMode ? [{ debugName: "designerActive" }] : /* istanbul ignore next */ []));
505
557
  newsActive = signal(false, ...(ngDevMode ? [{ debugName: "newsActive" }] : /* istanbul ignore next */ []));
@@ -518,6 +570,23 @@ class EfThemeConfigService {
518
570
  if (isPlatformBrowser(this.platformId) && initialState?.RTL) {
519
571
  this.document.documentElement.setAttribute('dir', 'rtl');
520
572
  }
573
+ // A store that hydrates after sign in announces it. The stored value
574
+ // may be a PARTIAL AppState (a server only knows some fields), so it
575
+ // is merged over the live state; a removed key resets to defaults.
576
+ // Either way the result is not written back: it came from the store.
577
+ const sub = this.prefs.changes?.subscribe((key) => {
578
+ if (key !== efPrefKey(this.STORAGE_NAME))
579
+ return;
580
+ const stored = this.readStoredState();
581
+ const next = stored
582
+ ? { ...this.appState(), ...stored }
583
+ : { ...DEFAULT_APP_STATE };
584
+ if (JSON.stringify(next) === JSON.stringify(this.appState()))
585
+ return;
586
+ this.fromStore = JSON.stringify(next);
587
+ this.appState.set(next);
588
+ });
589
+ inject(DestroyRef).onDestroy(() => sub?.unsubscribe());
521
590
  effect(() => {
522
591
  const state = this.appState();
523
592
  if (!state)
@@ -639,16 +708,34 @@ class EfThemeConfigService {
639
708
  }
640
709
  loadAppState() {
641
710
  if (isPlatformBrowser(this.platformId)) {
642
- const storedState = StorageUtils.getLocal(this.STORAGE_KEY);
711
+ const storedState = this.readStoredState();
643
712
  if (storedState) {
644
713
  return storedState;
645
714
  }
646
715
  }
647
716
  return { ...DEFAULT_APP_STATE };
648
717
  }
718
+ readStoredState() {
719
+ const raw = this.prefs.get(efPrefKey(this.STORAGE_NAME));
720
+ if (!raw)
721
+ return null;
722
+ try {
723
+ return JSON.parse(raw);
724
+ }
725
+ catch {
726
+ return null;
727
+ }
728
+ }
649
729
  saveAppState(state) {
650
730
  if (isPlatformBrowser(this.platformId)) {
651
- StorageUtils.setLocal(this.STORAGE_KEY, state);
731
+ const key = efPrefKey(this.STORAGE_NAME);
732
+ const serialized = JSON.stringify(state);
733
+ // One-shot: only the effect run caused by the adopt is an echo.
734
+ const echo = serialized === this.fromStore;
735
+ this.fromStore = null;
736
+ if (echo || serialized === this.prefs.get(key))
737
+ return;
738
+ this.prefs.set(key, serialized);
652
739
  }
653
740
  }
654
741
  /**
@@ -1668,6 +1755,30 @@ class EfPermissionService {
1668
1755
  setPermissions(perms) {
1669
1756
  this._permissions.set(perms);
1670
1757
  }
1758
+ /**
1759
+ * `null` until the app pushes the user's per-screen grants. While it is
1760
+ * `null`, `canScreen` allows everything, so nav behaves as it did before
1761
+ * per-screen filtering existed (module level only).
1762
+ */
1763
+ _screenGrants = signal(null, ...(ngDevMode ? [{ debugName: "_screenGrants" }] : /* istanbul ignore next */ []));
1764
+ /**
1765
+ * Replace the per-screen grants (keyed by screen code). Pass `null` to
1766
+ * go back to "no grants info"; `{}` means the user has no screen at all.
1767
+ */
1768
+ setScreenGrants(grants) {
1769
+ this._screenGrants.set(grants);
1770
+ }
1771
+ /**
1772
+ * Whether the user holds `verb` on the screen `code`. Reads a signal, so
1773
+ * it is safe inside `computed()`. Allows everything until grants have
1774
+ * been set; after that a screen with no grant is denied.
1775
+ */
1776
+ canScreen(code, verb = Permissions.Read) {
1777
+ const grants = this._screenGrants();
1778
+ if (grants === null)
1779
+ return true;
1780
+ return grants[code]?.permissions?.includes(verb) ?? false;
1781
+ }
1671
1782
  /**
1672
1783
  * The level granted to the current user for a given module.
1673
1784
  * Returns `'none'` if the module is not in the permission set.
@@ -2064,5 +2175,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
2064
2175
  * Generated bundle index. Do not edit.
2065
2176
  */
2066
2177
 
2067
- export { CacheService, ConfirmDialogService, DEFAULT_APP_STATE, EF_BUILD_INFO, EF_MODULES, EF_MODULES_TOKEN, EF_SESSION, EF_TRANSLATE_LOADER_CONFIG, EfActiveModuleService, EfComptoirTheme, EfPermissionService, EfShortcutService, EfTheme, EfThemeConfigService, EfToastService, EfVersionedTranslateLoader, EfViewportService, LoaderService, PRIMENG_AR_LOCALE, PRIMENG_EN_LOCALE, PRIMENG_FR_LOCALE, EfToastService as ToastService, formatShortcut, hasScreenPermission, isMacPlatform, provideEfTranslateLoader, screenGuard };
2178
+ export { CacheService, ConfirmDialogService, DEFAULT_APP_STATE, EF_BUILD_INFO, EF_MODULES, EF_MODULES_TOKEN, EF_PREFERENCE_STORE, EF_SESSION, EF_SIDE_COLLAPSED_KEY, EF_TABLE_PREFS_PREFIX, EF_TRANSLATE_LOADER_CONFIG, EfActiveModuleService, EfComptoirTheme, EfPermissionService, EfShortcutService, EfTheme, EfThemeConfigService, EfToastService, EfVersionedTranslateLoader, EfViewportService, LoaderService, LocalStoragePreferenceStore, PRIMENG_AR_LOCALE, PRIMENG_EN_LOCALE, PRIMENG_FR_LOCALE, EfToastService as ToastService, efPrefKey, efTablePrefsKey, formatShortcut, hasScreenPermission, isMacPlatform, provideEfTranslateLoader, screenGuard };
2068
2179
  //# sourceMappingURL=elasticias-core.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"elasticias-core.mjs","sources":["../../../../libs/core/src/lib/services/loader.service.ts","../../../../libs/core/src/lib/services/cache.service.ts","../../../../libs/core/src/lib/services/toast.service.ts","../../../../libs/core/src/lib/services/confirm-dialog.service.ts","../../../../libs/core/src/lib/guards/screen.guard.ts","../../../../libs/core/src/lib/theme/app-state.ts","../../../../libs/core/src/lib/theme/ef-theme-config.service.ts","../../../../libs/core/src/lib/theme/ef-theme.ts","../../../../libs/core/src/lib/theme/locales/primeng-en.ts","../../../../libs/core/src/lib/theme/locales/primeng-fr.ts","../../../../libs/core/src/lib/theme/locales/primeng-ar.ts","../../../../libs/core/src/lib/modules/ef-module-registry.ts","../../../../libs/core/src/lib/modules/ef-active-module.service.ts","../../../../libs/core/src/lib/responsive/ef-viewport.service.ts","../../../../libs/core/src/lib/auth/ef-permission.service.ts","../../../../libs/core/src/lib/auth/ef-session.token.ts","../../../../libs/core/src/lib/build/ef-build-info.token.ts","../../../../libs/core/src/lib/i18n/ef-versioned-translate-loader.ts","../../../../libs/core/src/lib/shortcuts/shortcut-keys.ts","../../../../libs/core/src/lib/shortcuts/format-shortcut.ts","../../../../libs/core/src/lib/shortcuts/ef-shortcut.service.ts","../../../../libs/core/src/elasticias-core.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\n\n@Injectable({ providedIn: 'root' })\nexport class LoaderService {\n private loadingSubject = new BehaviorSubject<boolean>(false);\n isLoading$ = this.loadingSubject.asObservable();\n\n show(): void {\n this.loadingSubject.next(true);\n }\n\n hide(): void {\n this.loadingSubject.next(false);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { StorageUtils } from '@elasticias/utils';\n\n@Injectable({ providedIn: 'root' })\nexport class CacheService {\n private cache: Record<string, unknown> = {};\n private useLocalStorage = false;\n\n configure(useLocalStorage = false): void {\n this.useLocalStorage = useLocalStorage;\n }\n\n getCache<T>(key: string): T | null {\n return this.useLocalStorage ? StorageUtils.getLocal<T>(key) : (this.cache[key] as T) ?? null;\n }\n\n setCache(key: string, value: unknown): void {\n if (this.useLocalStorage) {\n StorageUtils.setLocal(key, value);\n } else {\n this.cache[key] = value;\n }\n }\n\n updateCache(key: string, newValue: unknown): void {\n if (this.useLocalStorage) {\n const current = StorageUtils.getLocal(key);\n if (current && typeof current === 'object' && typeof newValue === 'object') {\n StorageUtils.setLocal(key, { ...(current as object), ...(newValue as object) });\n } else {\n StorageUtils.setLocal(key, newValue);\n }\n } else {\n const current = this.cache[key];\n if (current && typeof current === 'object' && typeof newValue === 'object') {\n this.cache[key] = { ...(current as object), ...(newValue as object) };\n } else {\n this.cache[key] = newValue;\n }\n }\n }\n\n removeCache(key: string): void {\n if (this.useLocalStorage) {\n StorageUtils.removeLocal(key);\n } else {\n delete this.cache[key];\n }\n }\n\n clearAllCache(): void {\n if (this.useLocalStorage) {\n StorageUtils.clearLocal();\n } else {\n this.cache = {};\n }\n }\n\n hasCache(key: string): boolean {\n return this.useLocalStorage ? StorageUtils.existsLocal(key) : key in this.cache;\n }\n}\n","import { Injectable, Injector, inject, signal } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport { MessageService } from 'primeng/api';\n\n/**\n * Toast severities — mapped 1:1 to the Comptoir status spectrum:\n * `info` → processing, `success` → delivered, `warn` → pending,\n * `error` → cancelled.\n */\nexport type EfToastSeverity = 'info' | 'success' | 'warn' | 'error';\n\n/** Optional inline action button rendered at the end of a toast. */\nexport interface EfToastAction {\n /** Translation key for the button label — preferred. */\n labelKey?: string;\n /** Direct label fallback when `labelKey` is empty. */\n label?: string;\n\n /** Visual tone — `'ghost'` (default) or `'primary'` for the\n * destructive / confirm action. */\n severity?: 'ghost' | 'primary';\n\n /** Click handler. */\n command?: () => void;\n\n /** Auto-close the toast after the click runs (default `true`). */\n dismissOnClick?: boolean;\n}\n\n/**\n * Toast options accepted by `EfToastService.show()`. Either a literal\n * `title` / `text` or their `*Key` translation variants — keys win\n * unless empty.\n */\nexport interface EfToastOptions {\n severity?: EfToastSeverity;\n title?: string;\n titleKey?: string;\n text?: string;\n textKey?: string;\n /** Auto-dismiss in ms; `0` = sticky (no auto-dismiss). */\n life?: number;\n actions?: EfToastAction[];\n}\n\n/** Active toast — instance held in `EfToastService.toasts`. */\nexport interface EfToast {\n id: number;\n severity: EfToastSeverity;\n title: string;\n text: string;\n life: number;\n actions?: EfToastAction[];\n}\n\n/**\n * Comptoir toast service — V2 successor to the legacy `ToastService`.\n *\n * Owns a signal-based queue (`toasts`) consumed by\n * `<ef-toast-region>`, AND forwards every toast to PrimeNG's\n * `MessageService` for back-compat with `<p-toast>` (still used by\n * ClientApp v1). Either renderer picks the toasts up; both work.\n *\n * Default i18n keys (override per-call via `titleKey` / `textKey`):\n * - `ef_toast_info_title`, `ef_toast_info_default`\n * - `ef_toast_success_title`, `ef_toast_success_default`\n * - `ef_toast_warn_title`, `ef_toast_warn_default`\n * - `ef_toast_error_title`, `ef_toast_error_default`\n *\n * Default lifespans: info 5s, success 4s, warn 6s, error 8s.\n */\n@Injectable({ providedIn: 'root' })\nexport class EfToastService {\n private static readonly LIFE_INFO = 5000;\n private static readonly LIFE_SUCCESS = 4000;\n private static readonly LIFE_WARN = 6000;\n private static readonly LIFE_ERROR = 8000;\n\n /**\n * Lazy holders. Resolving TranslateService eagerly at construction\n * time pulls in HttpClient → HTTP_INTERCEPTORS → AuthorizeInterceptor\n * → AuthorizeService → ToastService → cycle. We defer to the first\n * actual translate / message-publish call.\n */\n private readonly injector = inject(Injector);\n private _translate?: TranslateService;\n private _messageService?: MessageService | null;\n private _messageServiceResolved = false;\n\n private nextId = 1;\n\n /** Live queue — `<ef-toast-region>` renders this. */\n readonly toasts = signal<ReadonlyArray<EfToast>>([]);\n\n /* ── Convenience methods (back-compat with the legacy\n ToastService signature: `(message?, title?, life?)`). ── */\n\n showInfo(message?: string, title?: string, life: number = EfToastService.LIFE_INFO): void {\n this.show({\n severity: 'info',\n title: title ?? this.t('ef_toast_info_title'),\n text: message ?? this.t('ef_toast_info_default'),\n life,\n });\n }\n\n showSuccess(message?: string, title?: string, life: number = EfToastService.LIFE_SUCCESS): void {\n this.show({\n severity: 'success',\n title: title ?? this.t('ef_toast_success_title'),\n text: message ?? this.t('ef_toast_success_default'),\n life,\n });\n }\n\n showWarn(message?: string, title?: string, life: number = EfToastService.LIFE_WARN): void {\n this.show({\n severity: 'warn',\n title: title ?? this.t('ef_toast_warn_title'),\n text: message ?? this.t('ef_toast_warn_default'),\n life,\n });\n }\n\n showError(message?: string, title?: string, life: number = EfToastService.LIFE_ERROR): void {\n this.show({\n severity: 'error',\n title: title ?? this.t('ef_toast_error_title'),\n text: message ?? this.t('ef_toast_error_default'),\n life,\n });\n }\n\n /** Generic show — opts can mix `title`/`titleKey`, `text`/`textKey`. */\n show(opts: EfToastOptions): EfToast {\n const severity = opts.severity ?? 'info';\n const toast: EfToast = {\n id: this.nextId++,\n severity,\n title: this.resolve(opts.title, opts.titleKey, this.defaultTitleKey(severity)),\n text: this.resolve(opts.text, opts.textKey, undefined),\n life: opts.life ?? this.defaultLife(severity),\n actions: opts.actions,\n };\n\n // Collapse a burst of identical toasts into one. A dashboard fans\n // out to many independent queries, so one rejected filter used to\n // stack the same message once per widget -- seven copies of \"a\n // validation error occurred\", burying the screen. Only toasts that\n // are still on screen dedupe, so the same message shown again later\n // still appears.\n const duplicate = this.toasts().find(\n t =>\n t.severity === toast.severity &&\n t.title === toast.title &&\n t.text === toast.text,\n );\n if (duplicate) return duplicate;\n\n this.toasts.update(list => [...list, toast]);\n\n // Forward to PrimeNG MessageService so v1's <p-toast> still\n // catches the toast. Sticky in PrimeNG is `life: 0`.\n this.messageService?.add({\n severity: toast.severity,\n summary: toast.title,\n detail: toast.text,\n life: toast.life || undefined,\n sticky: toast.life === 0,\n });\n\n return toast;\n }\n\n private get messageService(): MessageService | null {\n if (!this._messageServiceResolved) {\n this._messageServiceResolved = true;\n this._messageService = this.injector.get(MessageService, null, { optional: true });\n }\n return this._messageService ?? null;\n }\n\n dismiss(id: number): void {\n this.toasts.update(list => list.filter(t => t.id !== id));\n }\n\n clear(): void {\n this.toasts.set([]);\n this.messageService?.clear();\n }\n\n /* (messageService getter is defined just below `show` to keep it\n close to where it's consumed.) */\n\n /* ── Internals ─────────────────────────────────────────────── */\n\n private resolve(\n literal: string | undefined,\n key: string | undefined,\n fallbackKey: string | undefined,\n ): string {\n if (literal != null) return literal;\n if (key) return this.t(key);\n if (fallbackKey) return this.t(fallbackKey);\n return '';\n }\n\n private t(key: string): string {\n // Lazy-resolve TranslateService — see the field comment above\n // for the AuthorizeService cycle this avoids.\n this._translate ??= this.injector.get(TranslateService);\n const value = this._translate.instant(key);\n // `instant()` returns the key when no translation is loaded;\n // fall through to empty string so untranslated toasts don't\n // surface internal keys to end users.\n return value === key ? '' : value;\n }\n\n private defaultLife(severity: EfToastSeverity): number {\n switch (severity) {\n case 'info': return EfToastService.LIFE_INFO;\n case 'success': return EfToastService.LIFE_SUCCESS;\n case 'warn': return EfToastService.LIFE_WARN;\n case 'error': return EfToastService.LIFE_ERROR;\n }\n }\n\n private defaultTitleKey(severity: EfToastSeverity): string {\n return `ef_toast_${severity}_title`;\n }\n}\n\n/**\n * @deprecated Use `EfToastService` — same instance, new name. The\n * alias keeps existing imports compiling during the v1 → V2\n * migration.\n */\nexport { EfToastService as ToastService };\n","import { Injectable, Injector, inject } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport { ConfirmationService } from 'primeng/api';\n\n/** What the user is being asked to approve. Drives the copy, the icon\n * and the weight of the accept button. */\nexport type EfConfirmIntent = 'generic' | 'delete';\n\n/**\n * Options accepted by `ConfirmDialogService.confirm()`.\n *\n * Every piece of text is a translation key, per the framework's i18n\n * convention — the service resolves them through `TranslateService` so\n * the dialog speaks the user's language rather than the author's. The\n * literal `message` / `header` escape hatches exist for text that is\n * already translated (a server message, say); a key always wins.\n */\nexport interface EfConfirmOptions {\n /** Kind of confirmation — `'delete'` supplies destructive defaults. */\n intent?: EfConfirmIntent;\n\n /**\n * Name of the thing being acted on, so the dialog can say *what* it\n * is about to destroy: \"Delete client ANDALOCY PARFUMS?\" rather than\n * \"Delete?\". Omit it and the generic message is used instead.\n */\n name?: string | null;\n\n /** Translation key for the message — preferred over `message`. */\n messageKey?: string;\n /** Already-translated message. Used when `messageKey` is empty. */\n message?: string;\n /** Extra interpolation params for `messageKey` (`name` is added). */\n messageParams?: Record<string, unknown>;\n\n /** Translation key for the dialog title. */\n headerKey?: string;\n /** Already-translated dialog title. */\n header?: string;\n\n /** Translation key for the accept button label. */\n acceptLabelKey?: string;\n /** Translation key for the reject button label. */\n rejectLabelKey?: string;\n\n /** PrimeNG icon class shown in the body tile. */\n icon?: string;\n\n /** Run when the user accepts. */\n accept?: () => void;\n /** Run when the user cancels or dismisses. */\n reject?: () => void;\n\n /** Originating event, so PrimeNG can anchor the dialog. */\n event?: Event;\n}\n\n/** Built-in fallbacks, used only when a translation is missing, so a\n * consuming app that has not yet added the keys still gets a readable\n * dialog instead of a raw key (or worse, an empty message under an\n * irreversible action). */\nconst FALLBACKS: Record<string, string> = {\n ef_confirm_header: 'Confirmation',\n ef_confirm_message_generic: 'Are you sure you want to continue?',\n ef_confirm_accept: 'Confirm',\n ef_confirm_cancel: 'Cancel',\n ef_confirm_delete_header: 'Confirm deletion',\n ef_confirm_delete_accept: 'Delete',\n ef_confirm_delete_message: 'Are you sure you want to delete \"{{name}}\"? This action cannot be undone.',\n ef_confirm_delete_message_generic: 'Are you sure you want to delete this item? This action cannot be undone.',\n};\n\n/** Per-intent defaults. `confirm()` merges the caller's options over these. */\nconst INTENT_DEFAULTS: Record<EfConfirmIntent, Required<Pick<EfConfirmOptions,\n 'headerKey' | 'acceptLabelKey' | 'rejectLabelKey' | 'icon'>> & { messageKey: string; namedMessageKey?: string }> = {\n generic: {\n headerKey: 'ef_confirm_header',\n acceptLabelKey: 'ef_confirm_accept',\n rejectLabelKey: 'ef_confirm_cancel',\n icon: 'pi pi-exclamation-triangle',\n messageKey: 'ef_confirm_message_generic',\n },\n delete: {\n headerKey: 'ef_confirm_delete_header',\n acceptLabelKey: 'ef_confirm_delete_accept',\n rejectLabelKey: 'ef_confirm_cancel',\n icon: 'pi pi-exclamation-triangle',\n messageKey: 'ef_confirm_delete_message_generic',\n namedMessageKey: 'ef_confirm_delete_message',\n },\n};\n\n/**\n * The app-wide confirmation modal, driven through PrimeNG's\n * `ConfirmationService` and rendered by `<ef-confirm-dialog>`.\n *\n * Two call shapes:\n *\n * ```ts\n * // Options — the one to reach for.\n * confirmDialogService.confirm({\n * intent: 'delete',\n * name: client.name, // \"Delete ANDALOCY PARFUMS?\"\n * accept: () => this.remove(),\n * });\n *\n * // Legacy positional form, kept so existing callers keep compiling.\n * confirmDialogService.confirm('Already-translated question?', onYes, onNo);\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class ConfirmDialogService {\n private readonly confirmationService = inject(ConfirmationService);\n\n /**\n * Lazy holder. Resolving `TranslateService` at construction time pulls\n * in HttpClient and, through the interceptor chain, services that\n * inject this one — the same cycle `EfToastService` documents. Defer\n * to the first actual `confirm()` call, which is always well after\n * bootstrap.\n */\n private readonly injector = inject(Injector);\n private _translate?: TranslateService;\n\n confirm(options: EfConfirmOptions): void;\n /** @deprecated Pass `EfConfirmOptions` — a literal message cannot be translated. */\n confirm(message: string, acceptCallback?: () => void, rejectCallback?: () => void, event?: Event): void;\n confirm(\n messageOrOptions: string | EfConfirmOptions,\n acceptCallback?: () => void,\n rejectCallback?: () => void,\n event?: Event,\n ): void {\n const options: EfConfirmOptions =\n typeof messageOrOptions === 'string'\n ? { message: messageOrOptions, accept: acceptCallback, reject: rejectCallback, event }\n : messageOrOptions;\n\n const defaults = INTENT_DEFAULTS[options.intent ?? 'generic'];\n const name = options.name?.toString().trim() || undefined;\n\n this.confirmationService.confirm({\n target: options.event?.target ?? undefined,\n message: this.resolveMessage(options, defaults, name),\n header: options.header ?? this.t(options.headerKey ?? defaults.headerKey),\n closable: true,\n closeOnEscape: true,\n icon: options.icon ?? defaults.icon,\n rejectButtonProps: {\n label: this.t(options.rejectLabelKey ?? defaults.rejectLabelKey),\n severity: 'secondary',\n outlined: true,\n },\n acceptButtonProps: {\n label: this.t(options.acceptLabelKey ?? defaults.acceptLabelKey),\n // Semantics. The visual weight comes from the style class\n // below, because `.es-confirm .p-confirmdialog-accept-button`\n // in `_patterns.scss` paints the button at a specificity a\n // severity class cannot reach.\n severity: options.intent === 'delete' ? 'danger' : undefined,\n },\n // `.btn.btn-danger` is declared after the `.es-confirm` accept\n // rule at equal specificity, so it is what finally colours a\n // destructive confirm red instead of ordinary primary ink.\n acceptButtonStyleClass: options.intent === 'delete' ? 'btn btn-danger' : undefined,\n accept: () => options.accept?.(),\n reject: () => options.reject?.(),\n });\n }\n\n /**\n * Sugar for `confirm({ intent: 'delete', ... })`.\n *\n * ```ts\n * confirmDialogService.confirmDelete({ name: row.label, accept: () => … });\n * ```\n */\n confirmDelete(options: Omit<EfConfirmOptions, 'intent'> = {}): void {\n this.confirm({ ...options, intent: 'delete' });\n }\n\n /* ── Internals ─────────────────────────────────────────────── */\n\n private resolveMessage(\n options: EfConfirmOptions,\n defaults: (typeof INTENT_DEFAULTS)[EfConfirmIntent],\n name: string | undefined,\n ): string {\n if (options.messageKey) {\n return this.t(options.messageKey, { ...options.messageParams, name: escapeHtml(name ?? '') });\n }\n if (options.message != null) return options.message;\n\n // A named message when we know what is being acted on, the generic\n // one otherwise — so a caller with no name still reads correctly.\n const key = name && defaults.namedMessageKey ? defaults.namedMessageKey : defaults.messageKey;\n return this.t(key, { ...options.messageParams, name: escapeHtml(name ?? '') });\n }\n\n private t(key: string, params?: Record<string, unknown>): string {\n this._translate ??= this.injector.get(TranslateService);\n const value = this._translate.instant(key, params);\n // `instant()` hands back the key when nothing is loaded for it.\n // Never show that to a user who is about to destroy something.\n if (value !== key) return value;\n const fallback = FALLBACKS[key];\n return fallback ? interpolate(fallback, params) : '';\n }\n}\n\n/**\n * PrimeNG renders the confirm message through `[innerHTML]`. Angular\n * sanitizes it, so this is not about script execution — it is about an\n * entity name containing `<`, `>` or `&` rendering as markup or being\n * silently swallowed. \"Renault < Dacia\" must read as itself.\n */\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n/** Minimal `{{param}}` substitution for the built-in fallbacks, which\n * never reach ngx-translate's own interpolator. */\nfunction interpolate(template: string, params?: Record<string, unknown>): string {\n if (!params) return template;\n return template.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (match: string, key: string) =>\n params[key] == null ? match : String(params[key]),\n );\n}\n","import { inject } from '@angular/core';\nimport { CanActivateFn, ActivatedRouteSnapshot, Router } from '@angular/router';\nimport { StorageUtils } from '@elasticias/utils';\nimport { Permissions } from '@elasticias/types';\n\n/**\n * Configuration for the screen guard factory.\n */\nexport interface ScreenGuardConfig {\n /** Storage key where screen grants are stored (default: 'CURRENT_USER_GRANTS') */\n grantsStorageKey?: string;\n /** Route to redirect to when access is denied (default: '/') */\n deniedRedirect?: string;\n /** Minimum required permission to access the screen (default: Permissions.Read) */\n requiredPermission?: Permissions;\n /** Storage type to read grants from (default: 'session') */\n storageType?: 'local' | 'session';\n}\n\n/**\n * Creates a reusable Angular route guard that checks screen-level permissions.\n *\n * Usage in route definitions:\n * ```typescript\n * {\n * path: 'countries',\n * data: { screenCode: 'Countries' },\n * canActivate: [screenGuard()],\n * children: [\n * { path: '', component: CountriesComponent },\n * { path: 'details/:id', component: CountriesDetailsComponent },\n * ]\n * }\n * ```\n *\n * The guard reads the `screenCode` from route data (traversing parent routes)\n * and checks if the current user has at least the required permission (default: Read).\n */\nexport function screenGuard(config?: ScreenGuardConfig): CanActivateFn {\n return (route: ActivatedRouteSnapshot) => {\n const router = inject(Router);\n const grantsKey = config?.grantsStorageKey ?? 'CURRENT_USER_GRANTS';\n const deniedRedirect = config?.deniedRedirect ?? '/';\n const requiredPermission = config?.requiredPermission ?? Permissions.Read;\n const storageType = config?.storageType ?? 'local';\n\n const screenCode = getScreenCode(route);\n\n // If no screenCode found on this route or any parent, allow access\n if (!screenCode) {\n return true;\n }\n\n const screenGrants = storageType === 'session'\n ? StorageUtils.getSession<Record<string, { permissions?: string[] }>>(grantsKey)\n : StorageUtils.getLocal<Record<string, { permissions?: string[] }>>(grantsKey);\n\n if (!screenGrants) {\n router.navigate([deniedRedirect]);\n return false;\n }\n\n const grant = screenGrants[screenCode];\n if (!grant?.permissions?.includes(requiredPermission)) {\n router.navigate([deniedRedirect]);\n return false;\n }\n\n return true;\n };\n}\n\n/**\n * Walks up the route tree to find the nearest screenCode in route data.\n */\nfunction getScreenCode(route: ActivatedRouteSnapshot): string | undefined {\n let current: ActivatedRouteSnapshot | null = route;\n while (current) {\n const code = current.data?.['screenCode'] as string | undefined;\n if (code) return code;\n current = current.parent;\n }\n return undefined;\n}\n\n/**\n * Utility function to check if the current user has a specific permission on a screen.\n * Can be used in components/services outside of route guards.\n */\nexport function hasScreenPermission(\n screenCode: string,\n permission: Permissions,\n grantsStorageKey = 'CURRENT_USER_GRANTS',\n storageType: 'local' | 'session' = 'local'\n): boolean {\n const screenGrants = storageType === 'session'\n ? StorageUtils.getSession<Record<string, { permissions?: string[] }>>(grantsStorageKey)\n : StorageUtils.getLocal<Record<string, { permissions?: string[] }>>(grantsStorageKey);\n if (!screenGrants) return false;\n\n const grant = screenGrants[screenCode];\n return grant?.permissions?.includes(permission) ?? false;\n}\n","export interface AppState {\n preset?: string;\n primary?: string;\n surface?: string;\n darkTheme?: boolean;\n menuActive?: boolean;\n mobileMenuVisible?: boolean;\n designerKey?: string;\n RTL?: boolean;\n}\n\nexport const DEFAULT_APP_STATE: AppState = {\n preset: 'Lara',\n primary: 'noir',\n surface: null as any,\n darkTheme: false,\n menuActive: true,\n mobileMenuVisible: false,\n designerKey: 'primeng-designer-theme',\n RTL: false\n};\n","import { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { computed, effect, inject, Injectable, PLATFORM_ID, signal } from '@angular/core';\nimport { palette, updatePrimaryPalette } from '@primeng/themes';\nimport { StorageUtils } from '@elasticias/utils';\nimport { AppState, DEFAULT_APP_STATE } from './app-state';\n\n/**\n * Service that manages theme state: preset, primary color, surface, dark mode, RTL.\n * State is persisted to localStorage so user preferences survive page reloads.\n *\n * Apps can extend this service or use it directly.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class EfThemeConfigService {\n private readonly STORAGE_KEY = 'APP_CONFIG_STATE';\n\n appState = signal<AppState>(null as any);\n\n designerActive = signal(false);\n\n newsActive = signal(false);\n\n document = inject(DOCUMENT);\n\n platformId = inject(PLATFORM_ID);\n\n theme = computed(() => (this.appState()?.darkTheme ? 'dark' : 'light'));\n\n transitionComplete = signal<boolean>(false);\n\n constructor() {\n const initialState = this.loadAppState();\n this.appState.set({ ...initialState });\n\n // Apply preset class + RTL synchronously so the first paint has\n // the right theme — the effect below picks up subsequent changes\n // (including any subclass `appState.update()` issued before its\n // first run).\n this.updatePresetClass(initialState);\n if (isPlatformBrowser(this.platformId) && initialState?.RTL) {\n this.document.documentElement.setAttribute('dir', 'rtl');\n }\n\n effect(() => {\n const state = this.appState();\n if (!state) return;\n this.saveAppState(state);\n this.updatePresetClass(state);\n this.handleDarkModeTransition(state);\n this.applyRTL(state);\n });\n }\n\n private static readonly PRESET_CLASS_MAP: Record<string, string> = {\n Aura: 'theme-compact',\n Lara: 'theme-modern',\n Material: 'theme-material',\n Nora: 'theme-classic',\n Comptoir: 'theme-comptoir',\n };\n\n private static readonly TENANT_RAMP_STOPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900] as const;\n\n private static readonly ALL_THEME_CLASSES = Object.values(EfThemeConfigService.PRESET_CLASS_MAP);\n\n private updatePresetClass(state: AppState): void {\n if (isPlatformBrowser(this.platformId)) {\n const body = this.document.body;\n body.classList.remove(...EfThemeConfigService.ALL_THEME_CLASSES);\n if (state.preset) {\n const cls = EfThemeConfigService.PRESET_CLASS_MAP[state.preset];\n if (cls) {\n body.classList.add(cls);\n }\n }\n }\n }\n\n private handleDarkModeTransition(state: AppState): void {\n if (isPlatformBrowser(this.platformId)) {\n if ((document as any).startViewTransition) {\n this.startViewTransition(state);\n } else {\n this.toggleDarkMode(state);\n this.onTransitionEnd();\n }\n }\n }\n\n private startViewTransition(state: AppState): void {\n const transition = (document as any).startViewTransition(() => {\n this.toggleDarkMode(state);\n });\n\n transition.ready\n .then(() => this.onTransitionEnd())\n .catch(() => { /* view transition aborted */ });\n }\n\n private toggleDarkMode(state: AppState): void {\n if (state.darkTheme) {\n this.document.documentElement.classList.add('p-dark');\n } else {\n this.document.documentElement.classList.remove('p-dark');\n }\n }\n\n private onTransitionEnd() {\n this.transitionComplete.set(true);\n setTimeout(() => {\n this.transitionComplete.set(false);\n });\n }\n\n private applyRTL(state: AppState): void {\n if (isPlatformBrowser(this.platformId)) {\n const setDir = () => {\n if (state.RTL) {\n this.document.documentElement.setAttribute('dir', 'rtl');\n } else {\n this.document.documentElement.removeAttribute('dir');\n }\n };\n\n if ((document as any).startViewTransition) {\n const t = (document as any).startViewTransition(() => setDir());\n t.ready.catch(() => { /* view transition aborted */ });\n } else {\n setDir();\n }\n }\n }\n\n hideMenu() {\n this.appState.update((state) => ({ ...state, menuActive: false }));\n }\n\n showMenu() {\n this.appState.update((state) => ({ ...state, menuActive: true }));\n }\n\n toggleMobileMenu() {\n this.appState.update((state) => ({\n ...state,\n mobileMenuVisible: !state.mobileMenuVisible\n }));\n }\n\n closeMobileMenu() {\n this.appState.update((state) => ({\n ...state,\n mobileMenuVisible: false\n }));\n }\n\n openMobileMenu() {\n this.appState.update((state) => ({\n ...state,\n mobileMenuVisible: true\n }));\n }\n\n hideNews() {\n this.newsActive.set(false);\n }\n\n showNews() {\n this.newsActive.set(true);\n }\n\n showDesigner() {\n this.designerActive.set(true);\n }\n\n hideDesigner() {\n this.designerActive.set(false);\n }\n\n private loadAppState(): AppState {\n if (isPlatformBrowser(this.platformId)) {\n const storedState = StorageUtils.getLocal<AppState>(this.STORAGE_KEY);\n if (storedState) {\n return storedState;\n }\n }\n return { ...DEFAULT_APP_STATE };\n }\n\n private saveAppState(state: AppState): void {\n if (isPlatformBrowser(this.platformId)) {\n StorageUtils.setLocal(this.STORAGE_KEY, state);\n }\n }\n\n /**\n * Applies a tenant's brand color across both PrimeNG's primary palette\n * and the Comptoir `--tenant-*` CSS variables.\n *\n * Generates a 50–950 ramp from the input hex via PrimeNG's `palette()`\n * helper, hands the full ramp to `updatePrimaryPalette()`, and writes\n * stops 50–900 onto `documentElement.style` so the SCSS layer's\n * `var(--tenant-*)` references resolve to the tenant's color.\n *\n * Call this whenever the active tenant changes (e.g., from an effect\n * watching `tenantService.storeConfig().primaryColor`).\n */\n setTenantAccent(hex: string): void {\n if (!hex) return;\n\n const ramp = palette(hex) as Record<string, string>;\n if (!ramp) return;\n\n updatePrimaryPalette(ramp);\n\n if (isPlatformBrowser(this.platformId)) {\n const root = this.document.documentElement;\n for (const stop of EfThemeConfigService.TENANT_RAMP_STOPS) {\n const value = ramp[String(stop)];\n if (value) {\n root.style.setProperty(`--tenant-${stop}`, value);\n }\n }\n }\n }\n}\n","import { definePreset } from '@primeng/themes';\nimport Aura from '@primeng/themes/aura';\nimport Lara from '@primeng/themes/lara';\n\n/* ──────────────────────────────────────────────────────────────────\n * LEGACY: Noir preset (Aura base, monochrome surface palette).\n * Kept for backward-compat with apps that haven't migrated to\n * Comptoir. Phase 5 of the design-system plan retrofits consumers\n * to EfComptoirTheme; once that lands, Noir + EfTheme can be\n * deleted.\n * ────────────────────────────────────────────────────────────── */\n\nconst Noir = definePreset(Aura, {\n semantic: {\n primary: {\n 50: '{surface.50}',\n 100: '{surface.100}',\n 200: '{surface.200}',\n 300: '{surface.300}',\n 400: '{surface.400}',\n 500: '{surface.500}',\n 600: '{surface.600}',\n 700: '{surface.700}',\n 800: '{surface.800}',\n 900: '{surface.900}',\n 950: '{surface.950}'\n },\n colorScheme: {\n light: {\n primary: {\n color: '{primary.950}',\n contrastColor: '#ffffff',\n hoverColor: '{primary.800}',\n activeColor: '{primary.700}'\n },\n highlight: {\n background: '{primary.950}',\n focusBackground: '{primary.700}',\n color: '#ffffff',\n focusColor: '#ffffff'\n }\n },\n dark: {\n primary: {\n color: '{primary.50}',\n contrastColor: '{primary.950}',\n hoverColor: '{primary.200}',\n activeColor: '{primary.300}'\n },\n highlight: {\n background: '{primary.50}',\n focusBackground: '{primary.300}',\n color: '{primary.950}',\n focusColor: '{primary.950}'\n }\n }\n }\n }\n});\n\n/**\n * Default Elasticias theme configuration for PrimeNG.\n * Uses the Noir preset (surface-based primary colors) with dark mode support.\n *\n * @deprecated Migrate to {@link EfComptoirTheme} as part of Phase 5 of the\n * design-system plan. Will be removed once all consumers have moved.\n */\nexport const EfTheme = {\n preset: Noir,\n options: {\n darkModeSelector: '.p-dark',\n }\n};\n\nexport default EfTheme;\n\n/* ──────────────────────────────────────────────────────────────────\n * COMPTOIR: ink surface + tenant primary (Lara base).\n * Surface palette is the ink ramp from libs/tokens/colors.json.\n * Primary palette defaults to the parfumerie sample tenant; it is\n * runtime-replaced by EfThemeConfigService.setTenantAccent(hex)\n * via PrimeNG's updatePrimaryPalette() API.\n * ────────────────────────────────────────────────────────────── */\n\nconst ComptoirPreset = definePreset(Lara, {\n semantic: {\n primary: {\n 50: '#f7f0f4',\n 100: '#ecdce5',\n 200: '#d8b4c5',\n 300: '#b87a99',\n 400: '#934e74',\n 500: '#6f3257',\n 600: '#54243f',\n 700: '#401a30',\n 800: '#2c1221',\n 900: '#1a0913',\n 950: '#0d040a'\n },\n /* ──────────────────────────────────────────────────────────────\n * Control sizing (ADR-009). The native \"comptoir\" variant is the\n * default render path and is pinned to --hit-base (40px) in CSS;\n * these tokens align the OPT-IN PrimeNG variant (p-select filter,\n * p-multiselect, p-inputnumber stepper, etc.) to the same canonical\n * heights so the two paths agree:\n * base → 40px (--hit-base) sm → 32px (--hit) lg → 48px (--hit-touch, POS/mobile)\n * Lara form-field height ≈ paddingY*2 + lineHeight(1.5)*fontSize(14px) + 2px border.\n * base: 8px*2 + 21 + 2 ≈ 40px · sm: 5px*2 + ~18 + 2 ≈ 32px · lg: 12px*2 + 21 + 2 ≈ 48px\n * NOTE: exact pixel height depends on the app's root font-size; the\n * native default path is the verified one — confirm the PrimeNG\n * opt-in controls visually in the running app and nudge paddingY if\n * they read 1-2px off. Border radius matches --r-md (12px). */\n formField: {\n paddingX: '0.75rem',\n paddingY: '0.5rem',\n borderRadius: '12px',\n sm: {\n fontSize: '0.78rem',\n paddingX: '0.625rem',\n paddingY: '0.3125rem'\n },\n lg: {\n fontSize: '0.9375rem',\n paddingX: '0.875rem',\n paddingY: '0.75rem'\n }\n },\n colorScheme: {\n light: {\n primary: {\n color: '{primary.500}',\n contrastColor: '#ffffff',\n hoverColor: '{primary.600}',\n activeColor: '{primary.700}'\n },\n surface: {\n 0: '#ffffff',\n 50: '#f8f9fb',\n 100: '#f1f3f6',\n 200: '#e4e8ee',\n 300: '#cdd3dd',\n 400: '#9ca5b3',\n 500: '#6c7280',\n 600: '#4a4f5a',\n 700: '#2f3239',\n 800: '#1d1f24',\n 900: '#0f1115',\n 950: '#06070a'\n },\n highlight: {\n background: '{primary.500}',\n focusBackground: '{primary.600}',\n color: '#ffffff',\n focusColor: '#ffffff'\n }\n },\n dark: {\n primary: {\n color: '{primary.400}',\n contrastColor: '{primary.950}',\n hoverColor: '{primary.300}',\n activeColor: '{primary.200}'\n },\n /* The ramp runs in the SAME direction as the light one, and\n * that is deliberate — it used to be inverted here (0 = black\n * … 950 = near-white) and that single flip was the cause of\n * dark mode being unreadable product-wide.\n *\n * PrimeNG's surface ramp is not \"light values for light mode,\n * dark values for dark mode\". It is a fixed light→dark scale\n * that the *semantic* block indexes differently per scheme:\n * light reads `{surface.0}` as the page and `{surface.700}` as\n * body text, dark reads `{surface.900}` as the page and\n * `{surface.0}` as body text. Every component preset inherits\n * those conventions. Inverting the ramp therefore inverted\n * every inherited value at once — dark `text.color` resolved\n * to #000000, `content.background` to #f1f3f6, and\n * `button.text.secondary.color` to #2f3239 on a #1d1f24 card\n * (1.28:1, the reported bug).\n *\n * Keeping the ramp upright makes the ink scale land exactly on\n * the Comptoir dark aliases from `_comptoir.scss`:\n * surface.900 → --paper (#0f1115)\n * surface.800 → --paper-alt (#1d1f24)\n * surface.400 → --text-mute (#9ca5b3)\n * surface.50 → --text (#f8f9fb)\n * so inherited PrimeNG values agree with the design system\n * instead of fighting it. */\n surface: {\n 0: '#ffffff',\n 50: '#f8f9fb',\n 100: '#f1f3f6',\n 200: '#e4e8ee',\n 300: '#cdd3dd',\n 400: '#9ca5b3',\n 500: '#6c7280',\n 600: '#4a4f5a',\n 700: '#2f3239',\n 800: '#1d1f24',\n 900: '#0f1115',\n 950: '#06070a'\n },\n /* Lara's dark body text is `{surface.0}` = pure white; Comptoir's\n * --text is --ink-50. Pin it so the two agree. 17.94:1 on\n * --paper, 15.65:1 on --paper-alt. */\n text: {\n color: '{surface.50}',\n hoverColor: '{surface.50}'\n },\n highlight: {\n background: '{primary.400}',\n focusBackground: '{primary.300}',\n color: '{primary.950}',\n focusColor: '{primary.950}'\n }\n }\n }\n },\n /* ──────────────────────────────────────────────────────────────\n * Button: the low-emphasis variants.\n *\n * An upright surface ramp (above) fixes everything Lara expresses\n * through `{surface.N}`. It cannot fix the variants Lara expresses\n * through the accent and through raw Tailwind reds, because those\n * were tuned against Lara's own indigo/zinc, not against the\n * Comptoir tenant ramp. Measured on the default parfumerie accent,\n * against --paper (#0f1115) / --paper-alt (#1d1f24) in dark and\n * #ffffff / --paper (#f8f9fb) in light, resting state:\n *\n * dark text.primary {primary.400} #934e74 → 3.22 / 2.81 ✗\n * dark outlined.primary.border {primary.700} #401a30 → 1.27 / 1.11 ✗\n * dark outlined.secondary.border {surface.700} → 1.47 / 1.28 ✗\n * dark outlined.danger.border {red.700} → 2.92 / 2.55 ✗\n * light text.danger {red.500} #ef4444 → 3.76 / 3.57 ✗\n * light outlined.primary.border {primary.200} → 1.87 / 1.77 ✗\n * light outlined.secondary.border {surface.200} → 1.19 / 1.13 ✗\n *\n * Text colours below clear 4.5:1 in every state (resting, hover\n * tint and the 16% active tint); border colours clear the 3:1\n * WCAG 1.4.11 bar for a component boundary without brightening\n * into something that reads as a fill.\n *\n * The severities Comptoir actually ships on `<ef-button>` are\n * primary / secondary / danger; success, info, warn, help and\n * contrast are left on stock, which the upright ramp already\n * makes legible.\n *\n * Caveat: `{primary.N}` tracks the tenant accent through\n * `EfThemeConfigService.setTenantAccent()`, so these ratios hold\n * for the default ramp. A very dark or very light tenant accent\n * would need a lightness clamp in the ramp generator — noted, not\n * built. */\n components: {\n button: {\n colorScheme: {\n light: {\n text: {\n /* {primary.color} (= {primary.500}) already reads\n * 9.25 / 8.78 — left on stock so it keeps tracking\n * the tenant accent. */\n danger: { color: '{red.700}' } /* 6.47 / 6.14 */\n },\n outlined: {\n primary: { borderColor: '{primary.300}' }, /* 3.34 / 3.17 */\n secondary: { color: '{surface.600}', borderColor: '{surface.500}' }, /* 8.21 / 7.80 · border 4.82 / 4.58 */\n danger: { color: '{red.700}', borderColor: '{red.500}' } /* 6.47 / 6.14 · border 3.76 / 3.57 */\n }\n },\n dark: {\n text: {\n primary: { color: '{primary.200}' }, /* 10.13 / 8.84 */\n secondary: { color: '{surface.300}' }, /* 12.56 / 10.96 — the reported 1.28 pair */\n danger: { color: '{red.400}' } /* 6.83 / 5.96 */\n },\n outlined: {\n primary: { color: '{primary.200}', borderColor: '{primary.300}' }, /* 10.13 / 8.84 · border 5.65 / 4.93 */\n secondary: { color: '{surface.300}', borderColor: '{surface.500}' }, /* 12.56 / 10.96 · border 3.92 / 3.42 */\n danger: { color: '{red.400}', borderColor: '{red.500}' } /* 6.83 / 5.96 · border 5.02 / 4.38 */\n },\n /* `[link]=\"true\"` carries no ground of its own, so it sits\n * straight on --paper / --paper-alt: {primary.color} reads\n * 3.22 / 2.81 there. Same lift as the text variant. */\n link: {\n color: '{primary.200}', /* 10.13 / 8.84 */\n hoverColor: '{primary.100}',\n activeColor: '{primary.100}'\n }\n }\n }\n }\n }\n});\n\n/**\n * Comptoir theme configuration for PrimeNG (Phase 1 / design-system v0.2).\n * Surface palette = ink ramp; primary palette = tenant accent\n * (runtime-driven via `EfThemeConfigService.setTenantAccent(hex)`).\n *\n * Usage with providePrimeNG:\n * ```ts\n * providePrimeNG({ theme: EfComptoirTheme, ripple: true })\n * ```\n *\n * Pair with `state.preset = 'Comptoir'` so the body class becomes\n * `theme-comptoir` (avoids legacy `theme-modern` radius overrides).\n */\nexport const EfComptoirTheme = {\n preset: ComptoirPreset,\n options: {\n darkModeSelector: '.p-dark',\n }\n};\n","import { Translation } from 'primeng/api';\n\n/**\n * English locale for PrimeNG components.\n *\n * Usage:\n * ```ts\n * import { PRIMENG_EN_LOCALE } from '@elasticias/core';\n * this.primeng.translation = PRIMENG_EN_LOCALE;\n * ```\n */\nexport const PRIMENG_EN_LOCALE: Translation = {\n startsWith: 'Starts with',\n contains: 'Contains',\n notContains: 'Not contains',\n endsWith: 'Ends with',\n equals: 'Equals',\n notEquals: 'Not equals',\n noFilter: 'No Filter',\n lt: 'Less than',\n lte: 'Less than or equal to',\n gt: 'Greater than',\n gte: 'Greater than or equal to',\n dateIs: 'Date is',\n dateIsNot: 'Date is not',\n dateBefore: 'Date is before',\n dateAfter: 'Date is after',\n clear: 'Clear',\n apply: 'Apply',\n matchAll: 'Match All',\n matchAny: 'Match Any',\n addRule: 'Add Rule',\n removeRule: 'Remove Rule',\n accept: 'Yes',\n reject: 'No',\n choose: 'Choose',\n upload: 'Upload',\n cancel: 'Cancel',\n completed: 'Completed',\n pending: 'Pending',\n fileSizeTypes: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],\n dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],\n dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],\n dayNamesMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],\n monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],\n monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n chooseYear: 'Choose Year',\n chooseMonth: 'Choose Month',\n chooseDate: 'Choose Date',\n prevDecade: 'Previous Decade',\n nextDecade: 'Next Decade',\n prevYear: 'Previous Year',\n nextYear: 'Next Year',\n prevMonth: 'Previous Month',\n nextMonth: 'Next Month',\n prevHour: 'Previous Hour',\n nextHour: 'Next Hour',\n prevMinute: 'Previous Minute',\n nextMinute: 'Next Minute',\n prevSecond: 'Previous Second',\n nextSecond: 'Next Second',\n am: 'AM',\n pm: 'PM',\n today: 'Today',\n weekHeader: 'Wk',\n firstDayOfWeek: 0,\n showMonthAfterYear: false,\n dateFormat: 'mm/dd/yy',\n weak: 'Weak',\n medium: 'Medium',\n strong: 'Strong',\n passwordPrompt: 'Enter a password',\n emptyFilterMessage: 'No results found',\n searchMessage: '{0} results are available',\n selectionMessage: '{0} items selected',\n emptySelectionMessage: 'No selected item',\n emptySearchMessage: 'No results found',\n emptyMessage: 'No available options',\n aria: {\n trueLabel: 'True',\n falseLabel: 'False',\n nullLabel: 'Not Selected',\n star: '1 star',\n stars: '{star} stars',\n selectAll: 'All items selected',\n unselectAll: 'All items unselected',\n close: 'Close',\n previous: 'Previous',\n next: 'Next',\n navigation: 'Navigation',\n scrollTop: 'Scroll Top',\n moveTop: 'Move Top',\n moveUp: 'Move Up',\n moveDown: 'Move Down',\n moveBottom: 'Move Bottom',\n moveToTarget: 'Move to Target',\n moveToSource: 'Move to Source',\n moveAllToTarget: 'Move All to Target',\n moveAllToSource: 'Move All to Source',\n pageLabel: 'Page {page}',\n firstPageLabel: 'First Page',\n lastPageLabel: 'Last Page',\n nextPageLabel: 'Next Page',\n prevPageLabel: 'Previous Page',\n rowsPerPageLabel: 'Rows per page',\n jumpToPageDropdownLabel: 'Jump to Page Dropdown',\n jumpToPageInputLabel: 'Jump to Page Input',\n selectRow: 'Row Selected',\n unselectRow: 'Row Unselected',\n expandRow: 'Row Expanded',\n collapseRow: 'Row Collapsed',\n showFilterMenu: 'Show Filter Menu',\n hideFilterMenu: 'Hide Filter Menu',\n filterOperator: 'Filter Operator',\n filterConstraint: 'Filter Constraint',\n editRow: 'Row Edit',\n saveEdit: 'Save Edit',\n cancelEdit: 'Cancel Edit',\n listView: 'List View',\n gridView: 'Grid View',\n slide: 'Slide',\n slideNumber: '{slideNumber}',\n zoomImage: 'Zoom Image',\n zoomIn: 'Zoom In',\n zoomOut: 'Zoom Out',\n rotateRight: 'Rotate Right',\n rotateLeft: 'Rotate Left',\n listLabel: 'Option List',\n },\n} as Translation;\n","import { Translation } from 'primeng/api';\n\n/**\n * French locale for PrimeNG components.\n *\n * Usage:\n * ```ts\n * import { PRIMENG_FR_LOCALE } from '@elasticias/core';\n * this.primeng.translation = PRIMENG_FR_LOCALE;\n * ```\n */\nexport const PRIMENG_FR_LOCALE: Translation = {\n startsWith: 'Commence par',\n contains: 'Contient',\n notContains: 'Ne contient pas',\n endsWith: 'Se termine par',\n equals: 'Égal à',\n notEquals: 'Différent de',\n noFilter: 'Aucun filtre',\n lt: 'Inférieur à',\n lte: 'Inférieur ou égal à',\n gt: 'Supérieur à',\n gte: 'Supérieur ou égal à',\n dateIs: 'La date est',\n dateIsNot: \"La date n'est pas\",\n dateBefore: 'La date est avant',\n dateAfter: 'La date est après',\n clear: 'Effacer',\n apply: 'Appliquer',\n matchAll: 'Correspond à tous',\n matchAny: \"Correspond à n'importe quel\",\n addRule: 'Ajouter une règle',\n removeRule: 'Supprimer la règle',\n accept: 'Oui',\n reject: 'Non',\n choose: 'Choisir',\n upload: 'Télécharger',\n cancel: 'Annuler',\n completed: 'Terminé',\n pending: 'En attente',\n fileSizeTypes: ['o', 'Ko', 'Mo', 'Go', 'To', 'Po', 'Eo', 'Zo', 'Yo'],\n dayNames: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],\n dayNamesShort: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],\n dayNamesMin: ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'],\n monthNames: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],\n monthNamesShort: ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jun', 'Jul', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc'],\n chooseYear: \"Choisir l'année\",\n chooseMonth: 'Choisir le mois',\n chooseDate: 'Choisir la date',\n prevDecade: 'Décennie précédente',\n nextDecade: 'Décennie suivante',\n prevYear: 'Année précédente',\n nextYear: 'Année suivante',\n prevMonth: 'Mois précédent',\n nextMonth: 'Mois suivant',\n prevHour: 'Heure précédente',\n nextHour: 'Heure suivante',\n prevMinute: 'Minute précédente',\n nextMinute: 'Minute suivante',\n prevSecond: 'Seconde précédente',\n nextSecond: 'Seconde suivante',\n am: 'AM',\n pm: 'PM',\n today: \"Aujourd'hui\",\n weekHeader: 'Sem',\n firstDayOfWeek: 1,\n showMonthAfterYear: false,\n dateFormat: 'dd/mm/yy',\n weak: 'Faible',\n medium: 'Moyen',\n strong: 'Fort',\n passwordPrompt: 'Entrez un mot de passe',\n emptyFilterMessage: 'Aucun résultat trouvé',\n searchMessage: '{0} résultats sont disponibles',\n selectionMessage: '{0} éléments sélectionnés',\n emptySelectionMessage: 'Aucun élément sélectionné',\n emptySearchMessage: 'Aucun résultat trouvé',\n emptyMessage: 'Aucune option disponible',\n aria: {\n trueLabel: 'Vrai',\n falseLabel: 'Faux',\n nullLabel: 'Non sélectionné',\n star: '1 étoile',\n stars: '{star} étoiles',\n selectAll: 'Tous les éléments sélectionnés',\n unselectAll: 'Tous les éléments désélectionnés',\n close: 'Fermer',\n previous: 'Précédent',\n next: 'Suivant',\n navigation: 'Navigation',\n scrollTop: 'Défiler vers le haut',\n moveTop: 'Déplacer vers le haut',\n moveUp: 'Déplacer vers le haut',\n moveDown: 'Déplacer vers le bas',\n moveBottom: 'Déplacer vers le bas',\n moveToTarget: 'Déplacer vers la cible',\n moveToSource: 'Déplacer vers la source',\n moveAllToTarget: 'Tout déplacer vers la cible',\n moveAllToSource: 'Tout déplacer vers la source',\n pageLabel: 'Page {page}',\n firstPageLabel: 'Première page',\n lastPageLabel: 'Dernière page',\n nextPageLabel: 'Page suivante',\n prevPageLabel: 'Page précédente',\n rowsPerPageLabel: 'Lignes par page',\n jumpToPageDropdownLabel: 'Aller à la page',\n jumpToPageInputLabel: 'Aller à la page',\n selectRow: 'Ligne sélectionnée',\n unselectRow: 'Ligne désélectionnée',\n expandRow: 'Ligne développée',\n collapseRow: 'Ligne réduite',\n showFilterMenu: 'Afficher le menu de filtrage',\n hideFilterMenu: 'Masquer le menu de filtrage',\n filterOperator: 'Opérateur de filtrage',\n filterConstraint: 'Contrainte de filtrage',\n editRow: 'Modifier la ligne',\n saveEdit: 'Enregistrer la modification',\n cancelEdit: 'Annuler la modification',\n listView: 'Vue en liste',\n gridView: 'Vue en grille',\n slide: 'Glisser',\n slideNumber: '{slideNumber}',\n zoomImage: \"Agrandir l'image\",\n zoomIn: 'Zoomer',\n zoomOut: 'Dézoomer',\n rotateRight: 'Faire pivoter à droite',\n rotateLeft: 'Faire pivoter à gauche',\n listLabel: 'Liste',\n },\n} as Translation;\n","import { Translation } from 'primeng/api';\n\n/**\n * Arabic locale for PrimeNG components (Moroccan month names).\n *\n * Usage:\n * ```ts\n * import { PRIMENG_AR_LOCALE } from '@elasticias/core';\n * this.primeng.translation = PRIMENG_AR_LOCALE;\n * ```\n */\nexport const PRIMENG_AR_LOCALE: Translation = {\n startsWith: 'يبدأ بـ',\n contains: 'يحتوي على',\n notContains: 'لا يحتوي على',\n endsWith: 'ينتهي بـ',\n equals: 'يساوي',\n notEquals: 'لا يساوي',\n noFilter: 'بدون فلتر',\n lt: 'أقل من',\n lte: 'أقل من أو يساوي',\n gt: 'أكبر من',\n gte: 'أكبر من أو يساوي',\n dateIs: 'التاريخ هو',\n dateIsNot: 'التاريخ ليس',\n dateBefore: 'التاريخ قبل',\n dateAfter: 'التاريخ بعد',\n clear: 'مسح',\n apply: 'تطبيق',\n matchAll: 'تطابق الكل',\n matchAny: 'تطابق أي',\n addRule: 'إضافة قاعدة',\n removeRule: 'حذف القاعدة',\n accept: 'نعم',\n reject: 'لا',\n choose: 'اختيار',\n upload: 'رفع',\n cancel: 'إلغاء',\n completed: 'مكتمل',\n pending: 'قيد الانتظار',\n fileSizeTypes: ['بايت', 'ك.ب', 'م.ب', 'ج.ب', 'ت.ب', 'ب.ب', 'إ.ب', 'ز.ب', 'ي.ب'],\n dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],\n dayNamesShort: ['أحد', 'اثن', 'ثلا', 'أرب', 'خمي', 'جمع', 'سبت'],\n dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'],\n monthNames: ['يناير', 'فبراير', 'مارس', 'أبريل', 'ماي', 'يونيو', 'يوليوز', 'غشت', 'شتنبر', 'أكتوبر', 'نونبر', 'دجنبر'],\n monthNamesShort: ['ينا', 'فبر', 'مار', 'أبر', 'ماي', 'يون', 'يول', 'غشت', 'شتن', 'أكت', 'نون', 'دجن'],\n chooseYear: 'اختر السنة',\n chooseMonth: 'اختر الشهر',\n chooseDate: 'اختر التاريخ',\n prevDecade: 'العقد السابق',\n nextDecade: 'العقد التالي',\n prevYear: 'السنة السابقة',\n nextYear: 'السنة التالية',\n prevMonth: 'الشهر السابق',\n nextMonth: 'الشهر التالي',\n prevHour: 'الساعة السابقة',\n nextHour: 'الساعة التالية',\n prevMinute: 'الدقيقة السابقة',\n nextMinute: 'الدقيقة التالية',\n prevSecond: 'الثانية السابقة',\n nextSecond: 'الثانية التالية',\n am: 'ص',\n pm: 'م',\n today: 'اليوم',\n weekHeader: 'أس',\n firstDayOfWeek: 1,\n showMonthAfterYear: false,\n dateFormat: 'dd/mm/yy',\n weak: 'ضعيف',\n medium: 'متوسط',\n strong: 'قوي',\n passwordPrompt: 'أدخل كلمة المرور',\n emptyFilterMessage: 'لم يتم العثور على نتائج',\n searchMessage: '{0} نتائج متاحة',\n selectionMessage: '{0} عناصر محددة',\n emptySelectionMessage: 'لا يوجد عنصر محدد',\n emptySearchMessage: 'لم يتم العثور على نتائج',\n emptyMessage: 'لا توجد خيارات متاحة',\n aria: {\n trueLabel: 'صحيح',\n falseLabel: 'خاطئ',\n nullLabel: 'غير محدد',\n star: 'نجمة واحدة',\n stars: '{star} نجوم',\n selectAll: 'تم تحديد جميع العناصر',\n unselectAll: 'تم إلغاء تحديد جميع العناصر',\n close: 'إغلاق',\n previous: 'السابق',\n next: 'التالي',\n navigation: 'التنقل',\n scrollTop: 'التمرير للأعلى',\n moveTop: 'نقل للأعلى',\n moveUp: 'نقل للأعلى',\n moveDown: 'نقل للأسفل',\n moveBottom: 'نقل للأسفل',\n moveToTarget: 'نقل إلى الهدف',\n moveToSource: 'نقل إلى المصدر',\n moveAllToTarget: 'نقل الكل إلى الهدف',\n moveAllToSource: 'نقل الكل إلى المصدر',\n pageLabel: 'صفحة {page}',\n firstPageLabel: 'الصفحة الأولى',\n lastPageLabel: 'الصفحة الأخيرة',\n nextPageLabel: 'الصفحة التالية',\n prevPageLabel: 'الصفحة السابقة',\n rowsPerPageLabel: 'سطور في الصفحة',\n jumpToPageDropdownLabel: 'الانتقال إلى الصفحة',\n jumpToPageInputLabel: 'الانتقال إلى الصفحة',\n selectRow: 'تم تحديد السطر',\n unselectRow: 'تم إلغاء تحديد السطر',\n expandRow: 'تم توسيع السطر',\n collapseRow: 'تم طي السطر',\n showFilterMenu: 'إظهار قائمة الفلتر',\n hideFilterMenu: 'إخفاء قائمة الفلتر',\n filterOperator: 'عامل الفلتر',\n filterConstraint: 'قيد الفلتر',\n editRow: 'تعديل السطر',\n saveEdit: 'حفظ التعديل',\n cancelEdit: 'إلغاء التعديل',\n listView: 'عرض قائمة',\n gridView: 'عرض شبكة',\n slide: 'تمرير',\n slideNumber: '{slideNumber}',\n zoomImage: 'تكبير الصورة',\n zoomIn: 'تكبير',\n zoomOut: 'تصغير',\n rotateRight: 'تدوير لليمين',\n rotateLeft: 'تدوير لليسار',\n listLabel: 'قائمة',\n },\n} as Translation;\n","import { InjectionToken } from '@angular/core';\n\n/**\n * The eight ERP modules surfaced by Comptoir. New modules require\n * a matching `--m-{id}` token in the SCSS layer (libs/ui/src/lib/_comptoir.scss)\n * and a labelKey in the consuming app's i18n bundles.\n */\nexport type EfModuleId =\n | 'sales'\n | 'purchase'\n | 'stock'\n | 'pos'\n | 'marketing'\n | 'store'\n | 'finance'\n | 'admin';\n\nexport type EfNavAction = 'read' | 'write' | 'admin';\n\nexport interface EfNavItem {\n /** Stable identifier — usually matches the screen code (e.g. `Users`, `SalesOrders`). */\n id: string;\n labelKey: string;\n icon?: string;\n route: string;\n /** Minimum permission level required to render this item. Defaults to `read`. */\n requiredAction?: EfNavAction;\n /**\n * Optional count chip rendered after the label (e.g. `Commandes ⟨14⟩`).\n * Apps typically derive this from a service signal and patch the\n * registry — it can be number, string, or anything stringifiable.\n */\n badge?: string | number;\n}\n\nexport interface EfNavSection {\n id: string;\n labelKey?: string;\n items: EfNavItem[];\n}\n\nexport interface EfModule {\n id: EfModuleId;\n labelKey: string;\n /** PrimeNG icon class used by `ef-module-rail`, e.g. `pi pi-shopping-bag`. */\n icon: string;\n /**\n * CSS custom-property name (without the leading `--`) that the rail\n * applies to the module-current accent. Always `m-{id}` and resolves\n * via the SCSS layer's `[data-module]` selectors at runtime.\n */\n accent: `m-${EfModuleId}`;\n defaultRoute: string;\n navSections: EfNavSection[];\n /**\n * Logical grouping for rail divider placement. `ef-module-rail` renders\n * a 1px divider between two consecutive visible modules whose `group`\n * differs. Free string — `'operations' | 'commerce' | 'admin'` is the\n * conventional set but apps can use anything stable.\n */\n group?: string;\n}\n\n/**\n * Default skeleton for the eight ERP modules. Apps either consume this\n * directly via `EF_MODULES_TOKEN` or extend it with their own `navSections`.\n *\n * Phase 1 ships the metadata only — `ef-module-rail` (Phase 2) uses\n * `id` / `labelKey` / `icon` / `accent` / `defaultRoute`. `navSections`\n * are populated per-app as each module's screens land in Phase 4-5.\n */\nexport const EF_MODULES: ReadonlyArray<EfModule> = [\n {\n id: 'sales',\n labelKey: 'modules.sales',\n icon: 'pi pi-shopping-bag',\n accent: 'm-sales',\n defaultRoute: '/operations/sales',\n navSections: [],\n group: 'operations',\n },\n {\n id: 'purchase',\n labelKey: 'modules.purchase',\n icon: 'pi pi-truck',\n accent: 'm-purchase',\n defaultRoute: '/operations/purchase',\n navSections: [],\n group: 'operations',\n },\n {\n id: 'stock',\n labelKey: 'modules.stock',\n icon: 'pi pi-warehouse',\n accent: 'm-stock',\n defaultRoute: '/operations/stock',\n navSections: [],\n group: 'operations',\n },\n {\n id: 'pos',\n labelKey: 'modules.pos',\n icon: 'pi pi-shop',\n accent: 'm-pos',\n defaultRoute: '/pos',\n navSections: [],\n group: 'operations',\n },\n {\n id: 'marketing',\n labelKey: 'modules.marketing',\n icon: 'pi pi-megaphone',\n accent: 'm-marketing',\n defaultRoute: '/marketing',\n navSections: [],\n group: 'commerce',\n },\n {\n id: 'store',\n labelKey: 'modules.store',\n icon: 'pi pi-globe',\n accent: 'm-store',\n defaultRoute: '/store',\n navSections: [],\n group: 'commerce',\n },\n {\n id: 'finance',\n labelKey: 'modules.finance',\n icon: 'pi pi-chart-line',\n accent: 'm-finance',\n defaultRoute: '/finance',\n navSections: [],\n group: 'commerce',\n },\n {\n id: 'admin',\n labelKey: 'modules.admin',\n icon: 'pi pi-shield',\n accent: 'm-admin',\n defaultRoute: '/admin',\n navSections: [],\n group: 'admin',\n },\n];\n\n/**\n * DI token that the shell components (`ef-module-rail`, `ef-module-side`)\n * read from. Apps provide their own definition (typically extending\n * `EF_MODULES` with populated `navSections`):\n *\n * ```ts\n * providers: [\n * { provide: EF_MODULES_TOKEN, useValue: APP_MODULES }\n * ]\n * ```\n */\nexport const EF_MODULES_TOKEN = new InjectionToken<ReadonlyArray<EfModule>>(\n 'EF_MODULES',\n { providedIn: 'root', factory: () => EF_MODULES }\n);\n","import { computed, DestroyRef, inject, Injectable, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { filter } from 'rxjs/operators';\nimport { EF_MODULES_TOKEN, EfModule, EfModuleId, EfNavItem } from './ef-module-registry';\n\n/**\n * Single source of truth for \"which ERP module is active right now.\"\n *\n * Watches the Router and matches the current URL against each module's\n * `defaultRoute`. The longest matching prefix wins, so `/operations/sales`\n * resolves to `sales` even though `/operations` could in theory match\n * something shorter.\n *\n * Consumers — `ef-module-rail`, `ef-module-side`, `ef-app-main`,\n * `ef-page-head` — read `activeModule()` and derive their state from it.\n *\n * Apps that navigate programmatically without a URL change (rare) can\n * call `setActiveModule(id)` to override.\n */\n@Injectable({ providedIn: 'root' })\nexport class EfActiveModuleService {\n private readonly router = inject(Router);\n private readonly modules = inject(EF_MODULES_TOKEN);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly _activeModule = signal<EfModule | null>(null);\n private readonly _activeNavItem = signal<EfNavItem | null>(null);\n\n readonly activeModule = this._activeModule.asReadonly();\n readonly activeModuleId = computed(() => this._activeModule()?.id ?? null);\n readonly activeNavItem = this._activeNavItem.asReadonly();\n\n constructor() {\n this.resolveFromUrl(this.router.url);\n\n this.router.events\n .pipe(\n filter((e): e is NavigationEnd => e instanceof NavigationEnd),\n takeUntilDestroyed(this.destroyRef),\n )\n .subscribe(e => this.resolveFromUrl(e.urlAfterRedirects));\n }\n\n /**\n * Force the active module. Most apps don't need this — the router\n * subscription keeps `activeModule()` in sync automatically.\n */\n setActiveModule(id: EfModuleId | null): void {\n if (id === null) {\n this._activeModule.set(null);\n return;\n }\n const match = this.modules.find(m => m.id === id);\n if (match) this._activeModule.set(match);\n }\n\n private resolveFromUrl(url: string): void {\n const path = url.split('?')[0].split('#')[0];\n\n let bestModule: EfModule | null = null;\n let bestNavItem: EfNavItem | null = null;\n let bestLen = 0;\n for (const m of this.modules) {\n for (const route of this.routesFor(m)) {\n if (path === route || path.startsWith(route + '/')) {\n if (route.length > bestLen) {\n bestModule = m;\n bestNavItem = this.findNavItem(m, route);\n bestLen = route.length;\n }\n }\n }\n }\n this._activeModule.set(bestModule);\n this._activeNavItem.set(bestNavItem);\n }\n\n private findNavItem(m: EfModule, route: string): EfNavItem | null {\n for (const section of m.navSections) {\n for (const item of section.items) {\n if (item.route === route) return item;\n }\n }\n return null;\n }\n\n /**\n * Every URL prefix that should resolve back to this module: the\n * `defaultRoute` plus every nav item route. Modules whose nav items\n * span multiple URL prefixes (e.g. sales spread across `/operations/sales`\n * and `/parameters/sales`) need this to stay active across all of them.\n */\n private routesFor(m: EfModule): string[] {\n const routes: string[] = [m.defaultRoute];\n for (const section of m.navSections) {\n for (const item of section.items) {\n routes.push(item.route);\n }\n }\n return routes;\n }\n}\n","import { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { computed, DestroyRef, inject, Injectable, PLATFORM_ID, signal } from '@angular/core';\n\nexport type EfViewport = 'mobile' | 'tablet' | 'desktop';\n\ninterface ViewportQuery {\n viewport: EfViewport;\n query: string;\n}\n\nconst QUERIES: ViewportQuery[] = [\n { viewport: 'mobile', query: '(max-width: 767px)' },\n { viewport: 'tablet', query: '(min-width: 768px) and (max-width: 1279px)' },\n { viewport: 'desktop', query: '(min-width: 1280px)' },\n];\n\n/**\n * Emits the current viewport tier based on `window.matchMedia` breakpoints.\n *\n * Breakpoints come from `libs/tokens/targets.json`:\n * - mobile: ≤ 767px\n * - tablet: 768 – 1279px\n * - desktop: ≥ 1280px\n *\n * SSR-safe: returns `'desktop'` when `window` is unavailable.\n *\n * Usage:\n * ```ts\n * private viewport = inject(EfViewportService);\n *\n * isMobile = computed(() => this.viewport.current() === 'mobile');\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class EfViewportService {\n private readonly document = inject(DOCUMENT);\n private readonly platformId = inject(PLATFORM_ID);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly _current = signal<EfViewport>('desktop');\n\n readonly current = this._current.asReadonly();\n readonly isMobile = computed(() => this._current() === 'mobile');\n readonly isTablet = computed(() => this._current() === 'tablet');\n readonly isDesktop = computed(() => this._current() === 'desktop');\n\n constructor() {\n if (!isPlatformBrowser(this.platformId)) return;\n\n const win = this.document.defaultView;\n if (!win || typeof win.matchMedia !== 'function') return;\n\n const lists = QUERIES.map(({ viewport, query }) => {\n const mql = win.matchMedia(query);\n const handler = (e: MediaQueryListEvent | MediaQueryList) => {\n if (e.matches) this._current.set(viewport);\n };\n handler(mql);\n mql.addEventListener('change', handler as (e: MediaQueryListEvent) => void);\n return { mql, handler };\n });\n\n this.destroyRef.onDestroy(() => {\n for (const { mql, handler } of lists) {\n mql.removeEventListener('change', handler as (e: MediaQueryListEvent) => void);\n }\n });\n }\n}\n","import { computed, inject, Injectable, Signal, signal } from '@angular/core';\nimport { EF_MODULES_TOKEN, EfModule, EfModuleId } from '../modules/ef-module-registry';\n\nexport type EfPermissionLevel = 'none' | 'read' | 'write' | 'admin';\n\nexport interface EfModulePermission {\n module: EfModuleId;\n level: EfPermissionLevel;\n}\n\nconst LEVEL_ORDER: Record<EfPermissionLevel, number> = {\n none: 0,\n read: 1,\n write: 2,\n admin: 3,\n};\n\nconst ACTION_REQUIRED: Record<Exclude<EfPermissionLevel, 'none'>, EfPermissionLevel> = {\n read: 'read',\n write: 'write',\n admin: 'admin',\n};\n\n/**\n * Module-scoped permission service.\n *\n * Apps populate it from their auth bootstrap once the user's profile is\n * loaded — typically via `setPermissions()` or by providing a custom\n * source signal:\n *\n * ```ts\n * // bootstrap.ts\n * const perms = inject(EfPermissionService);\n * perms.setPermissions(profile.permissions);\n * ```\n *\n * The service is the single source of truth for shell components\n * (`ef-module-rail`, `ef-module-side`, `*efCan` directive) and routing\n * defaults. Once the screens/menus → Mongo migration lands, the\n * permissions list will be served denormalized on the user/profile\n * document and consumed here without a join.\n */\n@Injectable({ providedIn: 'root' })\nexport class EfPermissionService {\n private readonly modules = inject(EF_MODULES_TOKEN);\n\n private readonly _permissions = signal<ReadonlyArray<EfModulePermission>>([]);\n\n readonly permissions = this._permissions.asReadonly();\n\n /**\n * Replace the current permission set. Pass `[]` to clear (e.g., on logout).\n */\n setPermissions(perms: ReadonlyArray<EfModulePermission>): void {\n this._permissions.set(perms);\n }\n\n /**\n * The level granted to the current user for a given module.\n * Returns `'none'` if the module is not in the permission set.\n */\n level(module: EfModuleId): EfPermissionLevel {\n return this._permissions().find(p => p.module === module)?.level ?? 'none';\n }\n\n /**\n * Whether the current user can perform `action` on `module`.\n * Levels are hierarchical: `admin` > `write` > `read` > `none`.\n */\n can(module: EfModuleId, action: Exclude<EfPermissionLevel, 'none'> = 'read'): boolean {\n return LEVEL_ORDER[this.level(module)] >= LEVEL_ORDER[ACTION_REQUIRED[action]];\n }\n\n /**\n * The list of modules the user can read, in registry order.\n * Used by `ef-module-rail` to decide which icons render.\n */\n readonly visibleModules: Signal<ReadonlyArray<EfModule>> = computed(() => {\n const perms = this._permissions();\n const granted = new Set(\n perms.filter(p => p.level !== 'none').map(p => p.module)\n );\n return this.modules.filter(m => granted.has(m.id));\n });\n\n /**\n * The first visible module — the default landing module after login.\n * Returns `null` when the user has no modules.\n */\n readonly defaultModule: Signal<EfModule | null> = computed(() => {\n return this.visibleModules()[0] ?? null;\n });\n}\n","import { InjectionToken } from '@angular/core';\n\n/**\n * The bit of an app's session that shared chrome needs to act on.\n *\n * Signing out belongs to the app — it owns the auth client, the grant\n * refresh timer and where to land afterwards — but the control that\n * triggers it belongs to the shell. This token is the seam between them,\n * the same shape as `SCREEN_REF_DATA_SERVICE`.\n *\n * Components inject it optionally and hide their affordance when nothing\n * provides it, so an app that has not opted in shows no dead button.\n *\n * ```ts\n * // app.config.ts\n * { provide: EF_SESSION, useExisting: AuthorizeService }\n * ```\n */\nexport interface EfSession {\n /** End the session and send the user wherever the app decides. */\n logout(): void;\n}\n\nexport const EF_SESSION = new InjectionToken<EfSession>('EF_SESSION');\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Which build of the app is running.\n *\n * Apps generate this at build time — the framework cannot know it — and\n * provide it here so shared chrome can show it without importing anything\n * app-specific. `EfBuildStampComponent` is the intended consumer.\n *\n * ```ts\n * // app.config.ts\n * { provide: EF_BUILD_INFO, useValue: BUILD_INFO }\n * ```\n */\nexport interface EfBuildInfo {\n /** Release version. Empty when the app maintains none — consumers should\n * omit it rather than print a placeholder. */\n version: string;\n\n /** Short commit hash the build came from. */\n commit: string;\n\n /** Commit date as `YYYY-MM-DD` — what a reader actually recognises. */\n date: string;\n\n /** Branch the build came from, useful for telling develop from a release. */\n branch: string;\n\n /**\n * Which deployment this build was made for: `production`, `staging`,\n * `develop`, or `local`. Decided at build time from the ref, because a\n * production build is made from a tag rather than a branch.\n */\n environment: string;\n\n /**\n * The shared `@elasticias/*` packages this build was compiled against,\n * in the order the app wants them listed.\n *\n * Optional: an app that ships no shared packages, or generates its stamp\n * without resolving them, simply omits the key and consumers render\n * nothing rather than an empty group.\n */\n packages?: EfBuildPackage[];\n}\n\n/** One shared package and the version that went into the build. */\nexport interface EfBuildPackage {\n /** Package name as it appears in `package.json`, e.g. `@elasticias/ui`. */\n name: string;\n\n /** The version actually installed, not the range the app declared. */\n version: string;\n}\n\nexport const EF_BUILD_INFO = new InjectionToken<EfBuildInfo>('EF_BUILD_INFO');\n","import { HttpBackend, HttpClient } from '@angular/common/http';\nimport { inject, InjectionToken, Provider } from '@angular/core';\nimport { TranslateLoader, TranslationObject } from '@ngx-translate/core';\nimport { Observable } from 'rxjs';\nimport { EF_BUILD_INFO } from '../build/ef-build-info.token';\n\n/**\n * Where the translation files live, and how their URL is stamped.\n */\nexport interface EfVersionedTranslateLoaderConfig {\n /** Path the language file sits under. Defaults to `/assets/i18n/`. */\n prefix?: string;\n\n /** File extension. Defaults to `.json`. */\n suffix?: string;\n\n /**\n * Build identifier appended as `?v=`. Defaults to `EF_BUILD_INFO.commit`,\n * which the app already regenerates on every build, so a release changes\n * every translation URL without anyone maintaining a second number.\n */\n version?: string;\n\n /**\n * Bypass the HTTP interceptor chain. On by default: a translation file is\n * a static asset, and putting it through the app's auth interceptor means\n * a 401 handler can fire before the app knows how to say anything.\n */\n useHttpBackend?: boolean;\n}\n\nexport const EF_TRANSLATE_LOADER_CONFIG = new InjectionToken<EfVersionedTranslateLoaderConfig>(\n 'EF_TRANSLATE_LOADER_CONFIG',\n);\n\n/**\n * Translation loader that puts the build id in the URL.\n *\n * Angular content-hashes its JS and CSS but copies `/assets` verbatim, so a\n * translation file ships new content at a URL that never changes — the one\n * case HTTP caching handles worst. Two things follow from that.\n *\n * The first is ordinary staleness: a device holding yesterday's copy has no\n * reason to ask for today's, so a newly added key renders as its raw key.\n *\n * The second is worse and is why this exists rather than a cache header. A\n * device that cached the file while the server was still sending\n * `max-age=31536000, immutable` will not re-request it for up to a year, and\n * therefore never sees whatever header we send next. Headers only reach\n * browsers that ask. A URL they have never seen has no cache entry at all, so\n * changing the URL is the only thing that reaches them.\n *\n * Stamping the build id also means the URL is stable *within* a release, so\n * the file can go back to being cached hard instead of revalidated on every\n * single page load.\n */\nexport class EfVersionedTranslateLoader implements TranslateLoader {\n private readonly cfg = inject(EF_TRANSLATE_LOADER_CONFIG, { optional: true }) ?? {};\n private readonly buildInfo = inject(EF_BUILD_INFO, { optional: true });\n\n /**\n * Built from `HttpBackend` rather than injecting `HttpClient`, so the\n * request skips interceptors. See `useHttpBackend`.\n */\n private readonly http =\n this.cfg.useHttpBackend === false\n ? inject(HttpClient)\n : new HttpClient(inject(HttpBackend));\n\n getTranslation(lang: string): Observable<TranslationObject> {\n const prefix = this.cfg.prefix ?? '/assets/i18n/';\n const suffix = this.cfg.suffix ?? '.json';\n const version = this.cfg.version ?? this.buildInfo?.commit ?? '';\n\n // No build id (a bare `ng serve`, or an app that ships no stamp) means\n // no query string at all, rather than `?v=` — a URL that changes shape\n // between environments is harder to reason about than one that doesn't.\n const url = `${prefix}${lang}${suffix}${version ? `?v=${encodeURIComponent(version)}` : ''}`;\n return this.http.get<TranslationObject>(url);\n }\n}\n\n/**\n * Provide the versioned loader in place of `provideTranslateHttpLoader`.\n *\n * ```ts\n * provideTranslateService({ fallbackLang: 'fr', lang }),\n * provideEfTranslateLoader({ prefix: '/assets/i18n/' }),\n * ```\n *\n * Pair it with a long-lived cache header on the translation files: the URL now\n * carries the release, so there is nothing left to revalidate against.\n */\nexport function provideEfTranslateLoader(\n config: EfVersionedTranslateLoaderConfig = {},\n): Provider[] {\n return [\n { provide: EF_TRANSLATE_LOADER_CONFIG, useValue: config },\n { provide: TranslateLoader, useClass: EfVersionedTranslateLoader },\n ];\n}\n","/**\n * Key-combo parsing shared by `EfShortcutService` (matching a keydown event\n * against the registry) and `formatShortcut` (rendering a registration for\n * display). Kept internal to the shortcuts folder: neither export is part\n * of the public `@elasticias/core` surface.\n */\n\n/** Fixed order modifiers are stored and compared in, so `'shift+mod+x'`\n * and `'mod+shift+x'` normalise to the same string. */\nconst MODIFIER_ORDER = ['mod', 'shift', 'alt'] as const;\n\n/**\n * Physical-key `KeyboardEvent.code` values mapped to the token used in a\n * `keys` string. `code` identifies the physical key regardless of what\n * Shift makes it print, which is what lets `'shift+/'` match the key next\n * to Right Shift on a US layout even though pressing it actually produces\n * `'?'`.\n */\nconst CODE_KEYS: Record<string, string> = {\n Enter: 'enter',\n Escape: 'escape',\n Space: 'space',\n Backspace: 'backspace',\n Tab: 'tab',\n Slash: '/',\n};\n\n/** Normalises a `keys` registration string into a canonical, comparable\n * form: lowercase tokens, modifiers first in a fixed order. */\nexport function normaliseKeys(raw: string): string {\n const tokens = raw\n .toLowerCase()\n .split('+')\n .map(token => token.trim())\n .filter(Boolean);\n const modifierTokens = MODIFIER_ORDER.filter(modifier => tokens.includes(modifier));\n const rest = tokens.filter(token => !(MODIFIER_ORDER as readonly string[]).includes(token));\n return [...modifierTokens, ...rest].join('+');\n}\n\ninterface KeyEventLike {\n code: string;\n key: string;\n metaKey: boolean;\n ctrlKey: boolean;\n shiftKey: boolean;\n altKey: boolean;\n}\n\n/** The canonical key token for an event, independent of Shift. `KeyD`\n * is `'d'` whether or not Shift was held. */\nfunction keyToken(event: KeyEventLike): string {\n if (CODE_KEYS[event.code]) return CODE_KEYS[event.code];\n if (event.code?.startsWith('Key')) return event.code.slice(3).toLowerCase();\n if (event.code?.startsWith('Digit')) return event.code.slice(5);\n return event.key.toLowerCase();\n}\n\n/**\n * Builds the normalised combo a keydown event represents, e.g. `'mod+d'`.\n * `isMac` decides which physical modifier counts as `mod`: Meta on macOS,\n * Control everywhere else.\n */\nexport function comboFromEvent(event: KeyEventLike, isMac: boolean): string {\n const tokens: string[] = [];\n if (isMac ? event.metaKey : event.ctrlKey) tokens.push('mod');\n if (event.shiftKey) tokens.push('shift');\n if (event.altKey) tokens.push('alt');\n tokens.push(keyToken(event));\n return normaliseKeys(tokens.join('+'));\n}\n\n/**\n * True while the event target is a place the user is typing: an input, a\n * textarea, a select, or anything `contenteditable`. The dispatcher checks\n * this before anything else. Without it every shortcut key is a reserved\n * word in every text field in the app.\n */\nexport function isTypingTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n const tag = target.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true;\n return target.isContentEditable;\n}\n","import { normaliseKeys } from './shortcut-keys';\n\n/** Reads the platform once. `userAgentData` is the current standard; the\n * `platform` string fallback covers browsers that don't expose it yet.\n *\n * The test is \"Apple\", not \"Mac\". An iPhone reports `iPhone` and an iPad\n * reports either `iPad` or, since iPadOS 13, the same `MacIntel` a desktop\n * does. A narrower `/mac/i` told every iOS device with a keyboard that the\n * modifier was Ctrl, which is the one thing it is not. */\nfunction detectApplePlatform(): boolean {\n if (typeof navigator === 'undefined') return false;\n const uaData = (navigator as Navigator & { userAgentData?: { platform?: string } })\n .userAgentData;\n const platform = uaData?.platform ?? navigator.platform ?? '';\n return /mac|iphone|ipad|ipod/i.test(platform);\n}\n\n/**\n * Detected once, at module load. `formatShortcut` uses it to choose between\n * the Command glyphs and the Ctrl words. True for every Apple platform, not\n * just the desktop: an iPad with a keyboard sends Command like a Mac does.\n */\nexport const isMacPlatform: boolean = detectApplePlatform();\n\nconst MAC_MODIFIER_GLYPHS: Record<string, string> = {\n mod: '⌘',\n shift: '⇧',\n alt: '⌥',\n};\n\nconst OTHER_MODIFIER_WORDS: Record<string, string> = {\n mod: 'Ctrl',\n shift: 'Shift',\n alt: 'Alt',\n};\n\n/** Named keys with a glyph of their own, distinct from their letter. */\nconst KEY_GLYPHS: Record<string, string> = {\n enter: '↵',\n escape: 'Esc',\n backspace: '⌫',\n space: 'Space',\n tab: 'Tab',\n};\n\n/**\n * A produced character that stands in for the whole combo. Shift plus the\n * physical `/` key always reads as the question mark it prints. Showing\n * it as `'Shift' + '/'` would describe the keys pressed rather than the\n * shortcut a person recognises.\n */\nconst SHIFTED_SYMBOL_GLYPHS: Record<string, string> = {\n '/': '?',\n};\n\n/**\n * Formats a `keys` registration for display. One registration, correct on\n * both platforms:\n *\n * - `'mod+d'` → `⌘D` on macOS, `Ctrl+D` elsewhere\n * - `'enter'` → `↵`\n * - `'e'` → `E`\n * - `'shift+/'` → `?`\n *\n * `mac` defaults to the platform this code is actually running on. Pass it\n * explicitly only to render for a platform other than the current one.\n */\nexport function formatShortcut(keys: string, mac: boolean = isMacPlatform): string {\n const tokens = normaliseKeys(keys).split('+');\n const key = tokens[tokens.length - 1];\n const modifiers = tokens.slice(0, -1);\n\n if (modifiers.length === 1 && modifiers[0] === 'shift' && SHIFTED_SYMBOL_GLYPHS[key]) {\n return SHIFTED_SYMBOL_GLYPHS[key];\n }\n\n const displayKey = KEY_GLYPHS[key] ?? key.toUpperCase();\n\n if (mac) {\n return modifiers.map(modifier => MAC_MODIFIER_GLYPHS[modifier] ?? modifier).join('') + displayKey;\n }\n\n const words = modifiers.map(modifier => OTHER_MODIFIER_WORDS[modifier] ?? modifier);\n return [...words, displayKey].join('+');\n}\n","import { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { computed, DestroyRef, inject, Injectable, PLATFORM_ID, signal } from '@angular/core';\nimport { isMacPlatform } from './format-shortcut';\nimport { comboFromEvent, isTypingTarget, normaliseKeys } from './shortcut-keys';\nimport { EfShortcut, EfShortcutGroup } from './ef-shortcut.types';\n\n/**\n * App-wide keyboard-shortcut registry, plus the single `document:keydown`\n * dispatcher that acts on it.\n *\n * ```ts\n * private readonly shortcuts = inject(EfShortcutService);\n *\n * constructor() {\n * // Auto-unregisters on this component's DestroyRef, called from a\n * // constructor / field initializer, an active injection context.\n * this.shortcuts.register({\n * id: 'sales-order.save',\n * keys: 'mod+s',\n * labelKey: 'sales_order_save',\n * group: 'shortcut_group_sales_order',\n * handler: () => this.save(),\n * });\n * }\n * ```\n *\n * Two things make this safe to leave switched on everywhere:\n * - The dispatcher ignores keydown while the target is an input, textarea,\n * select, or anything `contenteditable`, unless the combo includes\n * `mod`. A bare key or a Shift/Alt combo could be real typing (Alt and\n * AltGr both produce characters on several layouts this app ships), but\n * `mod` never does, and a save/search shortcut is normally pressed from\n * inside the very field it acts on. See `isTypingTarget`.\n * - `preventDefault` is only called once a registration actually matches,\n * so an unmapped key never loses its browser default.\n *\n * `list()` exposes the registry grouped for `ef-shortcuts-dialog`, as a\n * signal so the dialog reflects registrations and disposals live.\n */\n@Injectable({ providedIn: 'root' })\nexport class EfShortcutService {\n private readonly document = inject(DOCUMENT);\n private readonly platformId = inject(PLATFORM_ID);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly registry = signal<ReadonlyMap<string, EfShortcut>>(new Map());\n\n /**\n * The registry, grouped for display and deduplicated by\n * (group, label, keys): several instances of the same conceptual\n * shortcut (one row-actions component per row, say) collapse to a\n * single line rather than repeating once per instance.\n */\n readonly list = computed<EfShortcutGroup[]>(() => {\n const deduped = new Map<string, EfShortcut>();\n for (const shortcut of this.registry().values()) {\n const key = `${shortcut.group}::${shortcut.labelKey}::${shortcut.keys}`;\n if (!deduped.has(key)) deduped.set(key, shortcut);\n }\n\n const byGroup = new Map<string, EfShortcut[]>();\n for (const shortcut of deduped.values()) {\n const group = byGroup.get(shortcut.group) ?? [];\n group.push(shortcut);\n byGroup.set(shortcut.group, group);\n }\n\n return Array.from(byGroup.entries()).map(([group, shortcuts]) => ({ group, shortcuts }));\n });\n\n constructor() {\n if (!isPlatformBrowser(this.platformId)) return;\n this.document.addEventListener('keydown', this.onKeydown);\n this.destroyRef.onDestroy(() => this.document.removeEventListener('keydown', this.onKeydown));\n }\n\n /**\n * Registers a shortcut and returns a disposer. When `register` is\n * called from an active injection context (a component constructor or\n * field initializer), the shortcut also auto-unregisters when that\n * context is destroyed. Call it explicitly elsewhere (a plain method,\n * a route resolver already outside construction) and dispose it\n * yourself.\n */\n register(shortcut: EfShortcut): () => void {\n const entry: EfShortcut = { ...shortcut, keys: normaliseKeys(shortcut.keys) };\n\n this.registry.update(map => {\n const next = new Map(map);\n next.set(entry.id, entry);\n return next;\n });\n\n const dispose = (): void => this.unregister(entry.id);\n this.tryGetCallerDestroyRef()?.onDestroy(dispose);\n return dispose;\n }\n\n /** Removes a registration by id. Safe to call twice: the disposer\n * returned by `register` calls this. */\n unregister(id: string): void {\n this.registry.update(map => {\n if (!map.has(id)) return map;\n const next = new Map(map);\n next.delete(id);\n return next;\n });\n }\n\n /** `inject()` throws outside an active injection context; that is how\n * a call from a plain method (as opposed to a constructor) is told\n * apart from one worth auto-disposing. */\n private tryGetCallerDestroyRef(): DestroyRef | null {\n try {\n return inject(DestroyRef, { optional: true });\n } catch {\n return null;\n }\n }\n\n private readonly onKeydown = (event: KeyboardEvent): void => {\n const combo = comboFromEvent(event, isMacPlatform);\n\n // A bare key, or one held with only Shift or Alt, is something the\n // user could plausibly be typing (Alt/AltGr produces real\n // characters on several layouts this app ships, French and\n // Moroccan included), so those stay inert in a field. `mod` never\n // types a character: Ctrl+S saves from inside a form field in\n // every application there is, and a form field is the only place\n // a save shortcut is ever actually pressed from.\n const isModCombo = combo.split('+').includes('mod');\n if (!isModCombo && isTypingTarget(event.target)) return;\n\n for (const shortcut of this.registry().values()) {\n if (shortcut.keys !== combo) continue;\n if (shortcut.when && !shortcut.when()) continue;\n event.preventDefault();\n shortcut.handler();\n return;\n }\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"elasticias-core.mjs","sources":["../../../../libs/core/src/lib/services/loader.service.ts","../../../../libs/core/src/lib/services/cache.service.ts","../../../../libs/core/src/lib/services/toast.service.ts","../../../../libs/core/src/lib/services/confirm-dialog.service.ts","../../../../libs/core/src/lib/guards/screen.guard.ts","../../../../libs/core/src/lib/preferences/ef-preference-store.ts","../../../../libs/core/src/lib/theme/app-state.ts","../../../../libs/core/src/lib/theme/ef-theme-config.service.ts","../../../../libs/core/src/lib/theme/ef-theme.ts","../../../../libs/core/src/lib/theme/locales/primeng-en.ts","../../../../libs/core/src/lib/theme/locales/primeng-fr.ts","../../../../libs/core/src/lib/theme/locales/primeng-ar.ts","../../../../libs/core/src/lib/modules/ef-module-registry.ts","../../../../libs/core/src/lib/modules/ef-active-module.service.ts","../../../../libs/core/src/lib/responsive/ef-viewport.service.ts","../../../../libs/core/src/lib/auth/ef-permission.service.ts","../../../../libs/core/src/lib/auth/ef-session.token.ts","../../../../libs/core/src/lib/build/ef-build-info.token.ts","../../../../libs/core/src/lib/i18n/ef-versioned-translate-loader.ts","../../../../libs/core/src/lib/shortcuts/shortcut-keys.ts","../../../../libs/core/src/lib/shortcuts/format-shortcut.ts","../../../../libs/core/src/lib/shortcuts/ef-shortcut.service.ts","../../../../libs/core/src/elasticias-core.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\n\n@Injectable({ providedIn: 'root' })\nexport class LoaderService {\n private loadingSubject = new BehaviorSubject<boolean>(false);\n isLoading$ = this.loadingSubject.asObservable();\n\n show(): void {\n this.loadingSubject.next(true);\n }\n\n hide(): void {\n this.loadingSubject.next(false);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { StorageUtils } from '@elasticias/utils';\n\n@Injectable({ providedIn: 'root' })\nexport class CacheService {\n private cache: Record<string, unknown> = {};\n private useLocalStorage = false;\n\n configure(useLocalStorage = false): void {\n this.useLocalStorage = useLocalStorage;\n }\n\n getCache<T>(key: string): T | null {\n return this.useLocalStorage ? StorageUtils.getLocal<T>(key) : (this.cache[key] as T) ?? null;\n }\n\n setCache(key: string, value: unknown): void {\n if (this.useLocalStorage) {\n StorageUtils.setLocal(key, value);\n } else {\n this.cache[key] = value;\n }\n }\n\n updateCache(key: string, newValue: unknown): void {\n if (this.useLocalStorage) {\n const current = StorageUtils.getLocal(key);\n if (current && typeof current === 'object' && typeof newValue === 'object') {\n StorageUtils.setLocal(key, { ...(current as object), ...(newValue as object) });\n } else {\n StorageUtils.setLocal(key, newValue);\n }\n } else {\n const current = this.cache[key];\n if (current && typeof current === 'object' && typeof newValue === 'object') {\n this.cache[key] = { ...(current as object), ...(newValue as object) };\n } else {\n this.cache[key] = newValue;\n }\n }\n }\n\n removeCache(key: string): void {\n if (this.useLocalStorage) {\n StorageUtils.removeLocal(key);\n } else {\n delete this.cache[key];\n }\n }\n\n clearAllCache(): void {\n if (this.useLocalStorage) {\n StorageUtils.clearLocal();\n } else {\n this.cache = {};\n }\n }\n\n hasCache(key: string): boolean {\n return this.useLocalStorage ? StorageUtils.existsLocal(key) : key in this.cache;\n }\n}\n","import { Injectable, Injector, inject, signal } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport { MessageService } from 'primeng/api';\n\n/**\n * Toast severities — mapped 1:1 to the Comptoir status spectrum:\n * `info` → processing, `success` → delivered, `warn` → pending,\n * `error` → cancelled.\n */\nexport type EfToastSeverity = 'info' | 'success' | 'warn' | 'error';\n\n/** Optional inline action button rendered at the end of a toast. */\nexport interface EfToastAction {\n /** Translation key for the button label — preferred. */\n labelKey?: string;\n /** Direct label fallback when `labelKey` is empty. */\n label?: string;\n\n /** Visual tone — `'ghost'` (default) or `'primary'` for the\n * destructive / confirm action. */\n severity?: 'ghost' | 'primary';\n\n /** Click handler. */\n command?: () => void;\n\n /** Auto-close the toast after the click runs (default `true`). */\n dismissOnClick?: boolean;\n}\n\n/**\n * Toast options accepted by `EfToastService.show()`. Either a literal\n * `title` / `text` or their `*Key` translation variants — keys win\n * unless empty.\n */\nexport interface EfToastOptions {\n severity?: EfToastSeverity;\n title?: string;\n titleKey?: string;\n text?: string;\n textKey?: string;\n /** Auto-dismiss in ms; `0` = sticky (no auto-dismiss). */\n life?: number;\n actions?: EfToastAction[];\n}\n\n/** Active toast — instance held in `EfToastService.toasts`. */\nexport interface EfToast {\n id: number;\n severity: EfToastSeverity;\n title: string;\n text: string;\n life: number;\n actions?: EfToastAction[];\n}\n\n/**\n * Comptoir toast service — V2 successor to the legacy `ToastService`.\n *\n * Owns a signal-based queue (`toasts`) consumed by\n * `<ef-toast-region>`, AND forwards every toast to PrimeNG's\n * `MessageService` for back-compat with `<p-toast>` (still used by\n * ClientApp v1). Either renderer picks the toasts up; both work.\n *\n * Default i18n keys (override per-call via `titleKey` / `textKey`):\n * - `ef_toast_info_title`, `ef_toast_info_default`\n * - `ef_toast_success_title`, `ef_toast_success_default`\n * - `ef_toast_warn_title`, `ef_toast_warn_default`\n * - `ef_toast_error_title`, `ef_toast_error_default`\n *\n * Default lifespans: info 5s, success 4s, warn 6s, error 8s.\n */\n@Injectable({ providedIn: 'root' })\nexport class EfToastService {\n private static readonly LIFE_INFO = 5000;\n private static readonly LIFE_SUCCESS = 4000;\n private static readonly LIFE_WARN = 6000;\n private static readonly LIFE_ERROR = 8000;\n\n /**\n * Lazy holders. Resolving TranslateService eagerly at construction\n * time pulls in HttpClient → HTTP_INTERCEPTORS → AuthorizeInterceptor\n * → AuthorizeService → ToastService → cycle. We defer to the first\n * actual translate / message-publish call.\n */\n private readonly injector = inject(Injector);\n private _translate?: TranslateService;\n private _messageService?: MessageService | null;\n private _messageServiceResolved = false;\n\n private nextId = 1;\n\n /** Live queue — `<ef-toast-region>` renders this. */\n readonly toasts = signal<ReadonlyArray<EfToast>>([]);\n\n /* ── Convenience methods (back-compat with the legacy\n ToastService signature: `(message?, title?, life?)`). ── */\n\n showInfo(message?: string, title?: string, life: number = EfToastService.LIFE_INFO): void {\n this.show({\n severity: 'info',\n title: title ?? this.t('ef_toast_info_title'),\n text: message ?? this.t('ef_toast_info_default'),\n life,\n });\n }\n\n showSuccess(message?: string, title?: string, life: number = EfToastService.LIFE_SUCCESS): void {\n this.show({\n severity: 'success',\n title: title ?? this.t('ef_toast_success_title'),\n text: message ?? this.t('ef_toast_success_default'),\n life,\n });\n }\n\n showWarn(message?: string, title?: string, life: number = EfToastService.LIFE_WARN): void {\n this.show({\n severity: 'warn',\n title: title ?? this.t('ef_toast_warn_title'),\n text: message ?? this.t('ef_toast_warn_default'),\n life,\n });\n }\n\n showError(message?: string, title?: string, life: number = EfToastService.LIFE_ERROR): void {\n this.show({\n severity: 'error',\n title: title ?? this.t('ef_toast_error_title'),\n text: message ?? this.t('ef_toast_error_default'),\n life,\n });\n }\n\n /** Generic show — opts can mix `title`/`titleKey`, `text`/`textKey`. */\n show(opts: EfToastOptions): EfToast {\n const severity = opts.severity ?? 'info';\n const toast: EfToast = {\n id: this.nextId++,\n severity,\n title: this.resolve(opts.title, opts.titleKey, this.defaultTitleKey(severity)),\n text: this.resolve(opts.text, opts.textKey, undefined),\n life: opts.life ?? this.defaultLife(severity),\n actions: opts.actions,\n };\n\n // Collapse a burst of identical toasts into one. A dashboard fans\n // out to many independent queries, so one rejected filter used to\n // stack the same message once per widget -- seven copies of \"a\n // validation error occurred\", burying the screen. Only toasts that\n // are still on screen dedupe, so the same message shown again later\n // still appears.\n const duplicate = this.toasts().find(\n t =>\n t.severity === toast.severity &&\n t.title === toast.title &&\n t.text === toast.text,\n );\n if (duplicate) return duplicate;\n\n this.toasts.update(list => [...list, toast]);\n\n // Forward to PrimeNG MessageService so v1's <p-toast> still\n // catches the toast. Sticky in PrimeNG is `life: 0`.\n this.messageService?.add({\n severity: toast.severity,\n summary: toast.title,\n detail: toast.text,\n life: toast.life || undefined,\n sticky: toast.life === 0,\n });\n\n return toast;\n }\n\n private get messageService(): MessageService | null {\n if (!this._messageServiceResolved) {\n this._messageServiceResolved = true;\n this._messageService = this.injector.get(MessageService, null, { optional: true });\n }\n return this._messageService ?? null;\n }\n\n dismiss(id: number): void {\n this.toasts.update(list => list.filter(t => t.id !== id));\n }\n\n clear(): void {\n this.toasts.set([]);\n this.messageService?.clear();\n }\n\n /* (messageService getter is defined just below `show` to keep it\n close to where it's consumed.) */\n\n /* ── Internals ─────────────────────────────────────────────── */\n\n private resolve(\n literal: string | undefined,\n key: string | undefined,\n fallbackKey: string | undefined,\n ): string {\n if (literal != null) return literal;\n if (key) return this.t(key);\n if (fallbackKey) return this.t(fallbackKey);\n return '';\n }\n\n private t(key: string): string {\n // Lazy-resolve TranslateService — see the field comment above\n // for the AuthorizeService cycle this avoids.\n this._translate ??= this.injector.get(TranslateService);\n const value = this._translate.instant(key);\n // `instant()` returns the key when no translation is loaded;\n // fall through to empty string so untranslated toasts don't\n // surface internal keys to end users.\n return value === key ? '' : value;\n }\n\n private defaultLife(severity: EfToastSeverity): number {\n switch (severity) {\n case 'info': return EfToastService.LIFE_INFO;\n case 'success': return EfToastService.LIFE_SUCCESS;\n case 'warn': return EfToastService.LIFE_WARN;\n case 'error': return EfToastService.LIFE_ERROR;\n }\n }\n\n private defaultTitleKey(severity: EfToastSeverity): string {\n return `ef_toast_${severity}_title`;\n }\n}\n\n/**\n * @deprecated Use `EfToastService` — same instance, new name. The\n * alias keeps existing imports compiling during the v1 → V2\n * migration.\n */\nexport { EfToastService as ToastService };\n","import { Injectable, Injector, inject } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport { ConfirmationService } from 'primeng/api';\n\n/** What the user is being asked to approve. Drives the copy, the icon\n * and the weight of the accept button. */\nexport type EfConfirmIntent = 'generic' | 'delete';\n\n/**\n * Options accepted by `ConfirmDialogService.confirm()`.\n *\n * Every piece of text is a translation key, per the framework's i18n\n * convention — the service resolves them through `TranslateService` so\n * the dialog speaks the user's language rather than the author's. The\n * literal `message` / `header` escape hatches exist for text that is\n * already translated (a server message, say); a key always wins.\n */\nexport interface EfConfirmOptions {\n /** Kind of confirmation — `'delete'` supplies destructive defaults. */\n intent?: EfConfirmIntent;\n\n /**\n * Name of the thing being acted on, so the dialog can say *what* it\n * is about to destroy: \"Delete client ANDALOCY PARFUMS?\" rather than\n * \"Delete?\". Omit it and the generic message is used instead.\n */\n name?: string | null;\n\n /** Translation key for the message — preferred over `message`. */\n messageKey?: string;\n /** Already-translated message. Used when `messageKey` is empty. */\n message?: string;\n /** Extra interpolation params for `messageKey` (`name` is added). */\n messageParams?: Record<string, unknown>;\n\n /** Translation key for the dialog title. */\n headerKey?: string;\n /** Already-translated dialog title. */\n header?: string;\n\n /** Translation key for the accept button label. */\n acceptLabelKey?: string;\n /** Translation key for the reject button label. */\n rejectLabelKey?: string;\n\n /** PrimeNG icon class shown in the body tile. */\n icon?: string;\n\n /** Run when the user accepts. */\n accept?: () => void;\n /** Run when the user cancels or dismisses. */\n reject?: () => void;\n\n /** Originating event, so PrimeNG can anchor the dialog. */\n event?: Event;\n}\n\n/** Built-in fallbacks, used only when a translation is missing, so a\n * consuming app that has not yet added the keys still gets a readable\n * dialog instead of a raw key (or worse, an empty message under an\n * irreversible action). */\nconst FALLBACKS: Record<string, string> = {\n ef_confirm_header: 'Confirmation',\n ef_confirm_message_generic: 'Are you sure you want to continue?',\n ef_confirm_accept: 'Confirm',\n ef_confirm_cancel: 'Cancel',\n ef_confirm_delete_header: 'Confirm deletion',\n ef_confirm_delete_accept: 'Delete',\n ef_confirm_delete_message: 'Are you sure you want to delete \"{{name}}\"? This action cannot be undone.',\n ef_confirm_delete_message_generic: 'Are you sure you want to delete this item? This action cannot be undone.',\n};\n\n/** Per-intent defaults. `confirm()` merges the caller's options over these. */\nconst INTENT_DEFAULTS: Record<EfConfirmIntent, Required<Pick<EfConfirmOptions,\n 'headerKey' | 'acceptLabelKey' | 'rejectLabelKey' | 'icon'>> & { messageKey: string; namedMessageKey?: string }> = {\n generic: {\n headerKey: 'ef_confirm_header',\n acceptLabelKey: 'ef_confirm_accept',\n rejectLabelKey: 'ef_confirm_cancel',\n icon: 'pi pi-exclamation-triangle',\n messageKey: 'ef_confirm_message_generic',\n },\n delete: {\n headerKey: 'ef_confirm_delete_header',\n acceptLabelKey: 'ef_confirm_delete_accept',\n rejectLabelKey: 'ef_confirm_cancel',\n icon: 'pi pi-exclamation-triangle',\n messageKey: 'ef_confirm_delete_message_generic',\n namedMessageKey: 'ef_confirm_delete_message',\n },\n};\n\n/**\n * The app-wide confirmation modal, driven through PrimeNG's\n * `ConfirmationService` and rendered by `<ef-confirm-dialog>`.\n *\n * Two call shapes:\n *\n * ```ts\n * // Options — the one to reach for.\n * confirmDialogService.confirm({\n * intent: 'delete',\n * name: client.name, // \"Delete ANDALOCY PARFUMS?\"\n * accept: () => this.remove(),\n * });\n *\n * // Legacy positional form, kept so existing callers keep compiling.\n * confirmDialogService.confirm('Already-translated question?', onYes, onNo);\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class ConfirmDialogService {\n private readonly confirmationService = inject(ConfirmationService);\n\n /**\n * Lazy holder. Resolving `TranslateService` at construction time pulls\n * in HttpClient and, through the interceptor chain, services that\n * inject this one — the same cycle `EfToastService` documents. Defer\n * to the first actual `confirm()` call, which is always well after\n * bootstrap.\n */\n private readonly injector = inject(Injector);\n private _translate?: TranslateService;\n\n confirm(options: EfConfirmOptions): void;\n /** @deprecated Pass `EfConfirmOptions` — a literal message cannot be translated. */\n confirm(message: string, acceptCallback?: () => void, rejectCallback?: () => void, event?: Event): void;\n confirm(\n messageOrOptions: string | EfConfirmOptions,\n acceptCallback?: () => void,\n rejectCallback?: () => void,\n event?: Event,\n ): void {\n const options: EfConfirmOptions =\n typeof messageOrOptions === 'string'\n ? { message: messageOrOptions, accept: acceptCallback, reject: rejectCallback, event }\n : messageOrOptions;\n\n const defaults = INTENT_DEFAULTS[options.intent ?? 'generic'];\n const name = options.name?.toString().trim() || undefined;\n\n this.confirmationService.confirm({\n target: options.event?.target ?? undefined,\n message: this.resolveMessage(options, defaults, name),\n header: options.header ?? this.t(options.headerKey ?? defaults.headerKey),\n closable: true,\n closeOnEscape: true,\n icon: options.icon ?? defaults.icon,\n rejectButtonProps: {\n label: this.t(options.rejectLabelKey ?? defaults.rejectLabelKey),\n severity: 'secondary',\n outlined: true,\n },\n acceptButtonProps: {\n label: this.t(options.acceptLabelKey ?? defaults.acceptLabelKey),\n // Semantics. The visual weight comes from the style class\n // below, because `.es-confirm .p-confirmdialog-accept-button`\n // in `_patterns.scss` paints the button at a specificity a\n // severity class cannot reach.\n severity: options.intent === 'delete' ? 'danger' : undefined,\n },\n // `.btn.btn-danger` is declared after the `.es-confirm` accept\n // rule at equal specificity, so it is what finally colours a\n // destructive confirm red instead of ordinary primary ink.\n acceptButtonStyleClass: options.intent === 'delete' ? 'btn btn-danger' : undefined,\n accept: () => options.accept?.(),\n reject: () => options.reject?.(),\n });\n }\n\n /**\n * Sugar for `confirm({ intent: 'delete', ... })`.\n *\n * ```ts\n * confirmDialogService.confirmDelete({ name: row.label, accept: () => … });\n * ```\n */\n confirmDelete(options: Omit<EfConfirmOptions, 'intent'> = {}): void {\n this.confirm({ ...options, intent: 'delete' });\n }\n\n /* ── Internals ─────────────────────────────────────────────── */\n\n private resolveMessage(\n options: EfConfirmOptions,\n defaults: (typeof INTENT_DEFAULTS)[EfConfirmIntent],\n name: string | undefined,\n ): string {\n if (options.messageKey) {\n return this.t(options.messageKey, { ...options.messageParams, name: escapeHtml(name ?? '') });\n }\n if (options.message != null) return options.message;\n\n // A named message when we know what is being acted on, the generic\n // one otherwise — so a caller with no name still reads correctly.\n const key = name && defaults.namedMessageKey ? defaults.namedMessageKey : defaults.messageKey;\n return this.t(key, { ...options.messageParams, name: escapeHtml(name ?? '') });\n }\n\n private t(key: string, params?: Record<string, unknown>): string {\n this._translate ??= this.injector.get(TranslateService);\n const value = this._translate.instant(key, params);\n // `instant()` hands back the key when nothing is loaded for it.\n // Never show that to a user who is about to destroy something.\n if (value !== key) return value;\n const fallback = FALLBACKS[key];\n return fallback ? interpolate(fallback, params) : '';\n }\n}\n\n/**\n * PrimeNG renders the confirm message through `[innerHTML]`. Angular\n * sanitizes it, so this is not about script execution — it is about an\n * entity name containing `<`, `>` or `&` rendering as markup or being\n * silently swallowed. \"Renault < Dacia\" must read as itself.\n */\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n/** Minimal `{{param}}` substitution for the built-in fallbacks, which\n * never reach ngx-translate's own interpolator. */\nfunction interpolate(template: string, params?: Record<string, unknown>): string {\n if (!params) return template;\n return template.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (match: string, key: string) =>\n params[key] == null ? match : String(params[key]),\n );\n}\n","import { inject } from '@angular/core';\nimport { CanActivateFn, ActivatedRouteSnapshot, Router } from '@angular/router';\nimport { StorageUtils } from '@elasticias/utils';\nimport { Permissions } from '@elasticias/types';\n\n/**\n * Configuration for the screen guard factory.\n */\nexport interface ScreenGuardConfig {\n /** Storage key where screen grants are stored (default: 'CURRENT_USER_GRANTS') */\n grantsStorageKey?: string;\n /** Route to redirect to when access is denied (default: '/') */\n deniedRedirect?: string;\n /** Minimum required permission to access the screen (default: Permissions.Read) */\n requiredPermission?: Permissions;\n /** Storage type to read grants from (default: 'session') */\n storageType?: 'local' | 'session';\n}\n\n/**\n * Creates a reusable Angular route guard that checks screen-level permissions.\n *\n * Usage in route definitions:\n * ```typescript\n * {\n * path: 'countries',\n * data: { screenCode: 'Countries' },\n * canActivate: [screenGuard()],\n * children: [\n * { path: '', component: CountriesComponent },\n * { path: 'details/:id', component: CountriesDetailsComponent },\n * ]\n * }\n * ```\n *\n * The guard reads the `screenCode` from route data (traversing parent routes)\n * and checks if the current user has at least the required permission (default: Read).\n */\nexport function screenGuard(config?: ScreenGuardConfig): CanActivateFn {\n return (route: ActivatedRouteSnapshot) => {\n const router = inject(Router);\n const grantsKey = config?.grantsStorageKey ?? 'CURRENT_USER_GRANTS';\n const deniedRedirect = config?.deniedRedirect ?? '/';\n const requiredPermission = config?.requiredPermission ?? Permissions.Read;\n const storageType = config?.storageType ?? 'local';\n\n const screenCode = getScreenCode(route);\n\n // If no screenCode found on this route or any parent, allow access\n if (!screenCode) {\n return true;\n }\n\n const screenGrants = storageType === 'session'\n ? StorageUtils.getSession<Record<string, { permissions?: string[] }>>(grantsKey)\n : StorageUtils.getLocal<Record<string, { permissions?: string[] }>>(grantsKey);\n\n if (!screenGrants) {\n router.navigate([deniedRedirect]);\n return false;\n }\n\n const grant = screenGrants[screenCode];\n if (!grant?.permissions?.includes(requiredPermission)) {\n router.navigate([deniedRedirect]);\n return false;\n }\n\n return true;\n };\n}\n\n/**\n * Walks up the route tree to find the nearest screenCode in route data.\n */\nfunction getScreenCode(route: ActivatedRouteSnapshot): string | undefined {\n let current: ActivatedRouteSnapshot | null = route;\n while (current) {\n const code = current.data?.['screenCode'] as string | undefined;\n if (code) return code;\n current = current.parent;\n }\n return undefined;\n}\n\n/**\n * Utility function to check if the current user has a specific permission on a screen.\n * Can be used in components/services outside of route guards.\n */\nexport function hasScreenPermission(\n screenCode: string,\n permission: Permissions,\n grantsStorageKey = 'CURRENT_USER_GRANTS',\n storageType: 'local' | 'session' = 'local'\n): boolean {\n const screenGrants = storageType === 'session'\n ? StorageUtils.getSession<Record<string, { permissions?: string[] }>>(grantsStorageKey)\n : StorageUtils.getLocal<Record<string, { permissions?: string[] }>>(grantsStorageKey);\n if (!screenGrants) return false;\n\n const grant = screenGrants[screenCode];\n return grant?.permissions?.includes(permission) ?? false;\n}\n","import { InjectionToken } from '@angular/core';\nimport type { Observable } from 'rxjs';\nimport { StorageUtils } from '@elasticias/utils';\n\n/**\n * Where the shell, the theme and data tables keep a viewer's UI preferences\n * (theme state, side-panel fold, table density and hidden columns).\n *\n * The synchronous contract is deliberate: these preferences are read while a\n * component is being built, so the first paint is right. An app that keeps\n * them on a server therefore serves reads from a local cache that it\n * hydrates itself, and sends writes upstream in the background.\n *\n * Keys are the full storage keys, exactly as they are in localStorage today\n * (see {@link efPrefKey} and {@link EF_SIDE_COLLAPSED_KEY}); values are the\n * raw strings stored under them.\n */\nexport interface EfPreferenceStore {\n /** The stored value, or null when absent or storage is unavailable. */\n get(key: string): string | null;\n /**\n * Consumers may call this with a value the store already holds, and a\n * store that keeps partial values (the theme's AppState) will not match\n * it byte for byte. Server-backed stores should ignore no-op sets\n * (compare the parsed or merged result) rather than issue a request.\n */\n set(key: string, value: string): void;\n remove(key: string): void;\n /**\n * Optional. Emits a key whose value was changed from outside the\n * consumers (for example a server hydrate after sign in), so a consumer\n * that is already alive can re-read it. Must NOT emit for the store's own\n * `set` / `remove` calls. The theme and the app shell follow it (a removed\n * key resets them to defaults; the theme value may be a partial AppState,\n * merged over the live one). ef-data-card reads its key only when it is\n * constructed and ignores it.\n */\n readonly changes?: Observable<string>;\n}\n\n/** localStorage key of the app-shell side-panel fold ('1' collapsed, '0' open). Not prefixed. */\nexport const EF_SIDE_COLLAPSED_KEY = 'ef.shell.side-collapsed';\n\n/** Key for a preference that StorageUtils has always stored under its prefix (`Elasticias_` by default). */\nexport function efPrefKey(name: string): string {\n return `${StorageUtils.prefix}${name}`;\n}\n\n/** Prefix of the per-table key family: `efTablePrefsKey(tableKey)` is the full key. */\nexport const EF_TABLE_PREFS_PREFIX = 'TABLE_PREFS_';\n\n/** Full key of one table's density / hidden-columns preference (`Elasticias_TABLE_PREFS_<tableKey>`). */\nexport function efTablePrefsKey(tableKey: string): string {\n return efPrefKey(`${EF_TABLE_PREFS_PREFIX}${tableKey}`);\n}\n\n/** localStorage, never throwing: a private window or blocked site data just means nothing is remembered. */\nexport class LocalStoragePreferenceStore implements EfPreferenceStore {\n get(key: string): string | null {\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n }\n\n set(key: string, value: string): void {\n try {\n localStorage.setItem(key, value);\n } catch {\n /* the preference holds for this visit only */\n }\n }\n\n remove(key: string): void {\n try {\n localStorage.removeItem(key);\n } catch {\n /* nothing to remove from */\n }\n }\n}\n\n/**\n * Preference store. Defaults to localStorage with the historical keys, so\n * nothing changes unless an app provides its own:\n * `{ provide: EF_PREFERENCE_STORE, useClass: ServerPreferenceStore }`.\n */\nexport const EF_PREFERENCE_STORE = new InjectionToken<EfPreferenceStore>('EF_PREFERENCE_STORE', {\n providedIn: 'root',\n factory: () => new LocalStoragePreferenceStore(),\n});\n","export interface AppState {\n preset?: string;\n primary?: string;\n surface?: string;\n darkTheme?: boolean;\n menuActive?: boolean;\n mobileMenuVisible?: boolean;\n designerKey?: string;\n RTL?: boolean;\n}\n\nexport const DEFAULT_APP_STATE: AppState = {\n preset: 'Lara',\n primary: 'noir',\n surface: null as any,\n darkTheme: false,\n menuActive: true,\n mobileMenuVisible: false,\n designerKey: 'primeng-designer-theme',\n RTL: false\n};\n","import { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { computed, DestroyRef, effect, inject, Injectable, PLATFORM_ID, signal } from '@angular/core';\nimport { palette, updatePrimaryPalette } from '@primeng/themes';\nimport { EF_PREFERENCE_STORE, efPrefKey } from '../preferences/ef-preference-store';\nimport { AppState, DEFAULT_APP_STATE } from './app-state';\n\n/**\n * Service that manages theme state: preset, primary color, surface, dark mode, RTL.\n * State is persisted to localStorage so user preferences survive page reloads.\n *\n * Apps can extend this service or use it directly.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class EfThemeConfigService {\n private readonly STORAGE_NAME = 'APP_CONFIG_STATE';\n\n private readonly prefs = inject(EF_PREFERENCE_STORE);\n\n /** Serialized state last adopted from the store; saving it back would only echo. */\n private fromStore: string | null = null;\n\n appState = signal<AppState>(null as any);\n\n designerActive = signal(false);\n\n newsActive = signal(false);\n\n document = inject(DOCUMENT);\n\n platformId = inject(PLATFORM_ID);\n\n theme = computed(() => (this.appState()?.darkTheme ? 'dark' : 'light'));\n\n transitionComplete = signal<boolean>(false);\n\n constructor() {\n const initialState = this.loadAppState();\n this.appState.set({ ...initialState });\n\n // Apply preset class + RTL synchronously so the first paint has\n // the right theme — the effect below picks up subsequent changes\n // (including any subclass `appState.update()` issued before its\n // first run).\n this.updatePresetClass(initialState);\n if (isPlatformBrowser(this.platformId) && initialState?.RTL) {\n this.document.documentElement.setAttribute('dir', 'rtl');\n }\n\n // A store that hydrates after sign in announces it. The stored value\n // may be a PARTIAL AppState (a server only knows some fields), so it\n // is merged over the live state; a removed key resets to defaults.\n // Either way the result is not written back: it came from the store.\n const sub = this.prefs.changes?.subscribe((key) => {\n if (key !== efPrefKey(this.STORAGE_NAME)) return;\n const stored = this.readStoredState();\n const next: AppState = stored\n ? { ...this.appState(), ...stored }\n : { ...DEFAULT_APP_STATE };\n if (JSON.stringify(next) === JSON.stringify(this.appState())) return;\n this.fromStore = JSON.stringify(next);\n this.appState.set(next);\n });\n inject(DestroyRef).onDestroy(() => sub?.unsubscribe());\n\n effect(() => {\n const state = this.appState();\n if (!state) return;\n this.saveAppState(state);\n this.updatePresetClass(state);\n this.handleDarkModeTransition(state);\n this.applyRTL(state);\n });\n }\n\n private static readonly PRESET_CLASS_MAP: Record<string, string> = {\n Aura: 'theme-compact',\n Lara: 'theme-modern',\n Material: 'theme-material',\n Nora: 'theme-classic',\n Comptoir: 'theme-comptoir',\n };\n\n private static readonly TENANT_RAMP_STOPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900] as const;\n\n private static readonly ALL_THEME_CLASSES = Object.values(EfThemeConfigService.PRESET_CLASS_MAP);\n\n private updatePresetClass(state: AppState): void {\n if (isPlatformBrowser(this.platformId)) {\n const body = this.document.body;\n body.classList.remove(...EfThemeConfigService.ALL_THEME_CLASSES);\n if (state.preset) {\n const cls = EfThemeConfigService.PRESET_CLASS_MAP[state.preset];\n if (cls) {\n body.classList.add(cls);\n }\n }\n }\n }\n\n private handleDarkModeTransition(state: AppState): void {\n if (isPlatformBrowser(this.platformId)) {\n if ((document as any).startViewTransition) {\n this.startViewTransition(state);\n } else {\n this.toggleDarkMode(state);\n this.onTransitionEnd();\n }\n }\n }\n\n private startViewTransition(state: AppState): void {\n const transition = (document as any).startViewTransition(() => {\n this.toggleDarkMode(state);\n });\n\n transition.ready\n .then(() => this.onTransitionEnd())\n .catch(() => { /* view transition aborted */ });\n }\n\n private toggleDarkMode(state: AppState): void {\n if (state.darkTheme) {\n this.document.documentElement.classList.add('p-dark');\n } else {\n this.document.documentElement.classList.remove('p-dark');\n }\n }\n\n private onTransitionEnd() {\n this.transitionComplete.set(true);\n setTimeout(() => {\n this.transitionComplete.set(false);\n });\n }\n\n private applyRTL(state: AppState): void {\n if (isPlatformBrowser(this.platformId)) {\n const setDir = () => {\n if (state.RTL) {\n this.document.documentElement.setAttribute('dir', 'rtl');\n } else {\n this.document.documentElement.removeAttribute('dir');\n }\n };\n\n if ((document as any).startViewTransition) {\n const t = (document as any).startViewTransition(() => setDir());\n t.ready.catch(() => { /* view transition aborted */ });\n } else {\n setDir();\n }\n }\n }\n\n hideMenu() {\n this.appState.update((state) => ({ ...state, menuActive: false }));\n }\n\n showMenu() {\n this.appState.update((state) => ({ ...state, menuActive: true }));\n }\n\n toggleMobileMenu() {\n this.appState.update((state) => ({\n ...state,\n mobileMenuVisible: !state.mobileMenuVisible\n }));\n }\n\n closeMobileMenu() {\n this.appState.update((state) => ({\n ...state,\n mobileMenuVisible: false\n }));\n }\n\n openMobileMenu() {\n this.appState.update((state) => ({\n ...state,\n mobileMenuVisible: true\n }));\n }\n\n hideNews() {\n this.newsActive.set(false);\n }\n\n showNews() {\n this.newsActive.set(true);\n }\n\n showDesigner() {\n this.designerActive.set(true);\n }\n\n hideDesigner() {\n this.designerActive.set(false);\n }\n\n private loadAppState(): AppState {\n if (isPlatformBrowser(this.platformId)) {\n const storedState = this.readStoredState();\n if (storedState) {\n return storedState;\n }\n }\n return { ...DEFAULT_APP_STATE };\n }\n\n private readStoredState(): AppState | null {\n const raw = this.prefs.get(efPrefKey(this.STORAGE_NAME));\n if (!raw) return null;\n try {\n return JSON.parse(raw) as AppState;\n } catch {\n return null;\n }\n }\n\n private saveAppState(state: AppState): void {\n if (isPlatformBrowser(this.platformId)) {\n const key = efPrefKey(this.STORAGE_NAME);\n const serialized = JSON.stringify(state);\n // One-shot: only the effect run caused by the adopt is an echo.\n const echo = serialized === this.fromStore;\n this.fromStore = null;\n if (echo || serialized === this.prefs.get(key)) return;\n this.prefs.set(key, serialized);\n }\n }\n\n /**\n * Applies a tenant's brand color across both PrimeNG's primary palette\n * and the Comptoir `--tenant-*` CSS variables.\n *\n * Generates a 50–950 ramp from the input hex via PrimeNG's `palette()`\n * helper, hands the full ramp to `updatePrimaryPalette()`, and writes\n * stops 50–900 onto `documentElement.style` so the SCSS layer's\n * `var(--tenant-*)` references resolve to the tenant's color.\n *\n * Call this whenever the active tenant changes (e.g., from an effect\n * watching `tenantService.storeConfig().primaryColor`).\n */\n setTenantAccent(hex: string): void {\n if (!hex) return;\n\n const ramp = palette(hex) as Record<string, string>;\n if (!ramp) return;\n\n updatePrimaryPalette(ramp);\n\n if (isPlatformBrowser(this.platformId)) {\n const root = this.document.documentElement;\n for (const stop of EfThemeConfigService.TENANT_RAMP_STOPS) {\n const value = ramp[String(stop)];\n if (value) {\n root.style.setProperty(`--tenant-${stop}`, value);\n }\n }\n }\n }\n}\n","import { definePreset } from '@primeng/themes';\nimport Aura from '@primeng/themes/aura';\nimport Lara from '@primeng/themes/lara';\n\n/* ──────────────────────────────────────────────────────────────────\n * LEGACY: Noir preset (Aura base, monochrome surface palette).\n * Kept for backward-compat with apps that haven't migrated to\n * Comptoir. Phase 5 of the design-system plan retrofits consumers\n * to EfComptoirTheme; once that lands, Noir + EfTheme can be\n * deleted.\n * ────────────────────────────────────────────────────────────── */\n\nconst Noir = definePreset(Aura, {\n semantic: {\n primary: {\n 50: '{surface.50}',\n 100: '{surface.100}',\n 200: '{surface.200}',\n 300: '{surface.300}',\n 400: '{surface.400}',\n 500: '{surface.500}',\n 600: '{surface.600}',\n 700: '{surface.700}',\n 800: '{surface.800}',\n 900: '{surface.900}',\n 950: '{surface.950}'\n },\n colorScheme: {\n light: {\n primary: {\n color: '{primary.950}',\n contrastColor: '#ffffff',\n hoverColor: '{primary.800}',\n activeColor: '{primary.700}'\n },\n highlight: {\n background: '{primary.950}',\n focusBackground: '{primary.700}',\n color: '#ffffff',\n focusColor: '#ffffff'\n }\n },\n dark: {\n primary: {\n color: '{primary.50}',\n contrastColor: '{primary.950}',\n hoverColor: '{primary.200}',\n activeColor: '{primary.300}'\n },\n highlight: {\n background: '{primary.50}',\n focusBackground: '{primary.300}',\n color: '{primary.950}',\n focusColor: '{primary.950}'\n }\n }\n }\n }\n});\n\n/**\n * Default Elasticias theme configuration for PrimeNG.\n * Uses the Noir preset (surface-based primary colors) with dark mode support.\n *\n * @deprecated Migrate to {@link EfComptoirTheme} as part of Phase 5 of the\n * design-system plan. Will be removed once all consumers have moved.\n */\nexport const EfTheme = {\n preset: Noir,\n options: {\n darkModeSelector: '.p-dark',\n }\n};\n\nexport default EfTheme;\n\n/* ──────────────────────────────────────────────────────────────────\n * COMPTOIR: ink surface + tenant primary (Lara base).\n * Surface palette is the ink ramp from libs/tokens/colors.json.\n * Primary palette defaults to the parfumerie sample tenant; it is\n * runtime-replaced by EfThemeConfigService.setTenantAccent(hex)\n * via PrimeNG's updatePrimaryPalette() API.\n * ────────────────────────────────────────────────────────────── */\n\nconst ComptoirPreset = definePreset(Lara, {\n semantic: {\n primary: {\n 50: '#f7f0f4',\n 100: '#ecdce5',\n 200: '#d8b4c5',\n 300: '#b87a99',\n 400: '#934e74',\n 500: '#6f3257',\n 600: '#54243f',\n 700: '#401a30',\n 800: '#2c1221',\n 900: '#1a0913',\n 950: '#0d040a'\n },\n /* ──────────────────────────────────────────────────────────────\n * Control sizing (ADR-009). The native \"comptoir\" variant is the\n * default render path and is pinned to --hit-base (40px) in CSS;\n * these tokens align the OPT-IN PrimeNG variant (p-select filter,\n * p-multiselect, p-inputnumber stepper, etc.) to the same canonical\n * heights so the two paths agree:\n * base → 40px (--hit-base) sm → 32px (--hit) lg → 48px (--hit-touch, POS/mobile)\n * Lara form-field height ≈ paddingY*2 + lineHeight(1.5)*fontSize(14px) + 2px border.\n * base: 8px*2 + 21 + 2 ≈ 40px · sm: 5px*2 + ~18 + 2 ≈ 32px · lg: 12px*2 + 21 + 2 ≈ 48px\n * NOTE: exact pixel height depends on the app's root font-size; the\n * native default path is the verified one — confirm the PrimeNG\n * opt-in controls visually in the running app and nudge paddingY if\n * they read 1-2px off. Border radius matches --r-md (12px). */\n formField: {\n paddingX: '0.75rem',\n paddingY: '0.5rem',\n borderRadius: '12px',\n sm: {\n fontSize: '0.78rem',\n paddingX: '0.625rem',\n paddingY: '0.3125rem'\n },\n lg: {\n fontSize: '0.9375rem',\n paddingX: '0.875rem',\n paddingY: '0.75rem'\n }\n },\n colorScheme: {\n light: {\n primary: {\n color: '{primary.500}',\n contrastColor: '#ffffff',\n hoverColor: '{primary.600}',\n activeColor: '{primary.700}'\n },\n surface: {\n 0: '#ffffff',\n 50: '#f8f9fb',\n 100: '#f1f3f6',\n 200: '#e4e8ee',\n 300: '#cdd3dd',\n 400: '#9ca5b3',\n 500: '#6c7280',\n 600: '#4a4f5a',\n 700: '#2f3239',\n 800: '#1d1f24',\n 900: '#0f1115',\n 950: '#06070a'\n },\n highlight: {\n background: '{primary.500}',\n focusBackground: '{primary.600}',\n color: '#ffffff',\n focusColor: '#ffffff'\n }\n },\n dark: {\n primary: {\n color: '{primary.400}',\n contrastColor: '{primary.950}',\n hoverColor: '{primary.300}',\n activeColor: '{primary.200}'\n },\n /* The ramp runs in the SAME direction as the light one, and\n * that is deliberate — it used to be inverted here (0 = black\n * … 950 = near-white) and that single flip was the cause of\n * dark mode being unreadable product-wide.\n *\n * PrimeNG's surface ramp is not \"light values for light mode,\n * dark values for dark mode\". It is a fixed light→dark scale\n * that the *semantic* block indexes differently per scheme:\n * light reads `{surface.0}` as the page and `{surface.700}` as\n * body text, dark reads `{surface.900}` as the page and\n * `{surface.0}` as body text. Every component preset inherits\n * those conventions. Inverting the ramp therefore inverted\n * every inherited value at once — dark `text.color` resolved\n * to #000000, `content.background` to #f1f3f6, and\n * `button.text.secondary.color` to #2f3239 on a #1d1f24 card\n * (1.28:1, the reported bug).\n *\n * Keeping the ramp upright makes the ink scale land exactly on\n * the Comptoir dark aliases from `_comptoir.scss`:\n * surface.900 → --paper (#0f1115)\n * surface.800 → --paper-alt (#1d1f24)\n * surface.400 → --text-mute (#9ca5b3)\n * surface.50 → --text (#f8f9fb)\n * so inherited PrimeNG values agree with the design system\n * instead of fighting it. */\n surface: {\n 0: '#ffffff',\n 50: '#f8f9fb',\n 100: '#f1f3f6',\n 200: '#e4e8ee',\n 300: '#cdd3dd',\n 400: '#9ca5b3',\n 500: '#6c7280',\n 600: '#4a4f5a',\n 700: '#2f3239',\n 800: '#1d1f24',\n 900: '#0f1115',\n 950: '#06070a'\n },\n /* Lara's dark body text is `{surface.0}` = pure white; Comptoir's\n * --text is --ink-50. Pin it so the two agree. 17.94:1 on\n * --paper, 15.65:1 on --paper-alt. */\n text: {\n color: '{surface.50}',\n hoverColor: '{surface.50}'\n },\n highlight: {\n background: '{primary.400}',\n focusBackground: '{primary.300}',\n color: '{primary.950}',\n focusColor: '{primary.950}'\n }\n }\n }\n },\n /* ──────────────────────────────────────────────────────────────\n * Button: the low-emphasis variants.\n *\n * An upright surface ramp (above) fixes everything Lara expresses\n * through `{surface.N}`. It cannot fix the variants Lara expresses\n * through the accent and through raw Tailwind reds, because those\n * were tuned against Lara's own indigo/zinc, not against the\n * Comptoir tenant ramp. Measured on the default parfumerie accent,\n * against --paper (#0f1115) / --paper-alt (#1d1f24) in dark and\n * #ffffff / --paper (#f8f9fb) in light, resting state:\n *\n * dark text.primary {primary.400} #934e74 → 3.22 / 2.81 ✗\n * dark outlined.primary.border {primary.700} #401a30 → 1.27 / 1.11 ✗\n * dark outlined.secondary.border {surface.700} → 1.47 / 1.28 ✗\n * dark outlined.danger.border {red.700} → 2.92 / 2.55 ✗\n * light text.danger {red.500} #ef4444 → 3.76 / 3.57 ✗\n * light outlined.primary.border {primary.200} → 1.87 / 1.77 ✗\n * light outlined.secondary.border {surface.200} → 1.19 / 1.13 ✗\n *\n * Text colours below clear 4.5:1 in every state (resting, hover\n * tint and the 16% active tint); border colours clear the 3:1\n * WCAG 1.4.11 bar for a component boundary without brightening\n * into something that reads as a fill.\n *\n * The severities Comptoir actually ships on `<ef-button>` are\n * primary / secondary / danger; success, info, warn, help and\n * contrast are left on stock, which the upright ramp already\n * makes legible.\n *\n * Caveat: `{primary.N}` tracks the tenant accent through\n * `EfThemeConfigService.setTenantAccent()`, so these ratios hold\n * for the default ramp. A very dark or very light tenant accent\n * would need a lightness clamp in the ramp generator — noted, not\n * built. */\n components: {\n button: {\n colorScheme: {\n light: {\n text: {\n /* {primary.color} (= {primary.500}) already reads\n * 9.25 / 8.78 — left on stock so it keeps tracking\n * the tenant accent. */\n danger: { color: '{red.700}' } /* 6.47 / 6.14 */\n },\n outlined: {\n primary: { borderColor: '{primary.300}' }, /* 3.34 / 3.17 */\n secondary: { color: '{surface.600}', borderColor: '{surface.500}' }, /* 8.21 / 7.80 · border 4.82 / 4.58 */\n danger: { color: '{red.700}', borderColor: '{red.500}' } /* 6.47 / 6.14 · border 3.76 / 3.57 */\n }\n },\n dark: {\n text: {\n primary: { color: '{primary.200}' }, /* 10.13 / 8.84 */\n secondary: { color: '{surface.300}' }, /* 12.56 / 10.96 — the reported 1.28 pair */\n danger: { color: '{red.400}' } /* 6.83 / 5.96 */\n },\n outlined: {\n primary: { color: '{primary.200}', borderColor: '{primary.300}' }, /* 10.13 / 8.84 · border 5.65 / 4.93 */\n secondary: { color: '{surface.300}', borderColor: '{surface.500}' }, /* 12.56 / 10.96 · border 3.92 / 3.42 */\n danger: { color: '{red.400}', borderColor: '{red.500}' } /* 6.83 / 5.96 · border 5.02 / 4.38 */\n },\n /* `[link]=\"true\"` carries no ground of its own, so it sits\n * straight on --paper / --paper-alt: {primary.color} reads\n * 3.22 / 2.81 there. Same lift as the text variant. */\n link: {\n color: '{primary.200}', /* 10.13 / 8.84 */\n hoverColor: '{primary.100}',\n activeColor: '{primary.100}'\n }\n }\n }\n }\n }\n});\n\n/**\n * Comptoir theme configuration for PrimeNG (Phase 1 / design-system v0.2).\n * Surface palette = ink ramp; primary palette = tenant accent\n * (runtime-driven via `EfThemeConfigService.setTenantAccent(hex)`).\n *\n * Usage with providePrimeNG:\n * ```ts\n * providePrimeNG({ theme: EfComptoirTheme, ripple: true })\n * ```\n *\n * Pair with `state.preset = 'Comptoir'` so the body class becomes\n * `theme-comptoir` (avoids legacy `theme-modern` radius overrides).\n */\nexport const EfComptoirTheme = {\n preset: ComptoirPreset,\n options: {\n darkModeSelector: '.p-dark',\n }\n};\n","import { Translation } from 'primeng/api';\n\n/**\n * English locale for PrimeNG components.\n *\n * Usage:\n * ```ts\n * import { PRIMENG_EN_LOCALE } from '@elasticias/core';\n * this.primeng.translation = PRIMENG_EN_LOCALE;\n * ```\n */\nexport const PRIMENG_EN_LOCALE: Translation = {\n startsWith: 'Starts with',\n contains: 'Contains',\n notContains: 'Not contains',\n endsWith: 'Ends with',\n equals: 'Equals',\n notEquals: 'Not equals',\n noFilter: 'No Filter',\n lt: 'Less than',\n lte: 'Less than or equal to',\n gt: 'Greater than',\n gte: 'Greater than or equal to',\n dateIs: 'Date is',\n dateIsNot: 'Date is not',\n dateBefore: 'Date is before',\n dateAfter: 'Date is after',\n clear: 'Clear',\n apply: 'Apply',\n matchAll: 'Match All',\n matchAny: 'Match Any',\n addRule: 'Add Rule',\n removeRule: 'Remove Rule',\n accept: 'Yes',\n reject: 'No',\n choose: 'Choose',\n upload: 'Upload',\n cancel: 'Cancel',\n completed: 'Completed',\n pending: 'Pending',\n fileSizeTypes: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],\n dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],\n dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],\n dayNamesMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],\n monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],\n monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n chooseYear: 'Choose Year',\n chooseMonth: 'Choose Month',\n chooseDate: 'Choose Date',\n prevDecade: 'Previous Decade',\n nextDecade: 'Next Decade',\n prevYear: 'Previous Year',\n nextYear: 'Next Year',\n prevMonth: 'Previous Month',\n nextMonth: 'Next Month',\n prevHour: 'Previous Hour',\n nextHour: 'Next Hour',\n prevMinute: 'Previous Minute',\n nextMinute: 'Next Minute',\n prevSecond: 'Previous Second',\n nextSecond: 'Next Second',\n am: 'AM',\n pm: 'PM',\n today: 'Today',\n weekHeader: 'Wk',\n firstDayOfWeek: 0,\n showMonthAfterYear: false,\n dateFormat: 'mm/dd/yy',\n weak: 'Weak',\n medium: 'Medium',\n strong: 'Strong',\n passwordPrompt: 'Enter a password',\n emptyFilterMessage: 'No results found',\n searchMessage: '{0} results are available',\n selectionMessage: '{0} items selected',\n emptySelectionMessage: 'No selected item',\n emptySearchMessage: 'No results found',\n emptyMessage: 'No available options',\n aria: {\n trueLabel: 'True',\n falseLabel: 'False',\n nullLabel: 'Not Selected',\n star: '1 star',\n stars: '{star} stars',\n selectAll: 'All items selected',\n unselectAll: 'All items unselected',\n close: 'Close',\n previous: 'Previous',\n next: 'Next',\n navigation: 'Navigation',\n scrollTop: 'Scroll Top',\n moveTop: 'Move Top',\n moveUp: 'Move Up',\n moveDown: 'Move Down',\n moveBottom: 'Move Bottom',\n moveToTarget: 'Move to Target',\n moveToSource: 'Move to Source',\n moveAllToTarget: 'Move All to Target',\n moveAllToSource: 'Move All to Source',\n pageLabel: 'Page {page}',\n firstPageLabel: 'First Page',\n lastPageLabel: 'Last Page',\n nextPageLabel: 'Next Page',\n prevPageLabel: 'Previous Page',\n rowsPerPageLabel: 'Rows per page',\n jumpToPageDropdownLabel: 'Jump to Page Dropdown',\n jumpToPageInputLabel: 'Jump to Page Input',\n selectRow: 'Row Selected',\n unselectRow: 'Row Unselected',\n expandRow: 'Row Expanded',\n collapseRow: 'Row Collapsed',\n showFilterMenu: 'Show Filter Menu',\n hideFilterMenu: 'Hide Filter Menu',\n filterOperator: 'Filter Operator',\n filterConstraint: 'Filter Constraint',\n editRow: 'Row Edit',\n saveEdit: 'Save Edit',\n cancelEdit: 'Cancel Edit',\n listView: 'List View',\n gridView: 'Grid View',\n slide: 'Slide',\n slideNumber: '{slideNumber}',\n zoomImage: 'Zoom Image',\n zoomIn: 'Zoom In',\n zoomOut: 'Zoom Out',\n rotateRight: 'Rotate Right',\n rotateLeft: 'Rotate Left',\n listLabel: 'Option List',\n },\n} as Translation;\n","import { Translation } from 'primeng/api';\n\n/**\n * French locale for PrimeNG components.\n *\n * Usage:\n * ```ts\n * import { PRIMENG_FR_LOCALE } from '@elasticias/core';\n * this.primeng.translation = PRIMENG_FR_LOCALE;\n * ```\n */\nexport const PRIMENG_FR_LOCALE: Translation = {\n startsWith: 'Commence par',\n contains: 'Contient',\n notContains: 'Ne contient pas',\n endsWith: 'Se termine par',\n equals: 'Égal à',\n notEquals: 'Différent de',\n noFilter: 'Aucun filtre',\n lt: 'Inférieur à',\n lte: 'Inférieur ou égal à',\n gt: 'Supérieur à',\n gte: 'Supérieur ou égal à',\n dateIs: 'La date est',\n dateIsNot: \"La date n'est pas\",\n dateBefore: 'La date est avant',\n dateAfter: 'La date est après',\n clear: 'Effacer',\n apply: 'Appliquer',\n matchAll: 'Correspond à tous',\n matchAny: \"Correspond à n'importe quel\",\n addRule: 'Ajouter une règle',\n removeRule: 'Supprimer la règle',\n accept: 'Oui',\n reject: 'Non',\n choose: 'Choisir',\n upload: 'Télécharger',\n cancel: 'Annuler',\n completed: 'Terminé',\n pending: 'En attente',\n fileSizeTypes: ['o', 'Ko', 'Mo', 'Go', 'To', 'Po', 'Eo', 'Zo', 'Yo'],\n dayNames: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],\n dayNamesShort: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],\n dayNamesMin: ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'],\n monthNames: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],\n monthNamesShort: ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jun', 'Jul', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc'],\n chooseYear: \"Choisir l'année\",\n chooseMonth: 'Choisir le mois',\n chooseDate: 'Choisir la date',\n prevDecade: 'Décennie précédente',\n nextDecade: 'Décennie suivante',\n prevYear: 'Année précédente',\n nextYear: 'Année suivante',\n prevMonth: 'Mois précédent',\n nextMonth: 'Mois suivant',\n prevHour: 'Heure précédente',\n nextHour: 'Heure suivante',\n prevMinute: 'Minute précédente',\n nextMinute: 'Minute suivante',\n prevSecond: 'Seconde précédente',\n nextSecond: 'Seconde suivante',\n am: 'AM',\n pm: 'PM',\n today: \"Aujourd'hui\",\n weekHeader: 'Sem',\n firstDayOfWeek: 1,\n showMonthAfterYear: false,\n dateFormat: 'dd/mm/yy',\n weak: 'Faible',\n medium: 'Moyen',\n strong: 'Fort',\n passwordPrompt: 'Entrez un mot de passe',\n emptyFilterMessage: 'Aucun résultat trouvé',\n searchMessage: '{0} résultats sont disponibles',\n selectionMessage: '{0} éléments sélectionnés',\n emptySelectionMessage: 'Aucun élément sélectionné',\n emptySearchMessage: 'Aucun résultat trouvé',\n emptyMessage: 'Aucune option disponible',\n aria: {\n trueLabel: 'Vrai',\n falseLabel: 'Faux',\n nullLabel: 'Non sélectionné',\n star: '1 étoile',\n stars: '{star} étoiles',\n selectAll: 'Tous les éléments sélectionnés',\n unselectAll: 'Tous les éléments désélectionnés',\n close: 'Fermer',\n previous: 'Précédent',\n next: 'Suivant',\n navigation: 'Navigation',\n scrollTop: 'Défiler vers le haut',\n moveTop: 'Déplacer vers le haut',\n moveUp: 'Déplacer vers le haut',\n moveDown: 'Déplacer vers le bas',\n moveBottom: 'Déplacer vers le bas',\n moveToTarget: 'Déplacer vers la cible',\n moveToSource: 'Déplacer vers la source',\n moveAllToTarget: 'Tout déplacer vers la cible',\n moveAllToSource: 'Tout déplacer vers la source',\n pageLabel: 'Page {page}',\n firstPageLabel: 'Première page',\n lastPageLabel: 'Dernière page',\n nextPageLabel: 'Page suivante',\n prevPageLabel: 'Page précédente',\n rowsPerPageLabel: 'Lignes par page',\n jumpToPageDropdownLabel: 'Aller à la page',\n jumpToPageInputLabel: 'Aller à la page',\n selectRow: 'Ligne sélectionnée',\n unselectRow: 'Ligne désélectionnée',\n expandRow: 'Ligne développée',\n collapseRow: 'Ligne réduite',\n showFilterMenu: 'Afficher le menu de filtrage',\n hideFilterMenu: 'Masquer le menu de filtrage',\n filterOperator: 'Opérateur de filtrage',\n filterConstraint: 'Contrainte de filtrage',\n editRow: 'Modifier la ligne',\n saveEdit: 'Enregistrer la modification',\n cancelEdit: 'Annuler la modification',\n listView: 'Vue en liste',\n gridView: 'Vue en grille',\n slide: 'Glisser',\n slideNumber: '{slideNumber}',\n zoomImage: \"Agrandir l'image\",\n zoomIn: 'Zoomer',\n zoomOut: 'Dézoomer',\n rotateRight: 'Faire pivoter à droite',\n rotateLeft: 'Faire pivoter à gauche',\n listLabel: 'Liste',\n },\n} as Translation;\n","import { Translation } from 'primeng/api';\n\n/**\n * Arabic locale for PrimeNG components (Moroccan month names).\n *\n * Usage:\n * ```ts\n * import { PRIMENG_AR_LOCALE } from '@elasticias/core';\n * this.primeng.translation = PRIMENG_AR_LOCALE;\n * ```\n */\nexport const PRIMENG_AR_LOCALE: Translation = {\n startsWith: 'يبدأ بـ',\n contains: 'يحتوي على',\n notContains: 'لا يحتوي على',\n endsWith: 'ينتهي بـ',\n equals: 'يساوي',\n notEquals: 'لا يساوي',\n noFilter: 'بدون فلتر',\n lt: 'أقل من',\n lte: 'أقل من أو يساوي',\n gt: 'أكبر من',\n gte: 'أكبر من أو يساوي',\n dateIs: 'التاريخ هو',\n dateIsNot: 'التاريخ ليس',\n dateBefore: 'التاريخ قبل',\n dateAfter: 'التاريخ بعد',\n clear: 'مسح',\n apply: 'تطبيق',\n matchAll: 'تطابق الكل',\n matchAny: 'تطابق أي',\n addRule: 'إضافة قاعدة',\n removeRule: 'حذف القاعدة',\n accept: 'نعم',\n reject: 'لا',\n choose: 'اختيار',\n upload: 'رفع',\n cancel: 'إلغاء',\n completed: 'مكتمل',\n pending: 'قيد الانتظار',\n fileSizeTypes: ['بايت', 'ك.ب', 'م.ب', 'ج.ب', 'ت.ب', 'ب.ب', 'إ.ب', 'ز.ب', 'ي.ب'],\n dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],\n dayNamesShort: ['أحد', 'اثن', 'ثلا', 'أرب', 'خمي', 'جمع', 'سبت'],\n dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'],\n monthNames: ['يناير', 'فبراير', 'مارس', 'أبريل', 'ماي', 'يونيو', 'يوليوز', 'غشت', 'شتنبر', 'أكتوبر', 'نونبر', 'دجنبر'],\n monthNamesShort: ['ينا', 'فبر', 'مار', 'أبر', 'ماي', 'يون', 'يول', 'غشت', 'شتن', 'أكت', 'نون', 'دجن'],\n chooseYear: 'اختر السنة',\n chooseMonth: 'اختر الشهر',\n chooseDate: 'اختر التاريخ',\n prevDecade: 'العقد السابق',\n nextDecade: 'العقد التالي',\n prevYear: 'السنة السابقة',\n nextYear: 'السنة التالية',\n prevMonth: 'الشهر السابق',\n nextMonth: 'الشهر التالي',\n prevHour: 'الساعة السابقة',\n nextHour: 'الساعة التالية',\n prevMinute: 'الدقيقة السابقة',\n nextMinute: 'الدقيقة التالية',\n prevSecond: 'الثانية السابقة',\n nextSecond: 'الثانية التالية',\n am: 'ص',\n pm: 'م',\n today: 'اليوم',\n weekHeader: 'أس',\n firstDayOfWeek: 1,\n showMonthAfterYear: false,\n dateFormat: 'dd/mm/yy',\n weak: 'ضعيف',\n medium: 'متوسط',\n strong: 'قوي',\n passwordPrompt: 'أدخل كلمة المرور',\n emptyFilterMessage: 'لم يتم العثور على نتائج',\n searchMessage: '{0} نتائج متاحة',\n selectionMessage: '{0} عناصر محددة',\n emptySelectionMessage: 'لا يوجد عنصر محدد',\n emptySearchMessage: 'لم يتم العثور على نتائج',\n emptyMessage: 'لا توجد خيارات متاحة',\n aria: {\n trueLabel: 'صحيح',\n falseLabel: 'خاطئ',\n nullLabel: 'غير محدد',\n star: 'نجمة واحدة',\n stars: '{star} نجوم',\n selectAll: 'تم تحديد جميع العناصر',\n unselectAll: 'تم إلغاء تحديد جميع العناصر',\n close: 'إغلاق',\n previous: 'السابق',\n next: 'التالي',\n navigation: 'التنقل',\n scrollTop: 'التمرير للأعلى',\n moveTop: 'نقل للأعلى',\n moveUp: 'نقل للأعلى',\n moveDown: 'نقل للأسفل',\n moveBottom: 'نقل للأسفل',\n moveToTarget: 'نقل إلى الهدف',\n moveToSource: 'نقل إلى المصدر',\n moveAllToTarget: 'نقل الكل إلى الهدف',\n moveAllToSource: 'نقل الكل إلى المصدر',\n pageLabel: 'صفحة {page}',\n firstPageLabel: 'الصفحة الأولى',\n lastPageLabel: 'الصفحة الأخيرة',\n nextPageLabel: 'الصفحة التالية',\n prevPageLabel: 'الصفحة السابقة',\n rowsPerPageLabel: 'سطور في الصفحة',\n jumpToPageDropdownLabel: 'الانتقال إلى الصفحة',\n jumpToPageInputLabel: 'الانتقال إلى الصفحة',\n selectRow: 'تم تحديد السطر',\n unselectRow: 'تم إلغاء تحديد السطر',\n expandRow: 'تم توسيع السطر',\n collapseRow: 'تم طي السطر',\n showFilterMenu: 'إظهار قائمة الفلتر',\n hideFilterMenu: 'إخفاء قائمة الفلتر',\n filterOperator: 'عامل الفلتر',\n filterConstraint: 'قيد الفلتر',\n editRow: 'تعديل السطر',\n saveEdit: 'حفظ التعديل',\n cancelEdit: 'إلغاء التعديل',\n listView: 'عرض قائمة',\n gridView: 'عرض شبكة',\n slide: 'تمرير',\n slideNumber: '{slideNumber}',\n zoomImage: 'تكبير الصورة',\n zoomIn: 'تكبير',\n zoomOut: 'تصغير',\n rotateRight: 'تدوير لليمين',\n rotateLeft: 'تدوير لليسار',\n listLabel: 'قائمة',\n },\n} as Translation;\n","import { InjectionToken } from '@angular/core';\n\n/**\n * The eight ERP modules surfaced by Comptoir. New modules require\n * a matching `--m-{id}` token in the SCSS layer (libs/ui/src/lib/_comptoir.scss)\n * and a labelKey in the consuming app's i18n bundles.\n */\nexport type EfModuleId =\n | 'sales'\n | 'purchase'\n | 'stock'\n | 'pos'\n | 'marketing'\n | 'store'\n | 'finance'\n | 'admin';\n\nexport type EfNavAction = 'read' | 'write' | 'admin';\n\nexport interface EfNavItem {\n /** Stable identifier — usually matches the screen code (e.g. `Users`, `SalesOrders`). */\n id: string;\n labelKey: string;\n icon?: string;\n route: string;\n /** Minimum permission level required to render this item. Defaults to `read`. */\n requiredAction?: EfNavAction;\n /**\n * Code of the screen this item opens (the key in the user's screen\n * grants, e.g. `SalesOrders`). When set, the item shows only if the\n * user has Read on that screen, on top of the module-level check. Not\n * the same as `id`, which is only a stable identifier. Items without\n * it are filtered by module level alone.\n */\n screenCode?: string;\n /**\n * Optional count chip rendered after the label (e.g. `Commandes ⟨14⟩`).\n * Apps typically derive this from a service signal and patch the\n * registry — it can be number, string, or anything stringifiable.\n */\n badge?: string | number;\n}\n\nexport interface EfNavSection {\n id: string;\n labelKey?: string;\n items: EfNavItem[];\n}\n\nexport interface EfModule {\n id: EfModuleId;\n labelKey: string;\n /** PrimeNG icon class used by `ef-module-rail`, e.g. `pi pi-shopping-bag`. */\n icon: string;\n /**\n * CSS custom-property name (without the leading `--`) that the rail\n * applies to the module-current accent. Always `m-{id}` and resolves\n * via the SCSS layer's `[data-module]` selectors at runtime.\n */\n accent: `m-${EfModuleId}`;\n defaultRoute: string;\n navSections: EfNavSection[];\n /**\n * Logical grouping for rail divider placement. `ef-module-rail` renders\n * a 1px divider between two consecutive visible modules whose `group`\n * differs. Free string — `'operations' | 'commerce' | 'admin'` is the\n * conventional set but apps can use anything stable.\n */\n group?: string;\n}\n\n/**\n * Default skeleton for the eight ERP modules. Apps either consume this\n * directly via `EF_MODULES_TOKEN` or extend it with their own `navSections`.\n *\n * Phase 1 ships the metadata only — `ef-module-rail` (Phase 2) uses\n * `id` / `labelKey` / `icon` / `accent` / `defaultRoute`. `navSections`\n * are populated per-app as each module's screens land in Phase 4-5.\n */\nexport const EF_MODULES: ReadonlyArray<EfModule> = [\n {\n id: 'sales',\n labelKey: 'modules.sales',\n icon: 'pi pi-shopping-bag',\n accent: 'm-sales',\n defaultRoute: '/operations/sales',\n navSections: [],\n group: 'operations',\n },\n {\n id: 'purchase',\n labelKey: 'modules.purchase',\n icon: 'pi pi-truck',\n accent: 'm-purchase',\n defaultRoute: '/operations/purchase',\n navSections: [],\n group: 'operations',\n },\n {\n id: 'stock',\n labelKey: 'modules.stock',\n icon: 'pi pi-warehouse',\n accent: 'm-stock',\n defaultRoute: '/operations/stock',\n navSections: [],\n group: 'operations',\n },\n {\n id: 'pos',\n labelKey: 'modules.pos',\n icon: 'pi pi-shop',\n accent: 'm-pos',\n defaultRoute: '/pos',\n navSections: [],\n group: 'operations',\n },\n {\n id: 'marketing',\n labelKey: 'modules.marketing',\n icon: 'pi pi-megaphone',\n accent: 'm-marketing',\n defaultRoute: '/marketing',\n navSections: [],\n group: 'commerce',\n },\n {\n id: 'store',\n labelKey: 'modules.store',\n icon: 'pi pi-globe',\n accent: 'm-store',\n defaultRoute: '/store',\n navSections: [],\n group: 'commerce',\n },\n {\n id: 'finance',\n labelKey: 'modules.finance',\n icon: 'pi pi-chart-line',\n accent: 'm-finance',\n defaultRoute: '/finance',\n navSections: [],\n group: 'commerce',\n },\n {\n id: 'admin',\n labelKey: 'modules.admin',\n icon: 'pi pi-shield',\n accent: 'm-admin',\n defaultRoute: '/admin',\n navSections: [],\n group: 'admin',\n },\n];\n\n/**\n * DI token that the shell components (`ef-module-rail`, `ef-module-side`)\n * read from. Apps provide their own definition (typically extending\n * `EF_MODULES` with populated `navSections`):\n *\n * ```ts\n * providers: [\n * { provide: EF_MODULES_TOKEN, useValue: APP_MODULES }\n * ]\n * ```\n */\nexport const EF_MODULES_TOKEN = new InjectionToken<ReadonlyArray<EfModule>>(\n 'EF_MODULES',\n { providedIn: 'root', factory: () => EF_MODULES }\n);\n","import { computed, DestroyRef, inject, Injectable, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { filter } from 'rxjs/operators';\nimport { EF_MODULES_TOKEN, EfModule, EfModuleId, EfNavItem } from './ef-module-registry';\n\n/**\n * Single source of truth for \"which ERP module is active right now.\"\n *\n * Watches the Router and matches the current URL against each module's\n * `defaultRoute`. The longest matching prefix wins, so `/operations/sales`\n * resolves to `sales` even though `/operations` could in theory match\n * something shorter.\n *\n * Consumers — `ef-module-rail`, `ef-module-side`, `ef-app-main`,\n * `ef-page-head` — read `activeModule()` and derive their state from it.\n *\n * Apps that navigate programmatically without a URL change (rare) can\n * call `setActiveModule(id)` to override.\n */\n@Injectable({ providedIn: 'root' })\nexport class EfActiveModuleService {\n private readonly router = inject(Router);\n private readonly modules = inject(EF_MODULES_TOKEN);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly _activeModule = signal<EfModule | null>(null);\n private readonly _activeNavItem = signal<EfNavItem | null>(null);\n\n readonly activeModule = this._activeModule.asReadonly();\n readonly activeModuleId = computed(() => this._activeModule()?.id ?? null);\n readonly activeNavItem = this._activeNavItem.asReadonly();\n\n constructor() {\n this.resolveFromUrl(this.router.url);\n\n this.router.events\n .pipe(\n filter((e): e is NavigationEnd => e instanceof NavigationEnd),\n takeUntilDestroyed(this.destroyRef),\n )\n .subscribe(e => this.resolveFromUrl(e.urlAfterRedirects));\n }\n\n /**\n * Force the active module. Most apps don't need this — the router\n * subscription keeps `activeModule()` in sync automatically.\n */\n setActiveModule(id: EfModuleId | null): void {\n if (id === null) {\n this._activeModule.set(null);\n return;\n }\n const match = this.modules.find(m => m.id === id);\n if (match) this._activeModule.set(match);\n }\n\n private resolveFromUrl(url: string): void {\n const path = url.split('?')[0].split('#')[0];\n\n let bestModule: EfModule | null = null;\n let bestNavItem: EfNavItem | null = null;\n let bestLen = 0;\n for (const m of this.modules) {\n for (const route of this.routesFor(m)) {\n if (path === route || path.startsWith(route + '/')) {\n if (route.length > bestLen) {\n bestModule = m;\n bestNavItem = this.findNavItem(m, route);\n bestLen = route.length;\n }\n }\n }\n }\n this._activeModule.set(bestModule);\n this._activeNavItem.set(bestNavItem);\n }\n\n private findNavItem(m: EfModule, route: string): EfNavItem | null {\n for (const section of m.navSections) {\n for (const item of section.items) {\n if (item.route === route) return item;\n }\n }\n return null;\n }\n\n /**\n * Every URL prefix that should resolve back to this module: the\n * `defaultRoute` plus every nav item route. Modules whose nav items\n * span multiple URL prefixes (e.g. sales spread across `/operations/sales`\n * and `/parameters/sales`) need this to stay active across all of them.\n */\n private routesFor(m: EfModule): string[] {\n const routes: string[] = [m.defaultRoute];\n for (const section of m.navSections) {\n for (const item of section.items) {\n routes.push(item.route);\n }\n }\n return routes;\n }\n}\n","import { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { computed, DestroyRef, inject, Injectable, PLATFORM_ID, signal } from '@angular/core';\n\nexport type EfViewport = 'mobile' | 'tablet' | 'desktop';\n\ninterface ViewportQuery {\n viewport: EfViewport;\n query: string;\n}\n\nconst QUERIES: ViewportQuery[] = [\n { viewport: 'mobile', query: '(max-width: 767px)' },\n { viewport: 'tablet', query: '(min-width: 768px) and (max-width: 1279px)' },\n { viewport: 'desktop', query: '(min-width: 1280px)' },\n];\n\n/**\n * Emits the current viewport tier based on `window.matchMedia` breakpoints.\n *\n * Breakpoints come from `libs/tokens/targets.json`:\n * - mobile: ≤ 767px\n * - tablet: 768 – 1279px\n * - desktop: ≥ 1280px\n *\n * SSR-safe: returns `'desktop'` when `window` is unavailable.\n *\n * Usage:\n * ```ts\n * private viewport = inject(EfViewportService);\n *\n * isMobile = computed(() => this.viewport.current() === 'mobile');\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class EfViewportService {\n private readonly document = inject(DOCUMENT);\n private readonly platformId = inject(PLATFORM_ID);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly _current = signal<EfViewport>('desktop');\n\n readonly current = this._current.asReadonly();\n readonly isMobile = computed(() => this._current() === 'mobile');\n readonly isTablet = computed(() => this._current() === 'tablet');\n readonly isDesktop = computed(() => this._current() === 'desktop');\n\n constructor() {\n if (!isPlatformBrowser(this.platformId)) return;\n\n const win = this.document.defaultView;\n if (!win || typeof win.matchMedia !== 'function') return;\n\n const lists = QUERIES.map(({ viewport, query }) => {\n const mql = win.matchMedia(query);\n const handler = (e: MediaQueryListEvent | MediaQueryList) => {\n if (e.matches) this._current.set(viewport);\n };\n handler(mql);\n mql.addEventListener('change', handler as (e: MediaQueryListEvent) => void);\n return { mql, handler };\n });\n\n this.destroyRef.onDestroy(() => {\n for (const { mql, handler } of lists) {\n mql.removeEventListener('change', handler as (e: MediaQueryListEvent) => void);\n }\n });\n }\n}\n","import { computed, inject, Injectable, Signal, signal } from '@angular/core';\nimport { Permissions, ScreenGrants } from '@elasticias/types';\nimport { EF_MODULES_TOKEN, EfModule, EfModuleId } from '../modules/ef-module-registry';\n\nexport type EfPermissionLevel = 'none' | 'read' | 'write' | 'admin';\n\nexport interface EfModulePermission {\n module: EfModuleId;\n level: EfPermissionLevel;\n}\n\nconst LEVEL_ORDER: Record<EfPermissionLevel, number> = {\n none: 0,\n read: 1,\n write: 2,\n admin: 3,\n};\n\nconst ACTION_REQUIRED: Record<Exclude<EfPermissionLevel, 'none'>, EfPermissionLevel> = {\n read: 'read',\n write: 'write',\n admin: 'admin',\n};\n\n/**\n * Module-scoped permission service.\n *\n * Apps populate it from their auth bootstrap once the user's profile is\n * loaded — typically via `setPermissions()` or by providing a custom\n * source signal:\n *\n * ```ts\n * // bootstrap.ts\n * const perms = inject(EfPermissionService);\n * perms.setPermissions(profile.permissions);\n * ```\n *\n * The service is the single source of truth for shell components\n * (`ef-module-rail`, `ef-module-side`, `*efCan` directive) and routing\n * defaults. Once the screens/menus → Mongo migration lands, the\n * permissions list will be served denormalized on the user/profile\n * document and consumed here without a join.\n */\n@Injectable({ providedIn: 'root' })\nexport class EfPermissionService {\n private readonly modules = inject(EF_MODULES_TOKEN);\n\n private readonly _permissions = signal<ReadonlyArray<EfModulePermission>>([]);\n\n readonly permissions = this._permissions.asReadonly();\n\n /**\n * Replace the current permission set. Pass `[]` to clear (e.g., on logout).\n */\n setPermissions(perms: ReadonlyArray<EfModulePermission>): void {\n this._permissions.set(perms);\n }\n\n /**\n * `null` until the app pushes the user's per-screen grants. While it is\n * `null`, `canScreen` allows everything, so nav behaves as it did before\n * per-screen filtering existed (module level only).\n */\n private readonly _screenGrants = signal<ScreenGrants | null>(null);\n\n /**\n * Replace the per-screen grants (keyed by screen code). Pass `null` to\n * go back to \"no grants info\"; `{}` means the user has no screen at all.\n */\n setScreenGrants(grants: ScreenGrants | null): void {\n this._screenGrants.set(grants);\n }\n\n /**\n * Whether the user holds `verb` on the screen `code`. Reads a signal, so\n * it is safe inside `computed()`. Allows everything until grants have\n * been set; after that a screen with no grant is denied.\n */\n canScreen(code: string, verb: Permissions | string = Permissions.Read): boolean {\n const grants = this._screenGrants();\n if (grants === null) return true;\n return grants[code]?.permissions?.includes(verb) ?? false;\n }\n\n /**\n * The level granted to the current user for a given module.\n * Returns `'none'` if the module is not in the permission set.\n */\n level(module: EfModuleId): EfPermissionLevel {\n return this._permissions().find(p => p.module === module)?.level ?? 'none';\n }\n\n /**\n * Whether the current user can perform `action` on `module`.\n * Levels are hierarchical: `admin` > `write` > `read` > `none`.\n */\n can(module: EfModuleId, action: Exclude<EfPermissionLevel, 'none'> = 'read'): boolean {\n return LEVEL_ORDER[this.level(module)] >= LEVEL_ORDER[ACTION_REQUIRED[action]];\n }\n\n /**\n * The list of modules the user can read, in registry order.\n * Used by `ef-module-rail` to decide which icons render.\n */\n readonly visibleModules: Signal<ReadonlyArray<EfModule>> = computed(() => {\n const perms = this._permissions();\n const granted = new Set(\n perms.filter(p => p.level !== 'none').map(p => p.module)\n );\n return this.modules.filter(m => granted.has(m.id));\n });\n\n /**\n * The first visible module — the default landing module after login.\n * Returns `null` when the user has no modules.\n */\n readonly defaultModule: Signal<EfModule | null> = computed(() => {\n return this.visibleModules()[0] ?? null;\n });\n}\n","import { InjectionToken } from '@angular/core';\n\n/**\n * The bit of an app's session that shared chrome needs to act on.\n *\n * Signing out belongs to the app — it owns the auth client, the grant\n * refresh timer and where to land afterwards — but the control that\n * triggers it belongs to the shell. This token is the seam between them,\n * the same shape as `SCREEN_REF_DATA_SERVICE`.\n *\n * Components inject it optionally and hide their affordance when nothing\n * provides it, so an app that has not opted in shows no dead button.\n *\n * ```ts\n * // app.config.ts\n * { provide: EF_SESSION, useExisting: AuthorizeService }\n * ```\n */\nexport interface EfSession {\n /** End the session and send the user wherever the app decides. */\n logout(): void;\n}\n\nexport const EF_SESSION = new InjectionToken<EfSession>('EF_SESSION');\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Which build of the app is running.\n *\n * Apps generate this at build time — the framework cannot know it — and\n * provide it here so shared chrome can show it without importing anything\n * app-specific. `EfBuildStampComponent` is the intended consumer.\n *\n * ```ts\n * // app.config.ts\n * { provide: EF_BUILD_INFO, useValue: BUILD_INFO }\n * ```\n */\nexport interface EfBuildInfo {\n /** Release version. Empty when the app maintains none — consumers should\n * omit it rather than print a placeholder. */\n version: string;\n\n /** Short commit hash the build came from. */\n commit: string;\n\n /** Commit date as `YYYY-MM-DD` — what a reader actually recognises. */\n date: string;\n\n /** Branch the build came from, useful for telling develop from a release. */\n branch: string;\n\n /**\n * Which deployment this build was made for: `production`, `staging`,\n * `develop`, or `local`. Decided at build time from the ref, because a\n * production build is made from a tag rather than a branch.\n */\n environment: string;\n\n /**\n * The shared `@elasticias/*` packages this build was compiled against,\n * in the order the app wants them listed.\n *\n * Optional: an app that ships no shared packages, or generates its stamp\n * without resolving them, simply omits the key and consumers render\n * nothing rather than an empty group.\n */\n packages?: EfBuildPackage[];\n}\n\n/** One shared package and the version that went into the build. */\nexport interface EfBuildPackage {\n /** Package name as it appears in `package.json`, e.g. `@elasticias/ui`. */\n name: string;\n\n /** The version actually installed, not the range the app declared. */\n version: string;\n}\n\nexport const EF_BUILD_INFO = new InjectionToken<EfBuildInfo>('EF_BUILD_INFO');\n","import { HttpBackend, HttpClient } from '@angular/common/http';\nimport { inject, InjectionToken, Provider } from '@angular/core';\nimport { TranslateLoader, TranslationObject } from '@ngx-translate/core';\nimport { Observable } from 'rxjs';\nimport { EF_BUILD_INFO } from '../build/ef-build-info.token';\n\n/**\n * Where the translation files live, and how their URL is stamped.\n */\nexport interface EfVersionedTranslateLoaderConfig {\n /** Path the language file sits under. Defaults to `/assets/i18n/`. */\n prefix?: string;\n\n /** File extension. Defaults to `.json`. */\n suffix?: string;\n\n /**\n * Build identifier appended as `?v=`. Defaults to `EF_BUILD_INFO.commit`,\n * which the app already regenerates on every build, so a release changes\n * every translation URL without anyone maintaining a second number.\n */\n version?: string;\n\n /**\n * Bypass the HTTP interceptor chain. On by default: a translation file is\n * a static asset, and putting it through the app's auth interceptor means\n * a 401 handler can fire before the app knows how to say anything.\n */\n useHttpBackend?: boolean;\n}\n\nexport const EF_TRANSLATE_LOADER_CONFIG = new InjectionToken<EfVersionedTranslateLoaderConfig>(\n 'EF_TRANSLATE_LOADER_CONFIG',\n);\n\n/**\n * Translation loader that puts the build id in the URL.\n *\n * Angular content-hashes its JS and CSS but copies `/assets` verbatim, so a\n * translation file ships new content at a URL that never changes — the one\n * case HTTP caching handles worst. Two things follow from that.\n *\n * The first is ordinary staleness: a device holding yesterday's copy has no\n * reason to ask for today's, so a newly added key renders as its raw key.\n *\n * The second is worse and is why this exists rather than a cache header. A\n * device that cached the file while the server was still sending\n * `max-age=31536000, immutable` will not re-request it for up to a year, and\n * therefore never sees whatever header we send next. Headers only reach\n * browsers that ask. A URL they have never seen has no cache entry at all, so\n * changing the URL is the only thing that reaches them.\n *\n * Stamping the build id also means the URL is stable *within* a release, so\n * the file can go back to being cached hard instead of revalidated on every\n * single page load.\n */\nexport class EfVersionedTranslateLoader implements TranslateLoader {\n private readonly cfg = inject(EF_TRANSLATE_LOADER_CONFIG, { optional: true }) ?? {};\n private readonly buildInfo = inject(EF_BUILD_INFO, { optional: true });\n\n /**\n * Built from `HttpBackend` rather than injecting `HttpClient`, so the\n * request skips interceptors. See `useHttpBackend`.\n */\n private readonly http =\n this.cfg.useHttpBackend === false\n ? inject(HttpClient)\n : new HttpClient(inject(HttpBackend));\n\n getTranslation(lang: string): Observable<TranslationObject> {\n const prefix = this.cfg.prefix ?? '/assets/i18n/';\n const suffix = this.cfg.suffix ?? '.json';\n const version = this.cfg.version ?? this.buildInfo?.commit ?? '';\n\n // No build id (a bare `ng serve`, or an app that ships no stamp) means\n // no query string at all, rather than `?v=` — a URL that changes shape\n // between environments is harder to reason about than one that doesn't.\n const url = `${prefix}${lang}${suffix}${version ? `?v=${encodeURIComponent(version)}` : ''}`;\n return this.http.get<TranslationObject>(url);\n }\n}\n\n/**\n * Provide the versioned loader in place of `provideTranslateHttpLoader`.\n *\n * ```ts\n * provideTranslateService({ fallbackLang: 'fr', lang }),\n * provideEfTranslateLoader({ prefix: '/assets/i18n/' }),\n * ```\n *\n * Pair it with a long-lived cache header on the translation files: the URL now\n * carries the release, so there is nothing left to revalidate against.\n */\nexport function provideEfTranslateLoader(\n config: EfVersionedTranslateLoaderConfig = {},\n): Provider[] {\n return [\n { provide: EF_TRANSLATE_LOADER_CONFIG, useValue: config },\n { provide: TranslateLoader, useClass: EfVersionedTranslateLoader },\n ];\n}\n","/**\n * Key-combo parsing shared by `EfShortcutService` (matching a keydown event\n * against the registry) and `formatShortcut` (rendering a registration for\n * display). Kept internal to the shortcuts folder: neither export is part\n * of the public `@elasticias/core` surface.\n */\n\n/** Fixed order modifiers are stored and compared in, so `'shift+mod+x'`\n * and `'mod+shift+x'` normalise to the same string. */\nconst MODIFIER_ORDER = ['mod', 'shift', 'alt'] as const;\n\n/**\n * Physical-key `KeyboardEvent.code` values mapped to the token used in a\n * `keys` string. `code` identifies the physical key regardless of what\n * Shift makes it print, which is what lets `'shift+/'` match the key next\n * to Right Shift on a US layout even though pressing it actually produces\n * `'?'`.\n */\nconst CODE_KEYS: Record<string, string> = {\n Enter: 'enter',\n Escape: 'escape',\n Space: 'space',\n Backspace: 'backspace',\n Tab: 'tab',\n Slash: '/',\n};\n\n/** Normalises a `keys` registration string into a canonical, comparable\n * form: lowercase tokens, modifiers first in a fixed order. */\nexport function normaliseKeys(raw: string): string {\n const tokens = raw\n .toLowerCase()\n .split('+')\n .map(token => token.trim())\n .filter(Boolean);\n const modifierTokens = MODIFIER_ORDER.filter(modifier => tokens.includes(modifier));\n const rest = tokens.filter(token => !(MODIFIER_ORDER as readonly string[]).includes(token));\n return [...modifierTokens, ...rest].join('+');\n}\n\ninterface KeyEventLike {\n code: string;\n key: string;\n metaKey: boolean;\n ctrlKey: boolean;\n shiftKey: boolean;\n altKey: boolean;\n}\n\n/** The canonical key token for an event, independent of Shift. `KeyD`\n * is `'d'` whether or not Shift was held. */\nfunction keyToken(event: KeyEventLike): string {\n if (CODE_KEYS[event.code]) return CODE_KEYS[event.code];\n if (event.code?.startsWith('Key')) return event.code.slice(3).toLowerCase();\n if (event.code?.startsWith('Digit')) return event.code.slice(5);\n return event.key.toLowerCase();\n}\n\n/**\n * Builds the normalised combo a keydown event represents, e.g. `'mod+d'`.\n * `isMac` decides which physical modifier counts as `mod`: Meta on macOS,\n * Control everywhere else.\n */\nexport function comboFromEvent(event: KeyEventLike, isMac: boolean): string {\n const tokens: string[] = [];\n if (isMac ? event.metaKey : event.ctrlKey) tokens.push('mod');\n if (event.shiftKey) tokens.push('shift');\n if (event.altKey) tokens.push('alt');\n tokens.push(keyToken(event));\n return normaliseKeys(tokens.join('+'));\n}\n\n/**\n * True while the event target is a place the user is typing: an input, a\n * textarea, a select, or anything `contenteditable`. The dispatcher checks\n * this before anything else. Without it every shortcut key is a reserved\n * word in every text field in the app.\n */\nexport function isTypingTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n const tag = target.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true;\n return target.isContentEditable;\n}\n","import { normaliseKeys } from './shortcut-keys';\n\n/** Reads the platform once. `userAgentData` is the current standard; the\n * `platform` string fallback covers browsers that don't expose it yet.\n *\n * The test is \"Apple\", not \"Mac\". An iPhone reports `iPhone` and an iPad\n * reports either `iPad` or, since iPadOS 13, the same `MacIntel` a desktop\n * does. A narrower `/mac/i` told every iOS device with a keyboard that the\n * modifier was Ctrl, which is the one thing it is not. */\nfunction detectApplePlatform(): boolean {\n if (typeof navigator === 'undefined') return false;\n const uaData = (navigator as Navigator & { userAgentData?: { platform?: string } })\n .userAgentData;\n const platform = uaData?.platform ?? navigator.platform ?? '';\n return /mac|iphone|ipad|ipod/i.test(platform);\n}\n\n/**\n * Detected once, at module load. `formatShortcut` uses it to choose between\n * the Command glyphs and the Ctrl words. True for every Apple platform, not\n * just the desktop: an iPad with a keyboard sends Command like a Mac does.\n */\nexport const isMacPlatform: boolean = detectApplePlatform();\n\nconst MAC_MODIFIER_GLYPHS: Record<string, string> = {\n mod: '⌘',\n shift: '⇧',\n alt: '⌥',\n};\n\nconst OTHER_MODIFIER_WORDS: Record<string, string> = {\n mod: 'Ctrl',\n shift: 'Shift',\n alt: 'Alt',\n};\n\n/** Named keys with a glyph of their own, distinct from their letter. */\nconst KEY_GLYPHS: Record<string, string> = {\n enter: '↵',\n escape: 'Esc',\n backspace: '⌫',\n space: 'Space',\n tab: 'Tab',\n};\n\n/**\n * A produced character that stands in for the whole combo. Shift plus the\n * physical `/` key always reads as the question mark it prints. Showing\n * it as `'Shift' + '/'` would describe the keys pressed rather than the\n * shortcut a person recognises.\n */\nconst SHIFTED_SYMBOL_GLYPHS: Record<string, string> = {\n '/': '?',\n};\n\n/**\n * Formats a `keys` registration for display. One registration, correct on\n * both platforms:\n *\n * - `'mod+d'` → `⌘D` on macOS, `Ctrl+D` elsewhere\n * - `'enter'` → `↵`\n * - `'e'` → `E`\n * - `'shift+/'` → `?`\n *\n * `mac` defaults to the platform this code is actually running on. Pass it\n * explicitly only to render for a platform other than the current one.\n */\nexport function formatShortcut(keys: string, mac: boolean = isMacPlatform): string {\n const tokens = normaliseKeys(keys).split('+');\n const key = tokens[tokens.length - 1];\n const modifiers = tokens.slice(0, -1);\n\n if (modifiers.length === 1 && modifiers[0] === 'shift' && SHIFTED_SYMBOL_GLYPHS[key]) {\n return SHIFTED_SYMBOL_GLYPHS[key];\n }\n\n const displayKey = KEY_GLYPHS[key] ?? key.toUpperCase();\n\n if (mac) {\n return modifiers.map(modifier => MAC_MODIFIER_GLYPHS[modifier] ?? modifier).join('') + displayKey;\n }\n\n const words = modifiers.map(modifier => OTHER_MODIFIER_WORDS[modifier] ?? modifier);\n return [...words, displayKey].join('+');\n}\n","import { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { computed, DestroyRef, inject, Injectable, PLATFORM_ID, signal } from '@angular/core';\nimport { isMacPlatform } from './format-shortcut';\nimport { comboFromEvent, isTypingTarget, normaliseKeys } from './shortcut-keys';\nimport { EfShortcut, EfShortcutGroup } from './ef-shortcut.types';\n\n/**\n * App-wide keyboard-shortcut registry, plus the single `document:keydown`\n * dispatcher that acts on it.\n *\n * ```ts\n * private readonly shortcuts = inject(EfShortcutService);\n *\n * constructor() {\n * // Auto-unregisters on this component's DestroyRef, called from a\n * // constructor / field initializer, an active injection context.\n * this.shortcuts.register({\n * id: 'sales-order.save',\n * keys: 'mod+s',\n * labelKey: 'sales_order_save',\n * group: 'shortcut_group_sales_order',\n * handler: () => this.save(),\n * });\n * }\n * ```\n *\n * Two things make this safe to leave switched on everywhere:\n * - The dispatcher ignores keydown while the target is an input, textarea,\n * select, or anything `contenteditable`, unless the combo includes\n * `mod`. A bare key or a Shift/Alt combo could be real typing (Alt and\n * AltGr both produce characters on several layouts this app ships), but\n * `mod` never does, and a save/search shortcut is normally pressed from\n * inside the very field it acts on. See `isTypingTarget`.\n * - `preventDefault` is only called once a registration actually matches,\n * so an unmapped key never loses its browser default.\n *\n * `list()` exposes the registry grouped for `ef-shortcuts-dialog`, as a\n * signal so the dialog reflects registrations and disposals live.\n */\n@Injectable({ providedIn: 'root' })\nexport class EfShortcutService {\n private readonly document = inject(DOCUMENT);\n private readonly platformId = inject(PLATFORM_ID);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly registry = signal<ReadonlyMap<string, EfShortcut>>(new Map());\n\n /**\n * The registry, grouped for display and deduplicated by\n * (group, label, keys): several instances of the same conceptual\n * shortcut (one row-actions component per row, say) collapse to a\n * single line rather than repeating once per instance.\n */\n readonly list = computed<EfShortcutGroup[]>(() => {\n const deduped = new Map<string, EfShortcut>();\n for (const shortcut of this.registry().values()) {\n const key = `${shortcut.group}::${shortcut.labelKey}::${shortcut.keys}`;\n if (!deduped.has(key)) deduped.set(key, shortcut);\n }\n\n const byGroup = new Map<string, EfShortcut[]>();\n for (const shortcut of deduped.values()) {\n const group = byGroup.get(shortcut.group) ?? [];\n group.push(shortcut);\n byGroup.set(shortcut.group, group);\n }\n\n return Array.from(byGroup.entries()).map(([group, shortcuts]) => ({ group, shortcuts }));\n });\n\n constructor() {\n if (!isPlatformBrowser(this.platformId)) return;\n this.document.addEventListener('keydown', this.onKeydown);\n this.destroyRef.onDestroy(() => this.document.removeEventListener('keydown', this.onKeydown));\n }\n\n /**\n * Registers a shortcut and returns a disposer. When `register` is\n * called from an active injection context (a component constructor or\n * field initializer), the shortcut also auto-unregisters when that\n * context is destroyed. Call it explicitly elsewhere (a plain method,\n * a route resolver already outside construction) and dispose it\n * yourself.\n */\n register(shortcut: EfShortcut): () => void {\n const entry: EfShortcut = { ...shortcut, keys: normaliseKeys(shortcut.keys) };\n\n this.registry.update(map => {\n const next = new Map(map);\n next.set(entry.id, entry);\n return next;\n });\n\n const dispose = (): void => this.unregister(entry.id);\n this.tryGetCallerDestroyRef()?.onDestroy(dispose);\n return dispose;\n }\n\n /** Removes a registration by id. Safe to call twice: the disposer\n * returned by `register` calls this. */\n unregister(id: string): void {\n this.registry.update(map => {\n if (!map.has(id)) return map;\n const next = new Map(map);\n next.delete(id);\n return next;\n });\n }\n\n /** `inject()` throws outside an active injection context; that is how\n * a call from a plain method (as opposed to a constructor) is told\n * apart from one worth auto-disposing. */\n private tryGetCallerDestroyRef(): DestroyRef | null {\n try {\n return inject(DestroyRef, { optional: true });\n } catch {\n return null;\n }\n }\n\n private readonly onKeydown = (event: KeyboardEvent): void => {\n const combo = comboFromEvent(event, isMacPlatform);\n\n // A bare key, or one held with only Shift or Alt, is something the\n // user could plausibly be typing (Alt/AltGr produces real\n // characters on several layouts this app ships, French and\n // Moroccan included), so those stay inert in a field. `mod` never\n // types a character: Ctrl+S saves from inside a form field in\n // every application there is, and a form field is the only place\n // a save shortcut is ever actually pressed from.\n const isModCombo = combo.split('+').includes('mod');\n if (!isModCombo && isTypingTarget(event.target)) return;\n\n for (const shortcut of this.registry().values()) {\n if (shortcut.keys !== combo) continue;\n if (shortcut.when && !shortcut.when()) continue;\n event.preventDefault();\n shortcut.handler();\n return;\n }\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elasticias/core",
3
- "version": "1.0.39",
3
+ "version": "1.0.41",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.0.0",
6
6
  "@angular/core": "^21.0.0",
@@ -3,7 +3,7 @@ import { Observable } from 'rxjs';
3
3
  import * as i0 from '@angular/core';
4
4
  import { InjectionToken, Signal, Provider } from '@angular/core';
5
5
  import { CanActivateFn } from '@angular/router';
6
- import { Permissions } from '@elasticias/types';
6
+ import { Permissions, ScreenGrants } from '@elasticias/types';
7
7
  import * as _primeuix_themes_lara_base from '@primeuix/themes/lara/base';
8
8
  import * as _primeuix_themes_types from '@primeuix/themes/types';
9
9
  import * as _primeuix_themes_aura_base from '@primeuix/themes/aura/base';
@@ -276,7 +276,10 @@ declare const DEFAULT_APP_STATE: AppState;
276
276
  * Apps can extend this service or use it directly.
277
277
  */
278
278
  declare class EfThemeConfigService {
279
- private readonly STORAGE_KEY;
279
+ private readonly STORAGE_NAME;
280
+ private readonly prefs;
281
+ /** Serialized state last adopted from the store; saving it back would only echo. */
282
+ private fromStore;
280
283
  appState: i0.WritableSignal<AppState>;
281
284
  designerActive: i0.WritableSignal<boolean>;
282
285
  newsActive: i0.WritableSignal<boolean>;
@@ -304,6 +307,7 @@ declare class EfThemeConfigService {
304
307
  showDesigner(): void;
305
308
  hideDesigner(): void;
306
309
  private loadAppState;
310
+ private readStoredState;
307
311
  private saveAppState;
308
312
  /**
309
313
  * Applies a tenant's brand color across both PrimeNG's primary palette
@@ -404,6 +408,14 @@ interface EfNavItem {
404
408
  route: string;
405
409
  /** Minimum permission level required to render this item. Defaults to `read`. */
406
410
  requiredAction?: EfNavAction;
411
+ /**
412
+ * Code of the screen this item opens (the key in the user's screen
413
+ * grants, e.g. `SalesOrders`). When set, the item shows only if the
414
+ * user has Read on that screen, on top of the module-level check. Not
415
+ * the same as `id`, which is only a stable identifier. Items without
416
+ * it are filtered by module level alone.
417
+ */
418
+ screenCode?: string;
407
419
  /**
408
420
  * Optional count chip rendered after the label (e.g. `Commandes ⟨14⟩`).
409
421
  * Apps typically derive this from a service signal and patch the
@@ -565,6 +577,23 @@ declare class EfPermissionService {
565
577
  * Replace the current permission set. Pass `[]` to clear (e.g., on logout).
566
578
  */
567
579
  setPermissions(perms: ReadonlyArray<EfModulePermission>): void;
580
+ /**
581
+ * `null` until the app pushes the user's per-screen grants. While it is
582
+ * `null`, `canScreen` allows everything, so nav behaves as it did before
583
+ * per-screen filtering existed (module level only).
584
+ */
585
+ private readonly _screenGrants;
586
+ /**
587
+ * Replace the per-screen grants (keyed by screen code). Pass `null` to
588
+ * go back to "no grants info"; `{}` means the user has no screen at all.
589
+ */
590
+ setScreenGrants(grants: ScreenGrants | null): void;
591
+ /**
592
+ * Whether the user holds `verb` on the screen `code`. Reads a signal, so
593
+ * it is safe inside `computed()`. Allows everything until grants have
594
+ * been set; after that a screen with no grant is denied.
595
+ */
596
+ canScreen(code: string, verb?: Permissions | string): boolean;
568
597
  /**
569
598
  * The level granted to the current user for a given module.
570
599
  * Returns `'none'` if the module is not in the permission set.
@@ -852,5 +881,61 @@ declare const isMacPlatform: boolean;
852
881
  */
853
882
  declare function formatShortcut(keys: string, mac?: boolean): string;
854
883
 
855
- export { CacheService, ConfirmDialogService, DEFAULT_APP_STATE, EF_BUILD_INFO, EF_MODULES, EF_MODULES_TOKEN, EF_SESSION, EF_TRANSLATE_LOADER_CONFIG, EfActiveModuleService, EfComptoirTheme, EfPermissionService, EfShortcutService, EfTheme, EfThemeConfigService, EfToastService, EfVersionedTranslateLoader, EfViewportService, LoaderService, PRIMENG_AR_LOCALE, PRIMENG_EN_LOCALE, PRIMENG_FR_LOCALE, EfToastService as ToastService, formatShortcut, hasScreenPermission, isMacPlatform, provideEfTranslateLoader, screenGuard };
856
- export type { AppState, EfBuildInfo, EfBuildPackage, EfConfirmIntent, EfConfirmOptions, EfModule, EfModuleId, EfModulePermission, EfNavAction, EfNavItem, EfNavSection, EfPermissionLevel, EfSession, EfShortcut, EfShortcutGroup, EfToast, EfToastAction, EfToastOptions, EfToastSeverity, EfVersionedTranslateLoaderConfig, EfViewport, ScreenGuardConfig };
884
+ /**
885
+ * Where the shell, the theme and data tables keep a viewer's UI preferences
886
+ * (theme state, side-panel fold, table density and hidden columns).
887
+ *
888
+ * The synchronous contract is deliberate: these preferences are read while a
889
+ * component is being built, so the first paint is right. An app that keeps
890
+ * them on a server therefore serves reads from a local cache that it
891
+ * hydrates itself, and sends writes upstream in the background.
892
+ *
893
+ * Keys are the full storage keys, exactly as they are in localStorage today
894
+ * (see {@link efPrefKey} and {@link EF_SIDE_COLLAPSED_KEY}); values are the
895
+ * raw strings stored under them.
896
+ */
897
+ interface EfPreferenceStore {
898
+ /** The stored value, or null when absent or storage is unavailable. */
899
+ get(key: string): string | null;
900
+ /**
901
+ * Consumers may call this with a value the store already holds, and a
902
+ * store that keeps partial values (the theme's AppState) will not match
903
+ * it byte for byte. Server-backed stores should ignore no-op sets
904
+ * (compare the parsed or merged result) rather than issue a request.
905
+ */
906
+ set(key: string, value: string): void;
907
+ remove(key: string): void;
908
+ /**
909
+ * Optional. Emits a key whose value was changed from outside the
910
+ * consumers (for example a server hydrate after sign in), so a consumer
911
+ * that is already alive can re-read it. Must NOT emit for the store's own
912
+ * `set` / `remove` calls. The theme and the app shell follow it (a removed
913
+ * key resets them to defaults; the theme value may be a partial AppState,
914
+ * merged over the live one). ef-data-card reads its key only when it is
915
+ * constructed and ignores it.
916
+ */
917
+ readonly changes?: Observable<string>;
918
+ }
919
+ /** localStorage key of the app-shell side-panel fold ('1' collapsed, '0' open). Not prefixed. */
920
+ declare const EF_SIDE_COLLAPSED_KEY = "ef.shell.side-collapsed";
921
+ /** Key for a preference that StorageUtils has always stored under its prefix (`Elasticias_` by default). */
922
+ declare function efPrefKey(name: string): string;
923
+ /** Prefix of the per-table key family: `efTablePrefsKey(tableKey)` is the full key. */
924
+ declare const EF_TABLE_PREFS_PREFIX = "TABLE_PREFS_";
925
+ /** Full key of one table's density / hidden-columns preference (`Elasticias_TABLE_PREFS_<tableKey>`). */
926
+ declare function efTablePrefsKey(tableKey: string): string;
927
+ /** localStorage, never throwing: a private window or blocked site data just means nothing is remembered. */
928
+ declare class LocalStoragePreferenceStore implements EfPreferenceStore {
929
+ get(key: string): string | null;
930
+ set(key: string, value: string): void;
931
+ remove(key: string): void;
932
+ }
933
+ /**
934
+ * Preference store. Defaults to localStorage with the historical keys, so
935
+ * nothing changes unless an app provides its own:
936
+ * `{ provide: EF_PREFERENCE_STORE, useClass: ServerPreferenceStore }`.
937
+ */
938
+ declare const EF_PREFERENCE_STORE: InjectionToken<EfPreferenceStore>;
939
+
940
+ export { CacheService, ConfirmDialogService, DEFAULT_APP_STATE, EF_BUILD_INFO, EF_MODULES, EF_MODULES_TOKEN, EF_PREFERENCE_STORE, EF_SESSION, EF_SIDE_COLLAPSED_KEY, EF_TABLE_PREFS_PREFIX, EF_TRANSLATE_LOADER_CONFIG, EfActiveModuleService, EfComptoirTheme, EfPermissionService, EfShortcutService, EfTheme, EfThemeConfigService, EfToastService, EfVersionedTranslateLoader, EfViewportService, LoaderService, LocalStoragePreferenceStore, PRIMENG_AR_LOCALE, PRIMENG_EN_LOCALE, PRIMENG_FR_LOCALE, EfToastService as ToastService, efPrefKey, efTablePrefsKey, formatShortcut, hasScreenPermission, isMacPlatform, provideEfTranslateLoader, screenGuard };
941
+ export type { AppState, EfBuildInfo, EfBuildPackage, EfConfirmIntent, EfConfirmOptions, EfModule, EfModuleId, EfModulePermission, EfNavAction, EfNavItem, EfNavSection, EfPermissionLevel, EfPreferenceStore, EfSession, EfShortcut, EfShortcutGroup, EfToast, EfToastAction, EfToastOptions, EfToastSeverity, EfVersionedTranslateLoaderConfig, EfViewport, ScreenGuardConfig };