@elasticias/screens 1.0.39 → 1.0.40

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.
@@ -86,6 +86,15 @@ class ScreenContext extends AbstractEntity {
86
86
  entity;
87
87
  grants;
88
88
  duplicateMode = false;
89
+ /**
90
+ * Whether the screen may write the record it shows, for its current mode.
91
+ * Set by `AbstractDetailScreenV2` to its own `canWrite` signal, so shared
92
+ * components bound to `[context]` (ef-detail-toolbar's Save and its
93
+ * `requiresWrite` custom actions) follow the same rule without each
94
+ * screen passing it again. Undefined on screens that have no write mode
95
+ * (search, report), where those components keep their default behaviour.
96
+ */
97
+ canWrite;
89
98
  constructor(state, group, entity, refDataProvider, bundles, grants, screenName = '', language = 'fr') {
90
99
  super();
91
100
  this.state = state;
@@ -175,6 +184,12 @@ const SCREEN_REF_DATA_SERVICE = new InjectionToken('SCREEN_REF_DATA_SERVICE');
175
184
  class AbstractScreenComponent extends AbstractComponent {
176
185
  context;
177
186
  connectedUser;
187
+ /** V1 only: the NgForm a V1 detail template declares as `#entityForm`.
188
+ * V2 templates bind `[value]` / `(valueChangeEvent)` with no NgForm, so
189
+ * this stays undefined there and everything below that walks it
190
+ * (`disableAllControls`, `setFormErrors`, `isFormValid`) does nothing.
191
+ * V2 screens use `AbstractDetailScreenV2.readOnlyMode()` bound as
192
+ * `[efReadOnly]` on the form container, and `canWrite()` for saving. */
178
193
  entityForm;
179
194
  serverErrors = signal({}, ...(ngDevMode ? [{ debugName: "serverErrors" }] : /* istanbul ignore next */ []));
180
195
  refDataLoaded$ = new Subject();
@@ -196,6 +211,10 @@ class AbstractScreenComponent extends AbstractComponent {
196
211
  this.context.screenName = this.getBundleName();
197
212
  this.processGrants();
198
213
  }
214
+ /** The `isReadOnly()` branch below is the V1 read-only path. It never
215
+ * fires usefully on a V2 screen (see `entityForm`), and its predicate
216
+ * ignores the mode: Read+Create on an existing record counts as
217
+ * writable. V2 detail screens rely on `readOnlyMode()` instead. */
199
218
  ngAfterViewInit() {
200
219
  this.changeDetector.detectChanges();
201
220
  if (this.context && this.context.isReadOnly()) {
@@ -454,6 +473,8 @@ class AbstractScreenComponent extends AbstractComponent {
454
473
  clearServerErrors() {
455
474
  this.serverErrors.set({});
456
475
  }
476
+ /** V1 only: disables the controls of `entityForm`. A no-op on V2
477
+ * screens, which use `readOnlyMode()` + `[efReadOnly]`. */
457
478
  disableAllControls() {
458
479
  setTimeout(() => {
459
480
  if (this.entityForm && Object.keys(this.entityForm.controls).length > 0) {
@@ -1844,7 +1865,13 @@ class AbstractDetailScreenV2 extends AbstractScreenComponent {
1844
1865
  keys: 'mod+s',
1845
1866
  labelKey: 'common_save',
1846
1867
  group: 'shortcut_group_screen',
1847
- handler: () => this.save(),
1868
+ // Gated here as well as inside save(): a subclass that overrides
1869
+ // save() without calling super must still not be reachable from
1870
+ // the keyboard by a user who cannot write.
1871
+ handler: () => {
1872
+ if (this.canWrite())
1873
+ this.save();
1874
+ },
1848
1875
  });
1849
1876
  }
1850
1877
  /**
@@ -1866,6 +1893,36 @@ class AbstractDetailScreenV2 extends AbstractScreenComponent {
1866
1893
  * the `?mode=duplicate` query param.
1867
1894
  */
1868
1895
  duplicateMode = signal(false, ...(ngDevMode ? [{ debugName: "duplicateMode" }] : /* istanbul ignore next */ []));
1896
+ /**
1897
+ * Bumped every time `processGrants()` (re)reads the user's grants.
1898
+ * `context` is a plain object, not a signal, so without this a
1899
+ * `canWrite()` read before the grants arrive would memoize `false`
1900
+ * and the route subscription re-setting `editionState(false)` to the
1901
+ * same value would never invalidate it.
1902
+ */
1903
+ grantsVersion = signal(0, ...(ngDevMode ? [{ debugName: "grantsVersion" }] : /* istanbul ignore next */ []));
1904
+ /**
1905
+ * Whether the user may write the record on screen, for the mode it is
1906
+ * in: an existing record (edit mode, not duplicating) needs Edit; a new
1907
+ * record or a duplicate needs Create. Read is not enough for either,
1908
+ * which is how a Read-only user got a fully editable, savable form.
1909
+ *
1910
+ * Bind its negation on the form container to disable every ef-* control:
1911
+ * `<div class="form" [efReadOnly]="readOnlyMode()">`. ef-detail-toolbar
1912
+ * reads it through `context.canWrite` to hide Save, so screens pass
1913
+ * nothing for that. The backend still enforces the same grants; this is
1914
+ * the UI agreeing with it.
1915
+ */
1916
+ canWrite = computed(() => {
1917
+ this.grantsVersion();
1918
+ const ctx = this.context;
1919
+ if (!ctx)
1920
+ return false;
1921
+ const editingExisting = this.editionState() && !this.duplicateMode();
1922
+ return editingExisting ? ctx.hasEditPermission : ctx.hasCreatePermission;
1923
+ }, ...(ngDevMode ? [{ debugName: "canWrite" }] : /* istanbul ignore next */ []));
1924
+ /** `!canWrite()`, named for the `[efReadOnly]` binding it feeds. */
1925
+ readOnlyMode = computed(() => !this.canWrite(), ...(ngDevMode ? [{ debugName: "readOnlyMode" }] : /* istanbul ignore next */ []));
1869
1926
  /** True while service.get / create / update / delete is in flight. */
1870
1927
  loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
1871
1928
  /** Last load / save error message — empty string when none. */
@@ -1943,6 +2000,18 @@ class AbstractDetailScreenV2 extends AbstractScreenComponent {
1943
2000
  }
1944
2001
  });
1945
2002
  }
2003
+ processGrants() {
2004
+ // Stamp before super: it ends in detectChanges(), which renders an
2005
+ // ef-detail-toolbar bound to this context. A toolbar that first sees
2006
+ // the context without canWrite memoizes "unknown" (Save shown) and,
2007
+ // the context being the same object, never re-reads it.
2008
+ this.context.canWrite = this.canWrite;
2009
+ // Bumped before super too, so the render inside it recomputes
2010
+ // canWrite from the grants super is about to set rather than from a
2011
+ // value memoized on an earlier read.
2012
+ this.grantsVersion.update(v => v + 1);
2013
+ super.processGrants();
2014
+ }
1946
2015
  /**
1947
2016
  * Merge a partial patch into the `entity` signal — the canonical
1948
2017
  * way for form inputs to write back. Spread-immutably so OnPush
@@ -1986,8 +2055,14 @@ class AbstractDetailScreenV2 extends AbstractScreenComponent {
1986
2055
  * Persist the entity. Routes to `service.create()` when in new
1987
2056
  * or duplicate mode, `service.update(id, entity)` when editing.
1988
2057
  * Subclass `beforeSave()` can return `false` to cancel.
2058
+ *
2059
+ * A no-op when `canWrite()` is false, checked before `beforeSave()` so
2060
+ * a screen's validation never toasts at a user who could not save
2061
+ * anyway.
1989
2062
  */
1990
2063
  save() {
2064
+ if (!this.canWrite())
2065
+ return;
1991
2066
  const proceed = this.beforeSave();
1992
2067
  if (proceed === false)
1993
2068
  return;
@@ -2039,6 +2114,8 @@ class AbstractDetailScreenV2 extends AbstractScreenComponent {
2039
2114
  return undefined;
2040
2115
  }
2041
2116
  delete() {
2117
+ if (!this.context?.hasDeletePermission)
2118
+ return;
2042
2119
  const id = this.entityId();
2043
2120
  if (!id) {
2044
2121
  this.recordNotFound();
@@ -2069,8 +2146,12 @@ class AbstractDetailScreenV2 extends AbstractScreenComponent {
2069
2146
  * via `service.create()` after the user hits Save.
2070
2147
  * Without the id, the duplicate route would have nothing to
2071
2148
  * fetch — `entity` would be empty and the clone-as-template
2072
- * flow would fall back to creating a blank record. */
2149
+ * flow would fall back to creating a blank record.
2150
+ * Needs Create: a duplicate is saved through `service.create()`, so
2151
+ * opening one without Create would only lead to a read-only form. */
2073
2152
  duplicate() {
2153
+ if (!this.context?.hasCreatePermission)
2154
+ return;
2074
2155
  const id = this.entityId();
2075
2156
  const base = this.detailsBaseUrl();
2076
2157
  if (id == null) {
@@ -1 +1 @@
1
- {"version":3,"file":"elasticias-screens.mjs","sources":["../../../../libs/screens/src/lib/abstract/abstract.entity.ts","../../../../libs/screens/src/lib/abstract/abstract.component.ts","../../../../libs/screens/src/lib/config/screen-context.ts","../../../../libs/screens/src/lib/services/screen-reference-data.service.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-screen.component.ts","../../../../libs/screens/src/lib/config/screen-state.enum.ts","../../../../libs/screens/src/lib/entities/view-model.entity.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-detail-screen.component.ts","../../../../libs/screens/src/lib/entities/search.entity.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-search-screen.component.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-search-screen-v2.component.ts","../../../../libs/screens/src/lib/services/audit-history.service.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-detail-screen-v2.component.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-report-screen-v2.component.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-sub-screen.component.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-sub-screen-v2.component.ts","../../../../libs/screens/src/lib/config/screen-config.ts","../../../../libs/screens/src/index.ts","../../../../libs/screens/src/elasticias-screens.ts"],"sourcesContent":["export abstract class AbstractEntity {\n [key: string]: unknown;\n clone(entity: AbstractEntity): AbstractEntity {\n for (const field of Reflect.ownKeys(entity)) {\n if ((this as Record<string | symbol, unknown>)[field] == null) {\n (this as Record<string | symbol, unknown>)[field] = (entity as unknown as Record<string | symbol, unknown>)[field];\n }\n }\n return this;\n }\n\n newClone(): Record<string, unknown> {\n const cloneObj: Record<string, unknown> = {};\n for (const field of Reflect.ownKeys(this)) {\n cloneObj[field as string] = (this as Record<string | symbol, unknown>)[field];\n }\n return cloneObj;\n }\n\n update(entity: Record<string, unknown>): AbstractEntity {\n for (const field of Reflect.ownKeys(entity)) {\n if ((this as Record<string | symbol, unknown>)[field] != null) {\n (this as Record<string | symbol, unknown>)[field] = entity[field as string];\n }\n }\n return this;\n }\n\n buildEntity(entity: Record<string, unknown>): void {\n Object.keys(entity).forEach((key) => {\n (this as Record<string, unknown>)[key] = entity[key];\n });\n }\n\n clearFields(): void {\n for (const field of Reflect.ownKeys(this)) {\n (this as Record<string | symbol, unknown>)[field] = null;\n }\n }\n}\n","import { Component, Input, OnDestroy, OnInit } from '@angular/core';\nimport { PersistedState, PersistedStateOptions } from '@elasticias/utils';\nimport { Subject } from 'rxjs';\n\n@Component({ template: '' })\nexport abstract class AbstractComponent implements OnInit, OnDestroy {\n @Input() readOnly = false;\n protected destroyed$ = new Subject<void>();\n\n abstract ngOnInit(): void;\n abstract ngOnDestroy(): void;\n\n /**\n * Declare a piece of this component's state that should survive a page\n * refresh — an active period, a chosen tab, a collapsed rail.\n *\n * Nothing is read or written until the returned handle is used, so\n * calling this costs nothing and adds no storage dependency to\n * components that never touch it. Keep the key stable across releases\n * and namespaced to the screen, and pass `revive` for any shape holding\n * a `Date`: JSON hands those back as strings.\n *\n * ```ts\n * private readonly rail = this.persisted<boolean>('SALES_RAIL_OPEN');\n * ngOnInit() { this.open.set(this.rail.read() ?? true); }\n * ```\n */\n protected persisted<T>(key: string, options?: PersistedStateOptions<T>): PersistedState<T> {\n return new PersistedState<T>(key, options);\n }\n}\n","import { Signal, signal } from '@angular/core';\nimport { AbstractEntity } from '../abstract/abstract.entity';\nimport { Permissions } from '@elasticias/types';\n\n/**\n * Abstract interface for reference data providers.\n * Apps must implement this and provide it to ScreenContext.\n */\nexport interface ReferenceDataProvider {\n getReference(key: string): Signal<any[]>;\n hasReference(key: string): boolean;\n}\n\nexport class ScreenContext extends AbstractEntity {\n state: string;\n screenName!: string;\n language: string;\n group: unknown;\n private _refDataProvider?: ReferenceDataProvider;\n bundles: Map<string, Map<string, Map<string, string>>>;\n entity: unknown;\n grants: string[];\n duplicateMode = false;\n\n constructor(\n state: string,\n group?: unknown,\n entity?: unknown,\n refDataProvider?: ReferenceDataProvider,\n bundles?: Map<string, Map<string, Map<string, string>>>,\n grants?: string[],\n screenName = '',\n language = 'fr'\n ) {\n super();\n this.state = state;\n this.group = group;\n this.entity = entity;\n this.screenName = screenName;\n this.language = language;\n this._refDataProvider = refDataProvider;\n this.bundles = bundles ?? new Map();\n this.grants = grants ?? [];\n }\n\n setReferenceDataProvider(provider: ReferenceDataProvider): void {\n this._refDataProvider = provider;\n }\n\n get ref() {\n return {\n get: (key: string): Signal<any[]> => {\n if (!this._refDataProvider) {\n console.warn('ReferenceDataProvider not set in ScreenContext. Returning empty signal.');\n return signal([]);\n }\n return this._refDataProvider.getReference(key);\n },\n has: (key: string): boolean => {\n return this._refDataProvider?.hasReference(key) ?? false;\n },\n };\n }\n\n getLabel(key: string): string {\n try {\n return this.bundles.get(this.language)!.get(this.screenName)!.get(key) ?? key;\n } catch {\n return key;\n }\n }\n\n isGranted(permission: Permissions): boolean {\n return this.grants?.some((value) => value === permission) ?? false;\n }\n\n /* ── Permission convenience getters ───────────────────────────────\n Shared components (ef-row-actions, ef-data-card auto actions cell,\n toolbars) read these to default-show / default-hide CRUD buttons\n against the current user's grants without re-importing\n Permissions at every call site. */\n\n get hasReadPermission(): boolean {\n return this.isGranted(Permissions.Read);\n }\n\n get hasCreatePermission(): boolean {\n return this.isGranted(Permissions.Create);\n }\n\n get hasEditPermission(): boolean {\n return this.isGranted(Permissions.Edit);\n }\n\n get hasDeletePermission(): boolean {\n return this.isGranted(Permissions.Delete);\n }\n\n get hasDuplicatePermission(): boolean {\n return this.isGranted(Permissions.Duplicate);\n }\n\n get hasPrintPermission(): boolean {\n return this.isGranted(Permissions.Print);\n }\n\n get hasExportPermission(): boolean {\n return this.isGranted(Permissions.Export);\n }\n\n get hasImportPermission(): boolean {\n return this.isGranted(Permissions.Import);\n }\n\n isReadOnly(): boolean {\n return (\n this.isGranted(Permissions.Read) &&\n !this.isGranted(Permissions.Create) &&\n !this.isGranted(Permissions.Edit) &&\n !this.isGranted(Permissions.Delete)\n );\n }\n}\n","import { InjectionToken, Signal } from '@angular/core';\nimport { ReferenceDataProvider } from '../config/screen-context';\nimport { LoadOptions } from '../config/screen-config';\n\n/**\n * Abstract interface for reference data services used by screen components.\n * Apps must implement this interface and provide it via SCREEN_REF_DATA_SERVICE token.\n *\n * Extends ReferenceDataProvider (getReference/hasReference for ScreenContext)\n * with methods for loading, refreshing, and invalidating reference data.\n */\nexport interface ScreenReferenceDataService extends ReferenceDataProvider {\n /**\n * Load dynamic reference data by keys\n * @param keys Array of reference data keys to load\n * @param options Optional load options (bypassCache, ttl, forceRefresh)\n */\n loadReferenceKeys(keys: string[], options?: LoadOptions): Promise<void>;\n\n /**\n * Load static reference data by type names\n * @param types Array of static reference type names\n * @param forceRefresh Force reload from server\n */\n loadStaticRefs(types: string[], forceRefresh?: boolean): Promise<void>;\n\n /**\n * Refresh reference data keys (force reload from server)\n * @param keys Array of keys to refresh\n * @param bypassCache Bypass cache entirely\n */\n refreshKeys(keys: string[], bypassCache?: boolean): Promise<void>;\n\n /**\n * Invalidate reference data keys (mark as stale)\n * @param keys Array of keys to invalidate\n */\n invalidateKeys(keys: string[]): Promise<void>;\n}\n\n/**\n * Injection token for the screen reference data service.\n * Apps must provide this token with their concrete implementation.\n *\n * @example\n * // In app module or component providers:\n * { provide: SCREEN_REF_DATA_SERVICE, useExisting: ReferenceDataService }\n */\nexport const SCREEN_REF_DATA_SERVICE = new InjectionToken<ScreenReferenceDataService>(\n 'SCREEN_REF_DATA_SERVICE'\n);\n","import { AfterViewInit, ChangeDetectorRef, Component, inject, Input, OnDestroy, OnInit, signal, ViewChild } from '@angular/core';\nimport { AbstractComponent } from '../abstract.component';\nimport { ScreenContext } from '../../config/screen-context';\nimport { ScreenConfig, LoadOptions } from '../../config/screen-config';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { NgForm } from '@angular/forms';\nimport { AppUtils, PersistedState, StorageUtils } from '@elasticias/utils';\nimport { EfDatePresetKey, EfDateRange } from '../../entities/date-range.entity';\nimport { Permissions } from '@elasticias/types';\nimport { ToastService, ConfirmDialogService, CacheService } from '@elasticias/core';\nimport { Subject } from 'rxjs';\nimport { ScreenReferenceDataService, SCREEN_REF_DATA_SERVICE } from '../../services/screen-reference-data.service';\n\n@Component({\n template: ''\n})\nexport abstract class AbstractScreenComponent extends AbstractComponent implements OnInit, AfterViewInit, OnDestroy {\n @Input() context!: ScreenContext;\n connectedUser: any;\n\n @ViewChild('entityForm') entityForm!: NgForm;\n serverErrors = signal<{ [key: string]: string[] }>({});\n protected refDataLoaded$ = new Subject<void>();\n\n cacheService = inject(CacheService);\n changeDetector = inject(ChangeDetectorRef);\n toastService = inject(ToastService);\n confirmDialogService = inject(ConfirmDialogService);\n router = inject(Router);\n route = inject(ActivatedRoute);\n refDataService = inject(SCREEN_REF_DATA_SERVICE);\n\n currentUrl = '';\n\n protected abstract readonly screenState: string | null;\n get state(): string | null { return this.screenState; }\n screenStateKey = '';\n\n ngOnInit(): void {\n this.cacheService.configure(true);\n this.currentUrl = this.router.url;\n this.context = new ScreenContext(this.screenState ?? '', undefined, undefined, this.refDataService);\n\n this.screenStateKey = `SCREEN_STATE_${this.screenState}_${this.getBundleName()}`;\n this.context.screenName = this.getBundleName();\n this.processGrants();\n }\n\n ngAfterViewInit(): void {\n this.changeDetector.detectChanges();\n if (this.context && this.context.isReadOnly()) {\n this.disableAllControls();\n }\n }\n\n processGrants() {\n const userGrants: any = AbstractScreenComponent.readGrants();\n if (userGrants && userGrants[this.context.screenName] && userGrants[this.context.screenName].permissions) {\n this.context.grants = userGrants[this.context.screenName].permissions;\n } else {\n this.context.grants = [];\n }\n this.changeDetector.detectChanges();\n }\n\n isFormValid(): boolean {\n if (this.context.isReadOnly()) { return true; }\n if (!this.entityForm) {\n return false;\n }\n return this.entityForm.valid ?? false;\n }\n\n getConfig(): any {\n return null;\n }\n\n /**\n * Read a query param from the activated route's snapshot. Shared\n * accessor for deep-links on both search and detail screens (e.g.\n * `?status=PendingApproval`, `?mode=duplicate`) so screens don't\n * reach into `route.snapshot.queryParamMap` themselves.\n */\n protected queryParam(name: string): string | null {\n return this.route.snapshot.queryParamMap.get(name);\n }\n\n /**\n * Grant check for ANY screen (not just this one's `SCREEN` code) —\n * e.g. an operational strip or report widget calling a\n * differently-gated endpoint. For this screen's own grants prefer\n * `context.isGranted(...)`.\n */\n protected hasGrant(screen: string, permission: Permissions): boolean {\n const grants = AbstractScreenComponent.readGrants();\n return !!grants?.[screen]?.permissions?.includes(permission);\n }\n\n /**\n * Screen grants, read from wherever the host app put them.\n *\n * Apps store these per tab in sessionStorage (they are refetched on a timer\n * and must not outlive the tab), so sessionStorage is checked first. The\n * localStorage fallback keeps apps working that persist them there instead.\n *\n * Reading only localStorage silently yielded `null` for every screen, which\n * left `context.grants` empty and hid every permission-gated control -- the\n * New and Export buttons and the row actions -- on every screen at once.\n */\n protected static readGrants(): Record<\n string,\n { permissions?: string[] }\n > | null {\n return (\n StorageUtils.getSession<Record<string, { permissions?: string[] }>>(\n 'CURRENT_USER_GRANTS',\n ) ??\n StorageUtils.getLocal<Record<string, { permissions?: string[] }>>(\n 'CURRENT_USER_GRANTS',\n )\n );\n }\n\n getBundleName(): string {\n const config = this.getConfig();\n if (config) {\n return config.SCREEN;\n } else {\n console.error('getConfig() method should be implemented !!');\n }\n return '';\n }\n\n setFormErrors(errors: { [key: string]: string[] }) {\n if (!errors || !this.entityForm) { return; }\n\n Object.keys(errors).forEach((field) => {\n const camelCaseField = AppUtils.toCamelCase(field);\n const control = this.entityForm.controls[camelCaseField];\n\n if (control) {\n control.setErrors({ serverError: errors[field] });\n control.markAsTouched();\n }\n });\n }\n\n referentialKeys: any;\n staticListKeys: string[] = [];\n\n initializeReferenceKeys(keys: string[]): void {\n if (!keys) return;\n const referencialKeys: any = {};\n\n keys.forEach(p => {\n referencialKeys[p] = {};\n });\n\n this.referentialKeys = referencialKeys;\n }\n\n initializeStaticLists(keys: string[]): void {\n if (!keys) return;\n this.staticListKeys = keys;\n }\n\n async loadReferenceData(options?: LoadOptions) {\n const loadPromises: Promise<void>[] = [];\n\n if (!AppUtils.isNullOrEmpty(this.referentialKeys)) {\n const dynamicKeys = Object.keys(this.referentialKeys);\n\n const dynamicPromise = this.refDataService\n .loadReferenceKeys(dynamicKeys, options)\n .catch((error: unknown) => {\n console.error('Failed to load dynamic reference data:', error);\n });\n\n loadPromises.push(dynamicPromise);\n }\n\n if (this.staticListKeys && this.staticListKeys.length > 0) {\n const staticPromise = this.refDataService\n .loadStaticRefs(this.staticListKeys)\n .catch((error: unknown) => {\n console.error('Failed to load static lists:', error);\n });\n\n loadPromises.push(staticPromise);\n }\n\n if (loadPromises.length === 0) {\n this.refDataLoaded$.next();\n return;\n }\n\n try {\n await Promise.all(loadPromises);\n this.refDataLoaded$.next();\n } catch (error) {\n console.error('Failed to load reference data:', error);\n this.refDataLoaded$.next();\n }\n }\n\n async refreshReferenceData(keys?: string[]) {\n const keysToRefresh = keys || Object.keys(this.referentialKeys || {});\n\n if (keysToRefresh.length === 0) {\n return;\n }\n\n try {\n await this.refDataService.refreshKeys(keysToRefresh, true);\n this.toastService.showSuccess('Reference data refreshed successfully', 'Success');\n } catch (error) {\n console.error('Failed to refresh reference data:', error);\n this.toastService.showError('Failed to refresh reference data', 'Error');\n }\n }\n\n async refreshStaticLists() {\n if (!this.staticListKeys || this.staticListKeys.length === 0) {\n return;\n }\n\n try {\n await this.refDataService.loadStaticRefs(this.staticListKeys, true);\n this.toastService.showSuccess('Static lists refreshed successfully', 'Success');\n } catch (error) {\n console.error('Failed to refresh static lists:', error);\n this.toastService.showError('Failed to refresh static lists', 'Error');\n }\n }\n\n async invalidateReference(key: string) {\n await this.refDataService.invalidateKeys([key]);\n }\n\n async invalidateReferences(keys: string[]) {\n await this.refDataService.invalidateKeys(keys);\n }\n\n /** The record the user acted on carries no id — it was removed by someone\n * else, the list is stale, or the route points at nothing. Say that,\n * rather than the internal \"Item [id] is undefined!\" this used to ship\n * to end users. Lives on the common base so every screen abstract\n * (search, detail and sub in V1 and V2, plus report-v2) says the same\n * thing — four copies of one string is how this file set drifts. */\n protected recordNotFound(): void {\n this.toastService.show({ severity: 'error', textKey: 'ef_error_record_not_found' });\n }\n\n handleErrors(errors: string[]) {\n if (errors && errors.length > 0) {\n errors.forEach(error => this.toastService.showError(error, 'Erreur de validation'));\n } else {\n this.toastService.showError('Une erreur inconnue est survenue', 'Erreur');\n }\n }\n\n setServerErrors(errors: { [key: string]: string[] }) {\n // Backend (FluentValidation) keys are PascalCase (e.g. `ClientType`);\n // template field bindings and the camelCased `setFormErrors` path use\n // camelCase. Normalize here so screens can read `serverErrors()['clientType']`\n // and pass it straight to an `ef-*` control's `[errors]` input.\n const normalized: { [key: string]: string[] } = {};\n if (errors) {\n Object.keys(errors).forEach((key) => {\n normalized[AppUtils.toCamelCase(key)] = errors[key];\n });\n }\n this.serverErrors.set(normalized);\n }\n\n /* ── Persisted date range ───────────────────────────────────────\n Opt-in. A screen that wants its period to survive a refresh\n calls `restorePersistedDateRange()` once, before its first\n load, and `persistDateRange()` from `onDateRangeChange()`.\n `AbstractReportScreenV2` already does both; list screens can\n opt in the same way. */\n\n private _dateRangeState?: PersistedState<EfDateRange>;\n\n /** Storage key for the persisted period. Namespaced by the screen\n * code so two dashboards never share a period. */\n protected dateRangeStateKey(): string {\n return `SCREEN_DATE_RANGE_${this.getConfig()?.SCREEN ?? 'UNKNOWN'}`;\n }\n\n protected dateRangeState(): PersistedState<EfDateRange> {\n return (this._dateRangeState ??= this.persisted<EfDateRange>(this.dateRangeStateKey(), {\n revive: raw => AbstractScreenComponent.reviveDateRange(raw),\n }));\n }\n\n /**\n * The period to open on: the one the user last chose, or `fallback`\n * when there is nothing stored.\n *\n * A relative preset is recomputed rather than replayed — someone who\n * picked \"This month\" in September and comes back in October means\n * October, not a frozen September window. Only `'custom'` restores\n * the literal dates, which is the case that has no other meaning.\n * Pass `fromPreset` (a screen's own preset resolver) to get that;\n * without it, a stored preset falls back to the default.\n */\n protected restorePersistedDateRange(\n fallback: EfDateRange,\n fromPreset?: (key: EfDatePresetKey) => EfDateRange,\n ): EfDateRange {\n const stored = this.dateRangeState().read();\n if (!stored) return fallback;\n if (stored.presetKey === 'custom') return stored;\n return fromPreset ? fromPreset(stored.presetKey) : fallback;\n }\n\n protected persistDateRange(range: EfDateRange): void {\n this.dateRangeState().write(range);\n }\n\n protected clearPersistedDateRange(): void {\n this.dateRangeState().clear();\n }\n\n /** JSON gives back ISO strings; hand back real `Date`s or nothing. */\n private static reviveDateRange(raw: unknown): EfDateRange | null {\n const v = raw as Partial<EfDateRange> | null;\n if (!v || typeof v !== 'object' || !v.presetKey) return null;\n const start = new Date(v.start as unknown as string);\n const end = new Date(v.end as unknown as string);\n if (isNaN(start.getTime()) || isNaN(end.getTime())) return null;\n return {\n start,\n end,\n presetKey: v.presetKey,\n label: v.label ?? '',\n labelKey: v.labelKey,\n };\n }\n\n clearServerErrors() {\n this.serverErrors.set({});\n }\n\n disableAllControls() {\n setTimeout(() => {\n if (this.entityForm && Object.keys(this.entityForm.controls).length > 0) {\n const controlNames = Object.keys(this.entityForm.controls);\n controlNames.forEach(controlName => {\n const control = this.entityForm.controls[controlName];\n if (control) {\n control.disable();\n }\n });\n }\n }, 10);\n }\n}\n","export enum ScreenStateEnum {\n READ_ONLY = 'READ_ONLY',\n DETAIL = 'DETAIL',\n SEARCH = 'SEARCH',\n CUSTOM = 'CUSTOM',\n REPORT = 'REPORT',\n}\n\nexport enum StateUtilsEnum {\n REMOVE = 'removeState',\n ADD = 'addState',\n DUPLICATE = 'duplicateState',\n EDIT = 'editState',\n EDIT_AFTER_ERROR = 'editAfterErrorState',\n ADD_AFTER_ERROR = 'addAfterErrorState',\n SAVE = 'afterSaveState',\n}\n","import { AbstractEntity } from '../abstract/abstract.entity';\n\nexport class ViewModelEntity extends AbstractEntity {\n constructor(entity: Record<string, unknown>) {\n super();\n this.clone(entity as unknown as AbstractEntity);\n }\n}\n","import {\n AfterViewInit,\n Component,\n inject,\n Injector,\n OnDestroy,\n OnInit,\n} from '@angular/core';\nimport { ScreenStateEnum } from '../../config/screen-state.enum';\nimport { ViewModelEntity } from '../../entities/view-model.entity';\nimport { AbstractScreenComponent } from './abstract-screen.component';\nimport { Location } from '@angular/common';\nimport { combineLatest } from 'rxjs';\n\n@Component({\n template: '',\n})\nexport abstract class AbstractDetailScreenComponent\n extends AbstractScreenComponent\n implements AfterViewInit, OnInit, OnDestroy\n{\n protected readonly screenState = ScreenStateEnum.DETAIL;\n\n entity: any = {};\n entityId: any;\n editionState = false;\n duplicateMode = false;\n\n private location = inject(Location);\n protected injector = inject(Injector);\n private serviceInstance: any;\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.serviceInstance = this.injector.get(this.getConfig()!.SERVICE as any);\n\n const screenConfig = this.getConfig();\n if (screenConfig) {\n const hasDynamicRefs = (screenConfig.DETAILS_REFERENTIALS_KEYS?.length ?? 0) > 0;\n const hasStaticLists = (screenConfig.DETAILS_STATIC_LISTS?.length ?? 0) > 0;\n\n if (hasDynamicRefs) {\n this.initializeReferenceKeys(screenConfig.DETAILS_REFERENTIALS_KEYS);\n }\n if (hasStaticLists) {\n this.initializeStaticLists(screenConfig.DETAILS_STATIC_LISTS);\n }\n if (hasDynamicRefs || hasStaticLists) {\n this.loadReferenceData(screenConfig.REF_DATA_OPTIONS);\n }\n }\n }\n\n override ngAfterViewInit(): void {\n super.ngAfterViewInit();\n combineLatest([this.route.paramMap, this.route.queryParamMap]).subscribe(\n ([params, queryParams]) => {\n this.entityId = params.get('id');\n this.duplicateMode = queryParams.get('mode') === 'duplicate';\n this.context.duplicateMode = this.duplicateMode;\n\n if (this.entityId) {\n this.editionState = !this.duplicateMode;\n this.loadData();\n } else {\n this.editionState = false;\n this.duplicateMode = false;\n this.context.duplicateMode = false;\n }\n },\n );\n }\n\n public loadData(): void {\n try {\n this.serviceInstance.get(this.entityId).subscribe({\n next: (result: any) => {\n this.entity = new ViewModelEntity(result);\n this.entity.id = this.entityId;\n this.afterLoad();\n },\n error: (_error: any) => {\n // Errors handled by global error handler\n },\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n protected afterLoad() {\n this.changeDetector.detectChanges();\n }\n\n abstract beforeSave(): void;\n\n save() {\n try {\n this.beforeSave();\n this.clearServerErrors();\n\n const isCreateOperation = !this.editionState || this.duplicateMode;\n const entityToSave = this.duplicateMode\n ? this.prepareEntityForDuplication()\n : this.entity;\n\n const saveOperation = isCreateOperation\n ? this.serviceInstance.create(entityToSave)\n : this.serviceInstance.update(this.entityId, this.entity);\n\n saveOperation.subscribe({\n next: (response: any) => {\n if (response && response.errors && response.errors.length > 0) {\n this.handleErrors(response.errors);\n } else {\n this.toastService.showSuccess();\n this.afterSave(response);\n }\n },\n error: (response: any) => {\n console.log(response);\n if (response.errors) {\n this.setServerErrors(response.errors);\n this.setFormErrors(response.errors);\n this.onSaveError(response.errors);\n }\n },\n });\n } catch (error: any) {\n this.toastService.showError(\n error?.message || \"Une erreur est survenue lors de l'enregistrement\",\n );\n }\n }\n\n protected onSaveError(_errors: { [key: string]: string[] }) {\n // Override in subclass to handle validation errors\n }\n\n protected afterSave(result: any) {\n const screenConfig = this.getConfig();\n if (screenConfig?.INVALIDATE_KEYS_ON_SAVE) {\n this.invalidateReferences(screenConfig.INVALIDATE_KEYS_ON_SAVE);\n\n if (screenConfig.REFRESH_ON_SAVE) {\n this.refreshReferenceData(screenConfig.INVALIDATE_KEYS_ON_SAVE);\n }\n }\n\n if (!this.editionState || this.duplicateMode) {\n const baseUrl = this.currentUrl.split('?')[0];\n const detailsIndex = baseUrl.indexOf('/details');\n const cleanBaseUrl =\n detailsIndex !== -1\n ? baseUrl.substring(0, detailsIndex + '/details'.length)\n : baseUrl;\n this.router.navigate([cleanBaseUrl, result]);\n return;\n }\n }\n\n protected prepareEntityForDuplication(): any {\n const duplicatedEntity = { ...this.entity };\n delete duplicatedEntity.id;\n delete duplicatedEntity.Id;\n return this.customizeDuplicatedEntity(duplicatedEntity);\n }\n\n protected customizeDuplicatedEntity(entity: any): any {\n return entity;\n }\n\n duplicate() {\n const baseUrl = this.currentUrl.split('?')[0];\n this.router.navigate([baseUrl], {\n queryParams: { mode: 'duplicate' },\n });\n }\n\n print() {\n // Override in subclass to implement print functionality\n }\n\n /**\n * Name of the record being deleted, so the confirmation can say what\n * it is about to destroy rather than asking about \"this item\".\n * Override in the screen and return whatever a user recognises the\n * record by — `return this.entity?.name;` is the usual body.\n */\n protected getDeleteConfirmName(): string | undefined {\n return undefined;\n }\n\n delete(): void {\n if (!this.entityId) {\n this.recordNotFound();\n return;\n }\n\n this.confirmDialogService.confirm({\n intent: 'delete',\n name: this.getDeleteConfirmName(),\n accept: () =>\n this.serviceInstance.delete(this.entityId).subscribe({\n next: (result: any) => {\n if (result && result.errors && result.errors.length > 0) {\n this.handleErrors(result.errors);\n } else {\n this.toastService.showSuccess();\n this.navigateBack();\n }\n },\n error: () => {\n // Errors handled by global error handler\n },\n }),\n });\n }\n\n navigateBack() {\n const currentUrl = this.router.url.split('?')[0];\n const detailsIndex = currentUrl.indexOf('/details');\n if (detailsIndex !== -1) {\n this.router.navigate([currentUrl.substring(0, detailsIndex)]);\n } else {\n this.location.back();\n }\n }\n}\n","import { AbstractEntity } from '../abstract/abstract.entity';\n\nexport enum SortDirectionEnum {\n ASC = 'Ascending',\n DESC = 'Descending',\n DEFAULT_SORT_FIELD = 'id',\n}\n\nexport enum PaginationEnum {\n DEFAULT_PAGE = 1,\n DEFAULT_PAGE_SIZE = 10,\n}\n\nexport class SearchEntity extends AbstractEntity {\n pagination: { pageNumber: number; pageSize: number } = {\n pageNumber: PaginationEnum.DEFAULT_PAGE,\n pageSize: PaginationEnum.DEFAULT_PAGE_SIZE,\n };\n\n sort: Array<{ field: string; sortDirection: string }> = [];\n\n totalPages = 0;\n totalCount = 0;\n items: AbstractEntity[] = [];\n start: Date | null = null;\n end: Date | null = null;\n startEndDateRanges: Date[] | null = null;\n\n constructor(entity: Record<string, unknown>) {\n super();\n this.buildEntity(entity);\n\n if (!this.pagination) {\n this.pagination = {\n pageNumber: PaginationEnum.DEFAULT_PAGE,\n pageSize: PaginationEnum.DEFAULT_PAGE_SIZE,\n };\n }\n\n if (!this.sort) {\n this.sort = [{ field: SortDirectionEnum.DEFAULT_SORT_FIELD, sortDirection: SortDirectionEnum.DESC }];\n }\n\n if (!this.startEndDateRanges && entity['start'] && entity['end']) {\n this.startEndDateRanges = [new Date(entity['start'] as string), new Date(entity['end'] as string)];\n }\n }\n\n getSearchCriteria(): Record<string, unknown> {\n const { items: _items, totalPages: _totalPages, totalCount: _totalCount, ...criteria } = this;\n return criteria;\n }\n}\n","import {\n AfterViewInit,\n Component,\n inject,\n Injector,\n OnDestroy,\n OnInit,\n ViewChild,\n} from '@angular/core';\nimport { ScreenStateEnum } from '../../config/screen-state.enum';\nimport { ViewModelEntity } from '../../entities/view-model.entity';\nimport { SearchEntity, SortDirectionEnum } from '../../entities/search.entity';\nimport { AbstractScreenComponent } from './abstract-screen.component';\nimport { Table, TableLazyLoadEvent } from 'primeng/table';\nimport { take } from 'rxjs';\n\n/**\n * Column definition interface for ef-datatable integration.\n * Kept minimal here to avoid circular dependency on @elasticias/ui.\n */\nexport interface ScreenDatatableColumn {\n field: string;\n header: string;\n type?: string;\n [key: string]: any;\n}\n\n@Component({\n template: '',\n standalone: true,\n})\nexport abstract class AbstractSearchScreenComponent\n extends AbstractScreenComponent\n implements AfterViewInit, OnInit, OnDestroy\n{\n protected readonly screenState = ScreenStateEnum.SEARCH;\n\n @ViewChild('pTable') pTable!: Table;\n\n entity: any = new ViewModelEntity({});\n searchEntity = new SearchEntity(this.entity);\n enableDateRangeFilter = true;\n isLazySearch = true;\n lastSearchEvent: TableLazyLoadEvent | null = null;\n\n tableColumns: any[] = [];\n\n protected injector = inject(Injector);\n private serviceInstance: any;\n private isInitialLoad = true;\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.serviceInstance = this.injector.get(this.getConfig()!.SERVICE as any);\n\n this.tableColumns = this.getTableColumns();\n\n const screenConfig = this.getConfig();\n const hasDynamicRefs = (screenConfig?.SEARCH_REFERENTIALS_KEYS?.length ?? 0) > 0;\n const hasStaticLists = (screenConfig?.SEARCH_STATIC_LISTS?.length ?? 0) > 0;\n\n if (hasDynamicRefs || hasStaticLists) {\n if (hasDynamicRefs) {\n this.initializeReferenceKeys(screenConfig!.SEARCH_REFERENTIALS_KEYS);\n }\n\n if (hasStaticLists) {\n this.initializeStaticLists(screenConfig!.SEARCH_STATIC_LISTS);\n }\n\n this.loadReferenceData(screenConfig!.REF_DATA_OPTIONS);\n\n this.refDataLoaded$.pipe(take(1)).subscribe(() => {\n this.triggerSearchIfNeeded();\n });\n } else {\n this.triggerSearchIfNeeded();\n }\n }\n\n protected getTableColumns(): any[] {\n return [];\n }\n\n private triggerSearchIfNeeded() {\n const cachedCriteria = this.cacheService.getCache<any>(this.screenStateKey);\n if (cachedCriteria) {\n this.searchEntity = new SearchEntity(cachedCriteria);\n this.entity.buildEntity(this.searchEntity);\n this.searchEntity.items = [];\n\n if (this.searchEntity.startEndDateRanges) {\n this.entity.startEndDateRanges = [\n new Date(this.searchEntity.start!),\n new Date(this.searchEntity.end!),\n ];\n }\n\n this.changeDetector.detectChanges();\n this.search();\n } else {\n this.search();\n }\n }\n\n onLazyLoad(event: TableLazyLoadEvent): void {\n if (this.isInitialLoad) {\n this.isInitialLoad = false;\n return;\n }\n\n if (this.isReactiveBindingEcho(event)) {\n return;\n }\n\n this.search(event);\n }\n\n private isReactiveBindingEcho(event: TableLazyLoadEvent): boolean {\n if (!this.searchEntity.sort || this.searchEntity.sort.length === 0) {\n return false;\n }\n\n const currentSort = this.searchEntity.sort[0];\n const eventSortField = Array.isArray(event.sortField)\n ? event.sortField[0]\n : event.sortField;\n const eventSortDirection =\n event.sortOrder === 1 ? SortDirectionEnum.ASC : SortDirectionEnum.DESC;\n\n const currentPage = this.searchEntity.pagination?.pageNumber || 1;\n const currentPageSize = this.searchEntity.pagination?.pageSize || 10;\n const eventPage = this.getPageNumber(event);\n const eventPageSize = event.rows || 10;\n\n return (\n currentSort.field === eventSortField &&\n currentSort.sortDirection === eventSortDirection &&\n currentPage === eventPage &&\n currentPageSize === eventPageSize\n );\n }\n\n private prepareSearch(event: TableLazyLoadEvent | null): void {\n this.searchEntity.buildEntity(this.entity);\n const e = event || this.lastSearchEvent || { first: 0, rows: 10 };\n\n this.searchEntity.pagination = {\n pageNumber: this.getPageNumber(e),\n pageSize: e.rows || 10,\n };\n\n if (this.entity.startEndDateRanges) {\n this.searchEntity.start = this.entity.startEndDateRanges[0];\n this.searchEntity.end = this.entity.startEndDateRanges[1];\n } else {\n this.searchEntity.start = null;\n this.searchEntity.end = null;\n }\n\n if (this.isLazySearch) {\n if (e.sortField) {\n const sortField = this.getSortField(e);\n this.searchEntity.sort = [\n {\n field: sortField,\n sortDirection: this.getSortDirection(e),\n },\n ];\n } else if (!this.searchEntity.sort || this.searchEntity.sort.length === 0) {\n const defaultSort = this.getConfig()?.DEFAULT_SORT;\n this.searchEntity.sort = [\n {\n field: defaultSort?.field || 'id',\n sortDirection: defaultSort?.direction || SortDirectionEnum.DESC,\n },\n ];\n }\n }\n }\n\n protected search(event: TableLazyLoadEvent | null = null): void {\n this.prepareSearch(event);\n\n this.serviceInstance.search(this.searchEntity).subscribe({\n next: (result: any) => {\n this.lastSearchEvent = event;\n this.searchEntity = Object.assign(new SearchEntity({}), this.searchEntity, result);\n this.cacheService.setCache(this.screenStateKey, this.searchEntity);\n this.changeDetector.detectChanges();\n },\n error: () => {\n // Errors handled by global error handler\n },\n });\n }\n\n paginate(event: any) {\n const pageNumber = this.getPageNumber(event);\n const pageSize = event.rows;\n\n this.searchEntity.pagination.pageNumber = pageNumber;\n this.searchEntity.pagination.pageSize = pageSize;\n\n if (\n this.searchEntity.items == null ||\n this.searchEntity.items.length === 0\n ) {\n return;\n }\n }\n\n getPageNumber(event: TableLazyLoadEvent): number {\n return event.first != null\n ? Math.floor(event.first / (event.rows || 10)) + 1\n : 1;\n }\n\n getSortField(event: TableLazyLoadEvent): string {\n return Array.isArray(event.sortField)\n ? event.sortField[0]\n : event.sortField || 'id';\n }\n\n getSortDirection(event: TableLazyLoadEvent): string {\n return event.sortOrder === 1\n ? SortDirectionEnum.ASC\n : SortDirectionEnum.DESC;\n }\n\n navigateToDetails(id?: any): void {\n const path =\n id || id === 0\n ? `${this.currentUrl}/details/${id}`\n : `${this.currentUrl}/details`;\n this.router.navigate([path]);\n }\n\n add() {\n this.router.navigate([this.currentUrl.concat('/details')]);\n }\n\n edit(id: any) {\n if (!id) {\n this.recordNotFound();\n return;\n }\n this.router.navigate([this.currentUrl.concat('/details/'), id]);\n }\n\n /**\n * Name of the row being deleted, so the confirmation can say what it\n * is about to destroy rather than asking about \"this item\". Override\n * in the screen — look the row up in the loaded results and return\n * whatever a user would recognise it by.\n *\n * ```ts\n * protected override getDeleteConfirmName(id: any) {\n * return this.searchEntity.items?.find((r: any) => r.id === id)?.name;\n * }\n * ```\n */\n protected getDeleteConfirmName(_id: any): string | undefined {\n return undefined;\n }\n\n delete(id: any): void {\n if (!id) {\n this.recordNotFound();\n return;\n }\n\n this.confirmDialogService.confirm({\n intent: 'delete',\n name: this.getDeleteConfirmName(id),\n accept: () =>\n this.serviceInstance.delete(id).subscribe({\n next: (result: any) => {\n if (result && result.errors && result.errors.length > 0) {\n this.handleErrors(result.errors);\n } else {\n this.search();\n this.toastService.showSuccess();\n }\n },\n error: () => {\n // Errors handled by global error handler\n },\n }),\n });\n }\n\n duplicate(id: any) {\n if (!id) {\n this.recordNotFound();\n return;\n }\n this.router.navigate(\n [this.currentUrl.concat('/details/'), id],\n { queryParams: { mode: 'duplicate' } }\n );\n }\n\n clear(): void {\n this.entity.clearFields();\n this.searchEntity.clearFields();\n this.searchEntity = new SearchEntity({});\n\n this.lastSearchEvent = null;\n this.isInitialLoad = true;\n\n this.cacheService.setCache(this.screenStateKey, this.searchEntity);\n\n if (this.pTable) {\n this.pTable.first = 0;\n this.pTable.reset();\n }\n\n this.changeDetector.detectChanges();\n }\n\n ngOnDestroy(): void {\n this.destroyed$.next();\n this.destroyed$.complete();\n }\n}\n","import {\n Component,\n computed,\n inject,\n Injector,\n OnDestroy, OnInit,\n signal,\n} from '@angular/core';\nimport { take } from 'rxjs';\nimport { AbstractScreenComponent } from './abstract-screen.component';\nimport { ScreenStateEnum } from '../../config/screen-state.enum';\nimport { ActiveFilter } from '../../entities/active-filter.entity';\nimport { CsvUtils } from '@elasticias/utils';\nimport { TranslateService } from '@ngx-translate/core';\nimport {\n EfDataCardColumn,\n EfDataCardExportRequest,\n EfDataCardSort,\n EfReferenceColumnOpts,\n} from '../../entities/data-card-column.entity';\nimport { EfDateRange } from '../../entities/date-range.entity';\nimport {\n PaginationEnum,\n SearchEntity,\n SortDirectionEnum,\n} from '../../entities/search.entity';\n\n/**\n * Declarative definition of an advanced-search select filter rendered in\n * the filter drawer. One `<ef-select>` is rendered per entry; the screen\n * stays type-agnostic — `key` is simply the criteria property name sent to\n * the backend (which must expose a matching typed query prop, e.g.\n * `CityIds: List<int>`, `ClientIds: List<string>`, a scalar code, …). Works\n * for both single-select (`multiple` omitted/false → scalar value) and\n * multi-select (`multiple: true` → array value).\n */\nexport interface AdvancedSelectFilter {\n /** Criteria property name sent to the backend (must match a typed query prop). */\n key: string;\n /** Reference-data key supplying the options (e.g. `'cities'`). */\n refKey: string;\n /** i18n key for the field label (rendered by `ef-select`). */\n labelKey: string;\n /** Multi-select when `true` (array value); single-select otherwise (scalar). */\n multiple?: boolean;\n /** Option value field (default `'code'`). */\n valueField?: string;\n /** Option label field (default `'label'`). */\n labelField?: string;\n /** Placeholder i18n key (default `'common_all'`). */\n placeholderKey?: string;\n}\n\n/**\n * Signal-first counterpart to {@link AbstractSearchScreenComponent}.\n *\n * Built for V2 + zoneless apps: state is exposed as signals\n * (`items`, `loading`, `errorMsg`, `totalCount`, `criteria`) and the\n * class is intentionally **decoupled from PrimeNG `<p-table>`** —\n * subclasses render however they want (Comptoir `.tbl` patterns,\n * cards, virtual lists, …) and call the helpers below to mutate the\n * search criteria + re-execute.\n *\n * Same `ScreenConfig` surface as the legacy abstract:\n * - `SCREEN` (string code matching backend grants)\n * - `SERVICE` (NSwag client class with `search(criteria)` method)\n * - `SEARCH_REFERENTIALS_KEYS` / `SEARCH_STATIC_LISTS` for ref-data\n * - `DEFAULT_SORT` for first load\n *\n * Subclasses typically:\n *\n * ```ts\n * @Component({ ... })\n * export class FooComponent extends AbstractSearchScreenV2<FooDto> {\n * protected override getConfig() { return FooConfig; }\n * readonly rows = computed(() => this.items().map(toRow));\n * }\n * ```\n */\n@Component({ template: '', standalone: true })\nexport abstract class AbstractSearchScreenV2<TItem = any>\n extends AbstractScreenComponent\n implements OnInit\n{\n protected readonly screenState = ScreenStateEnum.SEARCH;\n protected readonly injector = inject(Injector);\n private serviceInstance: any;\n\n /**\n * Translate lazily, through the injector.\n *\n * Taking `TranslateService` as a field injection makes it a hard\n * construction-time requirement of every screen that extends this base,\n * which is more than the one method needing it deserves — and it is the\n * same shape as the DI cycle ADR-021 records in the app. Resolving it\n * here keeps the dependency optional: an app without ngx-translate gets\n * the key back rather than a crash.\n */\n protected t(key: string, params?: Record<string, unknown>): string {\n const translate = this.injector.get(TranslateService, null);\n return translate ? translate.instant(key, params) : key;\n }\n\n /** Monotonic guard: bumped on every `search()` call so an\n * out-of-order (stale) response from an earlier search can be\n * dropped instead of overwriting the latest results. */\n private searchSeq = 0;\n\n /** Current search results — populated after each `search()`. */\n readonly items = signal<TItem[]>([]);\n readonly totalCount = signal(0);\n readonly loading = signal(false);\n readonly errorMsg = signal<string | null>(null);\n\n /** Live search criteria (paging, sort, text, dates, custom). */\n readonly criteria = signal<SearchEntity>(new SearchEntity({}));\n\n /**\n * Active date-range filter shown in `ef-datepicker-advanced`'s\n * trigger. Display-only at construction time — actually filters\n * the search once `onDateRangeChange()` fires (or a screen wires\n * one in `ngOnInit`).\n *\n * Override `buildDefaultDateRange()` per screen to ship a\n * different starting preset.\n */\n readonly dateRange = signal<EfDateRange>(this.buildDefaultDateRange());\n\n /* ── Filter-bar UI state (DRY) ──────────────────────────────────\n Identical across every list screen — lifted up so subclasses\n don't re-declare. `clear()` resets all four signals. */\n\n /** Free-text search input value — bound `[(searchText)]` on\n * ef-smart-bar; drives `runSearch()`. */\n readonly searchQuery = signal('');\n\n /** Active status pill-group selection (defaults to `'all'`). */\n readonly statusFilter = signal<string>('all');\n\n /** Whether the advanced-filter drawer is open. */\n readonly drawerOpen = signal(false);\n\n /** Active named filter chips shown in the smart-bar. */\n readonly activeFilters = signal<ActiveFilter[]>([]);\n\n /* ── Advanced-filter selects (DRY) ──────────────────────────────\n Declarative `<ef-select>` filters rendered in the filter drawer.\n Override `advancedFilters` per screen; the base owns the value\n state, the apply→criteria push, and the reset. Type-agnostic:\n each `key` maps to a typed backend query prop of any shape. */\n\n /** Advanced-filter select definitions. Empty = no advanced filters. */\n readonly advancedFilters: AdvancedSelectFilter[] = [];\n\n /** Criteria key of the screen's activation tri-state filter\n * (`ef-activation-filter`), e.g. `'isActive'`. When set, the base\n * applies, baseline-clears, and cache-restores the boolean like any\n * declared advanced filter — the screen only binds the component to\n * `advancedValues()` / `setAdvancedValue()`. `null` = no activation\n * filter. */\n protected readonly activationFilterKey: string | null = null;\n\n /** Live values per advanced filter, keyed by `AdvancedSelectFilter.key`. */\n readonly advancedValues = signal<Record<string, unknown>>({});\n\n /** Store the picked value(s) for one advanced filter (no search yet —\n * the drawer's `(apply)` runs it). */\n setAdvancedValue(key: string, value: unknown): void {\n this.advancedValues.update((v) => ({ ...v, [key]: value }));\n }\n\n /** Push every advanced-filter value into the criteria as typed\n * top-level props and re-run the search. Wired to the drawer's\n * `(apply)`. Every DECLARED key is written on apply — a cleared\n * control must actively remove its (possibly cache-restored)\n * criteria value, not silently leave it behind. */\n applyAdvancedFilters(): void {\n const patch: Record<string, any> = {};\n for (const f of this.advancedFilters) patch[f.key] = undefined;\n if (this.activationFilterKey) patch[this.activationFilterKey] = undefined;\n Object.assign(patch, this.advancedValues());\n this.patchCriteria(patch);\n }\n\n /* ── Selection (DRY) ────────────────────────────────────────────\n Per-row checkbox state, used by `ef-bulk-bar` and the auto\n row-actions cell. */\n\n /** Selected row ids — keyed by `String(rowId(row))`. */\n readonly selected = signal<ReadonlySet<string>>(new Set());\n\n /** Live count derived from `selected`. */\n readonly selectionCount = computed(() => this.selected().size);\n\n /* ── Sort indicator (DRY) ───────────────────────────────────────\n ef-data-card consumes `[sort]` as `{ field, direction: 'asc' |\n 'desc' }`. The base criteria stores the legacy\n 'Ascending' / 'Descending' strings — convert lazily here. */\n\n readonly currentSort = computed<EfDataCardSort | null>(() => {\n const s = this.criteria().sort?.[0];\n if (!s?.field) return null;\n return {\n field: s.field,\n direction: (s.sortDirection ?? '').toLowerCase().startsWith('asc')\n ? 'asc'\n : 'desc',\n };\n });\n\n /* ── Row-actions standard surface ───────────────────────────────\n Subclasses can flip these off when a particular CRUD action\n isn't applicable. Defaults are all-on; permission filtering\n still happens at render time via ScreenContext, so an action\n that the user can't perform is hidden regardless of these\n flags. */\n\n readonly showViewAction = signal(true);\n readonly showEditAction = signal(true);\n readonly showDuplicateAction = signal(true);\n readonly showDeleteAction = signal(true);\n\n /**\n * PK accessor for a row. Default returns `row?.id` — override when\n * the backend names its primary key something else (e.g. sales-orders'\n * `orderId`). Used by the row-actions dispatcher and as the implicit\n * navigateToDetails / edit / delete argument.\n */\n rowId(row: any): any {\n return row?.id;\n }\n\n /**\n * Dispatch helper wired to ef-data-card's `(rowAction)` output and\n * the auto-rendered row-actions cell. Routes the standard four\n * actions to the inherited methods so subclasses don't have to\n * declare per-screen rowActions arrays.\n */\n onRowAction(\n action: 'view' | 'edit' | 'duplicate' | 'delete',\n row: any,\n ): void {\n const id = this.rowId(row);\n switch (action) {\n case 'view':\n this.navigateToDetails(id);\n break;\n case 'edit':\n this.edit(id);\n break;\n case 'duplicate':\n this.duplicate(id);\n break;\n case 'delete':\n this.delete(id);\n break;\n }\n }\n\n /* ── Date-range filter (DRY) ────────────────────────────────────\n Wired to ef-datepicker-advanced. The default range is\n `last_30_days` — override `buildDefaultDateRange()` per screen\n if a different starting preset is needed. */\n\n /**\n * Wired to `<ef-datepicker-advanced (rangeChange)>` — stores the\n * range for trigger display and pushes it into the search criteria\n * so the next `search()` filters by it.\n */\n onDateRangeChange(range: EfDateRange): void {\n this.dateRange.set(range);\n this.setDateRange(range.start, range.end);\n }\n\n /**\n * Reset the date range to the default. Called automatically by\n * `clear()` so screens don't have to remember to invoke it from\n * their own `clearAll()` orchestration.\n */\n protected resetDateRange(): void {\n this.dateRange.set(this.buildDefaultDateRange());\n }\n\n /**\n * Build the default `EfDateRange`. Override per screen to ship a\n * different default — e.g., a 90-day window for low-velocity\n * catalogues. Default: last 30 days.\n */\n protected buildDefaultDateRange(): EfDateRange {\n return {\n start: this.daysAgo(29),\n end: this.startOfToday(),\n presetKey: 'last_30_days',\n labelKey: 'date_preset_last_30_days',\n label: '30 derniers jours',\n };\n }\n\n /** Today at 00:00 local time. */\n protected startOfToday(): Date {\n const d = new Date();\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n }\n\n /** N days before today, at 00:00 local time. */\n protected daysAgo(n: number): Date {\n const t = this.startOfToday();\n t.setDate(t.getDate() - n);\n return t;\n }\n\n /* ── Filter-bar handlers (DRY) ──────────────────────────────────\n Wired to ef-smart-bar / pill-group / filter-drawer / chip\n removal. None of these need overriding — subclasses use them\n through inherited template bindings. */\n\n /** Wired to filter-drawer's `(apply)` — pushes the current\n * searchQuery into the criteria and re-runs the search. */\n runSearch(): void {\n this.setSearchText(this.searchQuery());\n }\n\n /** Pill-group click handler. Stores the selected status code; the\n * search itself only re-runs once the consumer pushes the value\n * into the criteria (or wires it via beforeSearch). */\n setStatus(key: string): void {\n this.statusFilter.set(key);\n }\n\n toggleDrawer(): void {\n this.drawerOpen.update((o) => !o);\n }\n\n /** Drop a chip from the active-filters list. */\n removeFilter(key: string): void {\n this.activeFilters.update((filters) =>\n filters.filter((f) => f.key !== key),\n );\n }\n\n /* ── Selection helpers (DRY) ────────────────────────────────────\n Mutate `selected` (Set<string>); template binds via\n `[checked]=\"isSelected(rowId(row))\"` and\n `(change)=\"toggleSelection(rowId(row))\"`. */\n\n toggleSelection(id: string): void {\n this.selected.update((set) => {\n const next = new Set(set);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }\n\n /** Toggle every visible row in or out of the selection in one shot. */\n toggleAllSelection(): void {\n const all = this.items().map((item) => String(this.rowId(item)));\n this.selected.update((set) =>\n set.size === all.length ? new Set() : new Set(all),\n );\n }\n\n isSelected(id: string): boolean {\n return this.selected().has(id);\n }\n\n /* ── Column builders (DRY) ──────────────────────────────────────\n Convenience helpers that return a fully-formed EfDataCardColumn\n with sensible per-type defaults. Pass `opts` to override any\n property — `opts` always wins over the builder's defaults. */\n\n /** Selection checkbox column — paired with `efColumnTemplate=\"select\"`\n * for the row's checkbox. 40px wide, no other props. */\n protected addSelectColumn(width = '40px'): EfDataCardColumn {\n return { id: 'select', width };\n }\n\n /** Plain text column. */\n protected addTextColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return { id: field, ...opts, field, headerKey, type: 'text' };\n }\n\n /** Monospace column — JetBrains Mono with tabular-nums; for codes,\n * IDs, refs, anything where character alignment matters. */\n protected addMonoColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return { id: field, ...opts, field, headerKey, type: 'mono' };\n }\n\n /** Number column — end-aligned, integer by default. Override\n * `minFractionDigits` / `maxFractionDigits` via opts for decimals. */\n protected addNumberColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return {\n id: field,\n minFractionDigits: 0,\n maxFractionDigits: 0,\n ...opts,\n field,\n headerKey,\n type: 'number',\n align: opts.align ?? 'end',\n };\n }\n\n /** Money column — end-aligned. ISO currency code defaults to `'MAD'`\n * (Elasticias' primary tenant locale); pass `opts.currencyCode` for\n * euros / USD / etc. */\n protected addMoneyColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return {\n id: field,\n currencyCode: 'MAD',\n ...opts,\n field,\n headerKey,\n type: 'money',\n align: opts.align ?? 'end',\n };\n }\n\n /** Date column — formats as `dd/MM/yyyy` by default. */\n protected addDateColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return { id: field, ...opts, field, headerKey, type: 'date' };\n }\n\n /** Datetime column — formats as `dd/MM/yyyy HH:mm` by default. */\n protected addDatetimeColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return { id: field, ...opts, field, headerKey, type: 'datetime' };\n }\n\n /** Boolean column — renders the `bool yes / bool no` indicator. */\n protected addBooleanColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return { id: field, ...opts, field, headerKey, type: 'boolean' };\n }\n\n /** Static-class chip column — renders `chip <chipPrefix><value>`.\n * Use `addStatusColumn` for reference_data-driven palettes. */\n protected addChipColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return {\n id: field,\n chipPrefix: 'chip-',\n ...opts,\n field,\n headerKey,\n type: 'chip',\n };\n }\n\n /** Status chip column — palette + label resolved from\n * `reference_data` via `referenceKey`. Sortable by default. */\n protected addStatusColumn(\n field: string,\n headerKey: string,\n referenceKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return {\n id: field,\n sortable: true,\n ...opts,\n field,\n headerKey,\n type: 'status',\n referenceKey,\n };\n }\n\n /** Reference column — looks up `field`'s value in the reference\n * list keyed by `referenceKey`, renders the matching item's label.\n * Defaults: `valueField: 'id'`, `labelField: 'label'`. */\n protected addReferenceColumn(\n field: string,\n headerKey: string,\n referenceKey: string,\n opts: EfReferenceColumnOpts = {},\n ): EfDataCardColumn {\n const { valueField, labelField, ...rest } = opts;\n return {\n id: field,\n ...rest,\n field,\n headerKey,\n type: 'reference',\n referenceKey,\n referenceValueField: valueField ?? rest.referenceValueField ?? 'code',\n referenceLabelField: labelField ?? rest.referenceLabelField ?? 'label',\n };\n }\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.serviceInstance = this.injector.get(this.getConfig()!.SERVICE as any);\n\n const cfg = this.getConfig();\n const hasDynamicRefs = (cfg?.SEARCH_REFERENTIALS_KEYS?.length ?? 0) > 0;\n const hasStaticLists = (cfg?.SEARCH_STATIC_LISTS?.length ?? 0) > 0;\n\n // Busy from the first frame, not from the first request.\n //\n // A screen with referentials waits for them before it searches at all, and\n // `loading` used to stay false for that entire window — so the table spent\n // it showing \"nothing here yet\" to someone whose data was still being\n // fetched. Six of the twelve list screens take that branch, including the\n // one where this was measured at 910ms. `search()` sets the same flag\n // again when it finally runs, so setting it here is idempotent.\n this.loading.set(true);\n\n if (hasDynamicRefs || hasStaticLists) {\n if (hasDynamicRefs)\n this.initializeReferenceKeys(cfg!.SEARCH_REFERENTIALS_KEYS);\n if (hasStaticLists) this.initializeStaticLists(cfg!.SEARCH_STATIC_LISTS);\n this.loadReferenceData(cfg!.REF_DATA_OPTIONS);\n this.refDataLoaded$.pipe(take(1)).subscribe(() => {\n this.bootstrapInitialSearch();\n this.applyDeepLinkStatus();\n });\n } else {\n this.bootstrapInitialSearch();\n this.applyDeepLinkStatus();\n }\n }\n\n /**\n * Deep-link support: `/<list>?status=<code>` pre-selects the status\n * pill after the initial criteria bootstrap (so the reset doesn't\n * clobber it). Runs through `setStatus()`, so a subclass override\n * that pushes the status into the criteria (the usual pattern) gets\n * the deep-linked value too. No-op without the query param.\n */\n private applyDeepLinkStatus(): void {\n const status = this.queryParam('status');\n if (status) this.setStatus(status);\n }\n\n /** Restore criteria from cache (returning to a screen) or seed defaults. */\n private bootstrapInitialSearch(): void {\n const cached = this.cacheService.getCache<any>(this.screenStateKey);\n if (cached) {\n this.criteria.set(new SearchEntity(cached));\n this.restoreFilterUiFromCriteria(cached);\n } else {\n const cfg = this.getConfig();\n const fresh = new SearchEntity({});\n if (cfg?.DEFAULT_SORT) {\n fresh.sort = [\n {\n field: cfg.DEFAULT_SORT.field,\n sortDirection: cfg.DEFAULT_SORT.direction,\n },\n ];\n }\n fresh.pagination = {\n pageNumber: PaginationEnum.DEFAULT_PAGE,\n pageSize: PaginationEnum.DEFAULT_PAGE_SIZE,\n };\n this.criteria.set(fresh);\n }\n this.search();\n }\n\n /**\n * Cache-restore sync: when a revisit restores cached criteria,\n * reflect the restored filters back into the filter-bar UI state so\n * what the drawer / search box displays matches what the search will\n * actually send (otherwise a stale criteria filter keeps applying\n * while every control reads \"Tous\"). Base handles the free-text\n * input and the declared advanced filters; override (calling super)\n * to sync screen-specific state — status pill, custom switches, ….\n */\n protected restoreFilterUiFromCriteria(cached: Record<string, any>): void {\n this.searchQuery.set(cached['searchText'] ?? '');\n const next: Record<string, unknown> = {};\n for (const f of this.advancedFilters) {\n const value = cached[f.key];\n if (value !== undefined && value !== null) next[f.key] = value;\n }\n const activationKey = this.activationFilterKey;\n if (activationKey && typeof cached[activationKey] === 'boolean') {\n next[activationKey] = cached[activationKey];\n }\n if (Object.keys(next).length) {\n this.advancedValues.update((cur) => ({ ...cur, ...next }));\n }\n }\n\n /**\n * Run a search with the current `criteria()`. Always populates\n * `items` / `totalCount` / `loading` / `errorMsg` and persists the\n * criteria to cache on success so revisits can restore.\n */\n search(): void {\n this.loading.set(true);\n this.errorMsg.set(null);\n\n // Stale responses are dropped so the latest issued search always\n // wins, even if an earlier in-flight search resolves later.\n const seq = ++this.searchSeq;\n\n this.serviceInstance.search(this.criteria()).subscribe({\n next: (result: any) => {\n if (seq !== this.searchSeq) return;\n this.items.set((result?.items ?? []) as TItem[]);\n this.totalCount.set(result?.totalCount ?? 0);\n this.cacheService.setCache(this.screenStateKey, this.criteria());\n this.loading.set(false);\n },\n error: (err: any) => {\n if (seq !== this.searchSeq) return;\n console.error('Search failed', err);\n this.errorMsg.set(err?.message ?? 'Erreur de chargement');\n this.loading.set(false);\n },\n });\n }\n\n /* ── Convenience criteria mutators ───────────────────────────── */\n\n setSearchText(text: string): void {\n this.criteria.update((c) =>\n this.cloneCriteria(c, { searchText: text || undefined, page: 1 }),\n );\n this.search();\n }\n\n setPage(pageNumber: number, pageSize?: number): void {\n this.criteria.update((c) =>\n this.cloneCriteria(c, {\n page: pageNumber,\n pageSize: pageSize ?? c.pagination.pageSize,\n }),\n );\n this.search();\n }\n\n setSort(field: string, direction: string = SortDirectionEnum.DESC): void {\n // Normalize `'asc' | 'desc'` (ef-data-card emits these) to the\n // backend's legacy `'Ascending' | 'Descending'` strings, so\n // subclasses don't need to override `setSort` just for that.\n const normalized = (direction || '').toLowerCase().startsWith('asc')\n ? 'Ascending'\n : 'Descending';\n this.criteria.update((c) =>\n this.cloneCriteria(c, { sort: [{ field, sortDirection: normalized }] }),\n );\n this.search();\n }\n\n setDateRange(start: Date | null, end: Date | null): void {\n this.criteria.update((c) => this.cloneCriteria(c, { start, end, page: 1 }));\n this.search();\n }\n\n /** Patch arbitrary extra fields onto the criteria (for module-specific filters). */\n patchCriteria(patch: Record<string, any>): void {\n this.criteria.update((c) =>\n this.cloneCriteria(c, { extra: patch, page: 1 }),\n );\n this.search();\n }\n\n /** Reset everything to defaults and re-fetch. Subclasses bind this\n * to ef-smart-bar's `(clear)` output directly — no per-screen\n * `clearAll()` orchestration needed. */\n clear(): void {\n const cfg = this.getConfig();\n const fresh = new SearchEntity({});\n if (cfg?.DEFAULT_SORT) {\n fresh.sort = [\n {\n field: cfg.DEFAULT_SORT.field,\n sortDirection: cfg.DEFAULT_SORT.direction,\n },\n ];\n }\n this.criteria.set(fresh);\n\n // Reset all the shared filter-bar / selection signals so\n // subclasses don't have to track each one individually.\n this.searchQuery.set('');\n this.statusFilter.set('all');\n this.drawerOpen.set(false);\n this.activeFilters.set([]);\n this.advancedValues.set({});\n this.selected.set(new Set());\n this.resetDateRange();\n\n this.cacheService.setCache(this.screenStateKey, fresh);\n this.search();\n }\n\n /* ── CSV export ───────────────────────────────────────────────── */\n\n /**\n * Rows fetched per request while exporting.\n *\n * `PaginationCriteriaValidator` caps PageSize at 100, but no ERP search\n * query currently subclasses `PaginationQueryValidator`, so nothing\n * enforces it today. 100 is therefore the documented contract rather\n * than a wall: staying inside it keeps the export honest if the\n * validator is ever wired up, and keeps one request from asking a Mongo\n * collection for twenty thousand documents at once.\n */\n private static readonly EXPORT_PAGE_SIZE = 100;\n\n /**\n * Upper bound on an export. A tenant with 20k orders would otherwise\n * fire 200 sequential requests on one click. When the result set is\n * larger, the file holds the first `EXPORT_MAX_ROWS` and the user is\n * told so rather than handed a silently truncated file.\n */\n private static readonly EXPORT_MAX_ROWS = 5000;\n\n readonly exporting = signal(false);\n\n /**\n * Write the current result set to a CSV, honouring the active search,\n * filters and sort, with the columns the viewer can actually see.\n *\n * The card raises this because Export lives beside Density and Columns —\n * all three act on the result set — but only the screen knows the query,\n * so the fetching happens here.\n */\n exportCsv(request: EfDataCardExportRequest): void {\n if (this.exporting()) return;\n\n const columns = request.columns.filter((c) => c.exportable !== false);\n if (columns.length === 0) {\n // Returning quietly here would make Export a control that looks\n // like it acts and does not, which is the exact failure the inert\n // bulk bars were removed for.\n this.toastService.showInfo(this.t('common_export_no_columns'));\n return;\n }\n\n this.exporting.set(true);\n void this.collectExportRows()\n .then(({ rows, truncated }) => {\n if (rows.length === 0) {\n this.toastService.showInfo(this.t('common_export_empty'));\n return;\n }\n\n const flattened = rows.map((row) => {\n const record: Record<string, unknown> = {};\n for (const col of columns) {\n record[col.id] = request.resolveCell(row, col);\n }\n return record;\n });\n\n const csv = CsvUtils.toCsv(\n flattened,\n columns.map((col) => ({\n key: col.id,\n header: col.headerKey ? this.t(col.headerKey) : (col.header ?? col.id),\n })),\n );\n\n CsvUtils.download(this.exportFileName(), csv);\n\n if (truncated) {\n this.toastService.showInfo(\n this.t('common_export_truncated', {\n count: AbstractSearchScreenV2.EXPORT_MAX_ROWS,\n }),\n );\n }\n })\n .catch(() => this.toastService.showError(this.t('common_export_failed')))\n .finally(() => this.exporting.set(false));\n }\n\n /** Page through the current criteria until the result set is exhausted. */\n private async collectExportRows(): Promise<{ rows: any[]; truncated: boolean }> {\n const pageSize = AbstractSearchScreenV2.EXPORT_PAGE_SIZE;\n const max = AbstractSearchScreenV2.EXPORT_MAX_ROWS;\n const rows: any[] = [];\n let page = 1;\n\n for (;;) {\n const criteria = this.cloneCriteria(this.criteria(), { page, pageSize });\n const result: any = await new Promise((resolve, reject) =>\n this.serviceInstance\n .search(criteria)\n .pipe(take(1))\n .subscribe({ next: resolve, error: reject }),\n );\n\n const batch: any[] = result?.items ?? [];\n rows.push(...batch);\n\n const total: number = result?.totalCount ?? rows.length;\n if (rows.length >= max) return { rows: rows.slice(0, max), truncated: total > max };\n if (batch.length < pageSize || rows.length >= total) return { rows, truncated: false };\n page += 1;\n }\n }\n\n\n /** `<screen>-YYYY-MM-DD-HHmm.csv`, so repeated exports do not collide. */\n private exportFileName(): string {\n const d = new Date();\n const pad = (n: number) => String(n).padStart(2, '0');\n const stamp =\n `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` +\n `-${pad(d.getHours())}${pad(d.getMinutes())}`;\n const screen = (this.getConfig()?.SCREEN ?? 'export').toString().toLowerCase();\n return `${screen}-${stamp}.csv`;\n }\n\n private cloneCriteria(\n c: SearchEntity,\n patch: {\n searchText?: string | undefined;\n page?: number;\n pageSize?: number;\n sort?: SearchEntity['sort'];\n start?: Date | null;\n end?: Date | null;\n extra?: Record<string, any>;\n },\n ): SearchEntity {\n const next = new SearchEntity({});\n Object.assign(next, c);\n if ('searchText' in patch) (next as any).searchText = patch.searchText;\n if (patch.page !== undefined || patch.pageSize !== undefined) {\n next.pagination = {\n pageNumber: patch.page ?? c.pagination.pageNumber,\n pageSize: patch.pageSize ?? c.pagination.pageSize,\n };\n }\n if (patch.sort !== undefined) next.sort = patch.sort;\n if (patch.start !== undefined) next.start = patch.start;\n if (patch.end !== undefined) next.end = patch.end;\n if (patch.extra) Object.assign(next, patch.extra);\n return next;\n }\n\n /* ── Navigation helpers ─────────────────────────────────────────\n V2 routing convention (matches v1):\n /<list>/details → AbstractDetailScreenV2 in create mode\n /<list>/details/:id → AbstractDetailScreenV2 in edit mode\n /<list>/details/:id?mode=duplicate → duplicate-as-template\n\n `currentUrl` cached on `AbstractScreenComponent.ngOnInit` is\n not reliable (Router.url isn't committed yet during route\n activation, so it holds the previous URL). Read `router.url`\n at call time via `resolveListUrl()` instead. */\n\n /** Resolve the list-screen URL at call time. Drops query / fragment\n * and strips a trailing slash. */\n protected resolveListUrl(): string {\n let url = this.router.url || this.currentUrl || '';\n const q = url.indexOf('?');\n if (q >= 0) url = url.slice(0, q);\n const h = url.indexOf('#');\n if (h >= 0) url = url.slice(0, h);\n return url.replace(/\\/$/, '');\n }\n\n navigateToDetails(id?: any): void {\n const base = `${this.resolveListUrl()}/details`;\n if (id == null && id !== 0) {\n this.router.navigate([base]);\n return;\n }\n this.router.navigate([base, id]);\n }\n\n /** Open the create form. */\n add(): void {\n this.router.navigate([`${this.resolveListUrl()}/details`]);\n }\n\n edit(id: any): void {\n if (!id) {\n this.recordNotFound();\n return;\n }\n this.router.navigate([`${this.resolveListUrl()}/details`, id]);\n }\n\n /**\n * Name of the row being deleted, so the confirmation can say what it\n * is about to destroy — \"Delete ANDALOCY PARFUMS?\" rather than\n * \"Delete?\". Override in the screen; returning `undefined` keeps the\n * generic message, which still reads correctly.\n *\n * ```ts\n * protected override getDeleteConfirmName(id: any) {\n * return this.items().find(r => r.id === id)?.name;\n * }\n * ```\n */\n protected getDeleteConfirmName(_id: any): string | undefined {\n return undefined;\n }\n\n delete(id: any): void {\n if (!id) {\n this.recordNotFound();\n return;\n }\n this.confirmDialogService.confirm({\n intent: 'delete',\n name: this.getDeleteConfirmName(id),\n accept: () =>\n this.serviceInstance.delete(id).subscribe({\n next: (result: any) => {\n if (result?.errors?.length) {\n this.handleErrors(result.errors);\n } else {\n this.search();\n this.toastService.showSuccess();\n }\n },\n // The HTTP error interceptor surfaces the message (toast). Swallow\n // here so a rejected delete (e.g. a 422 business-rule violation)\n // doesn't bubble up as an unhandled error.\n error: () => undefined,\n }),\n });\n }\n\n duplicate(id: any): void {\n if (!id) {\n this.recordNotFound();\n return;\n }\n this.router.navigate([`${this.resolveListUrl()}/details`, id], {\n queryParams: { mode: 'duplicate' },\n });\n }\n\n // AbstractComponent declares `abstract ngOnDestroy()`, so this must exist.\n // There is genuinely nothing to tear down here; removing it would push the\n // requirement onto every consumer component.\n // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method\n ngOnDestroy(): void {\n // Subclasses can override to clean up subscriptions; nothing to\n // tear down on the base since search subscriptions auto-complete.\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport { Observable } from 'rxjs';\n\n/**\n * Abstract contract for the change-history (audit trail) backend client used by\n * {@link AbstractDetailScreenV2}. Apps provide their NSwag-generated `AuditClient`\n * via the {@link AUDIT_HISTORY_SERVICE} token — kept abstract so `@elasticias/screens`\n * stays decoupled from any app's generated API client.\n */\nexport interface AuditHistoryService {\n /**\n * Fetch the change-history for a single record, newest first.\n * @param entityType Stable backend entity type discriminator (e.g. `'Client'`).\n * @param id Record identifier.\n */\n get(entityType: string, id: string): Observable<any[]>;\n}\n\n/**\n * Injection token for the change-history client. Provide it once at app root:\n *\n * @example\n * { provide: AUDIT_HISTORY_SERVICE, useExisting: AuditClient }\n *\n * Detail screens then only declare `static AUDIT_ENTITY_TYPE = 'Client'` on\n * their config — {@link AbstractDetailScreenV2} loads the history automatically\n * into its `auditEntries` signal.\n */\nexport const AUDIT_HISTORY_SERVICE = new InjectionToken<AuditHistoryService>(\n 'AUDIT_HISTORY_SERVICE'\n);\n","import {\n Component,\n DestroyRef,\n Injector,\n OnDestroy, OnInit,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { Location } from '@angular/common';\nimport { combineLatest } from 'rxjs';\nimport { EfShortcutService } from '@elasticias/core';\nimport { AbstractScreenComponent } from './abstract-screen.component';\nimport { ScreenStateEnum } from '../../config/screen-state.enum';\nimport { EfDetailToolbarAction } from '../../entities/detail-toolbar-action.entity';\nimport { ViewModelEntity } from '../../entities/view-model.entity';\nimport { AUDIT_HISTORY_SERVICE } from '../../services/audit-history.service';\n\n/**\n * Signal-first counterpart to {@link AbstractDetailScreenComponent}.\n *\n * Same business mechanism as v1 but signal-based and zoneless-friendly:\n * `entity` / `entityId` / `editionState` / `duplicateMode` / `loading`\n * / `errorMsg` are all writable signals.\n *\n * Routing convention (V2):\n * - `/<resource>/details` → new (create mode, `editionState=false`)\n * - `/<resource>/details/:id` → edit mode (loads via `service.get(id)`)\n * - `/<resource>/details/:id?mode=duplicate` → loads then strips id on save\n *\n * The same component handles all three paths — the route param +\n * `mode` query string drives the state. After a successful create\n * (or duplicate-save), the screen navigates to\n * `/<resource>/details/<new-id>` so the user lands in edit mode.\n *\n * Subclasses typically override:\n * - `getConfig()` — returns ScreenConfig with SERVICE\n * - `beforeSave(): boolean` — return false to cancel save\n * (default: true)\n * - `afterLoad()` — post-process loaded entity\n * - `afterSave(result)` — default invalidates refs + navigates\n * to the new edit URL after create\n * - `onSaveError(errors)` — surface form-level validation errors\n * - `customizeDuplicatedEntity` — clean fields before duplicating\n *\n * ```ts\n * @Component({ ... })\n * export class FooDetailComponent extends AbstractDetailScreenV2<FooDto> {\n * override getConfig() { return FooConfig; }\n *\n * protected override beforeSave(): boolean {\n * // validate this.entity() shape; return false to cancel\n * return true;\n * }\n * }\n * ```\n */\n@Component({ template: '', standalone: true })\nexport abstract class AbstractDetailScreenV2<TItem extends object = any>\n extends AbstractScreenComponent\n implements OnInit\n{\n protected readonly screenState = ScreenStateEnum.DETAIL;\n protected readonly injector = inject(Injector);\n protected readonly location = inject(Location);\n private readonly destroyRef = inject(DestroyRef);\n private readonly auditHistoryService = inject(AUDIT_HISTORY_SERVICE, { optional: true });\n private readonly shortcuts = inject(EfShortcutService);\n\n /** Distinguishes this instance's registration from any other detail\n * screen alive at once (the outgoing and incoming routed component\n * can briefly coexist), the same convention ef-row-actions uses:\n * a shared static id would let one instance's disposer unregister\n * a still-live sibling's entry. */\n private static nextInstanceId = 0;\n private readonly instanceId = AbstractDetailScreenV2.nextInstanceId++;\n\n protected serviceInstance: any;\n\n constructor() {\n super();\n // Every detail screen inherits mod+s with no per-screen wiring, and\n // it doubles as the fix for the browser's own Save Page dialog\n // otherwise popping up on top of it.\n this.shortcuts.register({\n id: `abstract-detail-screen-v2.${this.instanceId}.save`,\n keys: 'mod+s',\n labelKey: 'common_save',\n group: 'shortcut_group_screen',\n handler: () => this.save(),\n });\n }\n\n /**\n * Change-history entries for the loaded record, newest first. Populated\n * automatically when the config sets `AUDIT_ENTITY_TYPE` and an\n * `AUDIT_HISTORY_SERVICE` is provided. Bind it directly:\n * `<ef-change-history [entries]=\"auditEntries()\" />`.\n */\n readonly auditEntries = signal<any[]>([]);\n\n /** Loaded entity. Empty object when on `/details` (create mode). */\n readonly entity = signal<TItem>(<TItem>{});\n\n /** PK from the route param, or `null` on `/details` (new). */\n readonly entityId = signal<any>(null);\n\n /** Edit-mode flag — true when an id is present and we're not duplicating. */\n readonly editionState = signal(false);\n\n /**\n * When true, the loaded entity is treated as a template — saving\n * runs `service.create()` instead of `service.update()`. Set by\n * the `?mode=duplicate` query param.\n */\n readonly duplicateMode = signal(false);\n\n /** True while service.get / create / update / delete is in flight. */\n readonly loading = signal(false);\n\n /** Last load / save error message — empty string when none. */\n readonly errorMsg = signal<string | null>(null);\n\n /**\n * Reactive list of custom actions for `<ef-detail-toolbar>`'s\n * `[customActions]` input — recomputes whenever editionState /\n * duplicateMode flip. Default contents:\n * - Edit mode → empty (the standard `print | duplicate |\n * delete | save` row covers it)\n * - Create mode → `[Cancel]` — navigates back to the list\n * - Duplicate mode → `[Cancel]` — drops `?mode=duplicate` and\n * returns to edit view of the source entity\n *\n * Subclasses override `getCustomActions()` to add screen-specific\n * actions (Approve / Print PDF / Mark as paid / etc.). Call\n * `super.getCustomActions()` to keep the Cancel default.\n */\n readonly customActions = computed<ReadonlyArray<EfDetailToolbarAction>>(\n () => this.getCustomActions(),\n );\n\n /**\n * Builder for `customActions`. Override per screen to add or\n * replace the defaults. Pure function — reads other signals\n * freely, returns a fresh array each call.\n */\n protected getCustomActions(): EfDetailToolbarAction[] {\n // Edit mode: standard right-side group is enough; let subclass\n // append Preview / Print PDF / etc. by overriding this method.\n if (this.editionState()) return [];\n\n // Create / duplicate mode: a Cancel button. See cancel().\n return [\n {\n id: 'cancel',\n labelKey: 'common_cancel',\n icon: 'pi pi-times',\n severity: 'ghost',\n command: () => this.cancel(),\n },\n ];\n }\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.serviceInstance = this.injector.get(this.getConfig()!.SERVICE as any);\n\n // Reference / static lists for the detail context (different\n // set than the search screen's — `DETAILS_*` not `SEARCH_*`).\n const cfg = this.getConfig();\n if (cfg) {\n const hasDynamicRefs = (cfg.DETAILS_REFERENTIALS_KEYS?.length ?? 0) > 0;\n const hasStaticLists = (cfg.DETAILS_STATIC_LISTS?.length ?? 0) > 0;\n if (hasDynamicRefs) this.initializeReferenceKeys(cfg.DETAILS_REFERENTIALS_KEYS);\n if (hasStaticLists) this.initializeStaticLists(cfg.DETAILS_STATIC_LISTS);\n if (hasDynamicRefs || hasStaticLists) this.loadReferenceData(cfg.REF_DATA_OPTIONS);\n }\n\n // Wire route params → load (or reset to empty on /details).\n combineLatest([this.route.paramMap, this.route.queryParamMap])\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(([params, queryParams]) => {\n const id = params.get('id');\n const isDuplicate = queryParams.get('mode') === 'duplicate';\n\n this.entityId.set(id);\n this.duplicateMode.set(isDuplicate);\n this.context.duplicateMode = isDuplicate;\n this.editionState.set(!!id && !isDuplicate);\n\n if (id) {\n this.loadData();\n } else {\n // New mode — reset to a fresh empty entity, no history yet.\n this.entity.set(<TItem>{});\n this.auditEntries.set([]);\n this.afterLoad();\n }\n });\n }\n\n /**\n * Merge a partial patch into the `entity` signal — the canonical\n * way for form inputs to write back. Spread-immutably so OnPush\n * change detection picks it up.\n *\n * ```html\n * <ef-input-text\n * variant=\"comptoir\"\n * [value]=\"title()\"\n * (valueChangeEvent)=\"patchEntity({ title: $event })\"\n * />\n * ```\n */\n patchEntity(patch: Partial<TItem>): void {\n this.entity.update(current => ({ ...(current as object), ...patch }) as TItem);\n }\n\n /** Fetch the entity from the backend and populate `entity`. */\n loadData(): void {\n const id = this.entityId();\n if (!id) return;\n\n this.loading.set(true);\n this.errorMsg.set(null);\n\n this.serviceInstance.get(id).subscribe({\n next: (result: any) => {\n const vm = new ViewModelEntity(result) as unknown as TItem;\n (vm as any).id = id;\n this.entity.set(vm);\n this.loading.set(false);\n this.afterLoad();\n this.loadAuditHistory();\n },\n error: (err: any) => {\n console.error('AbstractDetailScreenV2.loadData failed', err);\n this.errorMsg.set(err?.message ?? 'Erreur de chargement');\n this.loading.set(false);\n },\n });\n }\n\n /**\n * Persist the entity. Routes to `service.create()` when in new\n * or duplicate mode, `service.update(id, entity)` when editing.\n * Subclass `beforeSave()` can return `false` to cancel.\n */\n save(): void {\n const proceed = this.beforeSave();\n if (proceed === false) return;\n\n this.clearServerErrors();\n\n const isCreate = !this.editionState() || this.duplicateMode();\n const payload = this.duplicateMode()\n ? this.prepareEntityForDuplication()\n : this.entity();\n\n this.loading.set(true);\n const op = isCreate\n ? this.serviceInstance.create(payload)\n : this.serviceInstance.update(this.entityId(), payload);\n\n op.subscribe({\n next: (response: any) => {\n this.loading.set(false);\n if (response?.errors?.length) {\n this.handleErrors(response.errors);\n return;\n }\n this.toastService.showSuccess();\n this.afterSave(response);\n },\n error: (response: any) => {\n this.loading.set(false);\n if (response?.errors) {\n this.setServerErrors(response.errors);\n this.setFormErrors(response.errors);\n this.onSaveError(response.errors);\n }\n },\n });\n }\n\n /**\n * Soft-delete-then-navigate-back. Confirms with the user first.\n */\n /**\n * Name of the record being deleted, so the confirmation can say what\n * it is about to destroy — \"Delete ANDALOCY PARFUMS?\" rather than\n * \"Delete?\". Override in the screen; returning `undefined` keeps the\n * generic message, which still reads correctly.\n *\n * ```ts\n * protected override getDeleteConfirmName() {\n * return this.entity()?.name;\n * }\n * ```\n */\n protected getDeleteConfirmName(): string | undefined {\n return undefined;\n }\n\n delete(): void {\n const id = this.entityId();\n if (!id) {\n this.recordNotFound();\n return;\n }\n\n this.confirmDialogService.confirm({\n intent: 'delete',\n name: this.getDeleteConfirmName(),\n accept: () =>\n this.serviceInstance.delete(id).subscribe({\n next: (result: any) => {\n if (result?.errors?.length) {\n this.handleErrors(result.errors);\n } else {\n this.toastService.showSuccess();\n this.navigateBack();\n }\n },\n // The HTTP error interceptor surfaces the message (toast).\n // Swallow here so a rejected delete (e.g. a 422 business-rule\n // violation) doesn't bubble up as an unhandled error.\n error: () => undefined,\n }),\n });\n }\n\n /** Navigate to `/details/:id?mode=duplicate` so the abstract can\n * reload the source entity, treat it as a template, and persist\n * via `service.create()` after the user hits Save.\n * Without the id, the duplicate route would have nothing to\n * fetch — `entity` would be empty and the clone-as-template\n * flow would fall back to creating a blank record. */\n duplicate(): void {\n const id = this.entityId();\n const base = this.detailsBaseUrl();\n if (id == null) {\n // No source record (already on /details with no id) —\n // just open the create form.\n this.router.navigate([base]);\n return;\n }\n this.router.navigate([base, id], {\n queryParams: { mode: 'duplicate' },\n });\n }\n\n /**\n * Cancel handler for the default toolbar action:\n * - Duplicate mode → drop `?mode=duplicate` and return to\n * `/details/:id`. The route subscription re-fires and reloads\n * the source entity, discarding any in-memory edits.\n * - Create mode (no id) → navigate back to the list.\n *\n * Subclasses may override to add a confirm dialog when the form\n * is dirty.\n */\n cancel(): void {\n if (this.duplicateMode() && this.entityId() != null) {\n this.router.navigate([this.detailsBaseUrl(), this.entityId()]);\n return;\n }\n this.navigateBack();\n }\n\n /** Navigate back to the list (strip `/details` and any id). */\n navigateBack(): void {\n const url = (this.router.url || '').split('?')[0];\n const idx = url.indexOf('/details');\n if (idx !== -1) {\n this.router.navigate([url.substring(0, idx)]);\n } else {\n this.location.back();\n }\n }\n\n /** Subclass print hook — no-op default. */\n print(): void { /* no-op */ }\n\n /**\n * Load the standardized change-history into `auditEntries` when the config\n * opts in via `AUDIT_ENTITY_TYPE` and an `AUDIT_HISTORY_SERVICE` is provided.\n * Called automatically after a successful `loadData()`. Failures degrade to\n * an empty history rather than blocking the screen.\n */\n protected loadAuditHistory(): void {\n this.auditEntries.set([]);\n\n const entityType = this.getConfig()?.AUDIT_ENTITY_TYPE;\n const id = this.entityId();\n\n // No service provided, screen not opted in, or no id yet → empty box.\n if (!this.auditHistoryService || !entityType || !id) {\n return;\n }\n\n // Fully defensive: a missing/misconfigured audit client (no provider,\n // wrong shape, get() throwing, or an HTTP failure) must never break the\n // detail screen — it just leaves the history empty.\n try {\n const result$ = this.auditHistoryService.get(entityType, id);\n if (!result$ || typeof result$.subscribe !== 'function') {\n return;\n }\n result$.subscribe({\n next: (entries) => this.auditEntries.set(entries ?? []),\n error: () => this.auditEntries.set([]),\n });\n } catch {\n this.auditEntries.set([]);\n }\n }\n\n /* ── Override hooks ─────────────────────────────────────────── */\n\n /**\n * Called right before `save()` dispatches to the backend. Return\n * `false` to cancel (e.g., form validation failed). Default: no-op.\n */\n protected beforeSave(): boolean | void {\n return true;\n }\n\n /** Override to post-process the loaded `entity` (or to refresh\n * derived signals). Default: no-op. */\n protected afterLoad(): void { /* no-op */ }\n\n /**\n * Default post-save behaviour:\n * - invalidate / refresh reference data per ScreenConfig\n * - after a CREATE (or duplicate-save), navigate to\n * `/details/<new-id>` so the user lands in edit mode\n */\n protected afterSave(result: any): void {\n const cfg = this.getConfig();\n if (cfg?.INVALIDATE_KEYS_ON_SAVE) {\n this.invalidateReferences(cfg.INVALIDATE_KEYS_ON_SAVE);\n if (cfg.REFRESH_ON_SAVE) {\n this.refreshReferenceData(cfg.INVALIDATE_KEYS_ON_SAVE);\n }\n }\n\n const isCreate = !this.editionState() || this.duplicateMode();\n if (isCreate) {\n const newId = typeof result === 'object' ? (result?.id ?? result) : result;\n this.router.navigate([this.detailsBaseUrl(), newId]);\n } else {\n // Update succeeded in place — refresh the change-history so the new\n // entry shows without a manual reload.\n this.loadAuditHistory();\n }\n }\n\n /** Override to surface form-level validation errors after a 4xx\n * response. Default: no-op (errors are already on `serverErrors`). */\n protected onSaveError(_errors: { [key: string]: string[] }): void { /* no-op */ }\n\n /** Strip id (if present) from the entity before a duplicate save. */\n protected prepareEntityForDuplication(): any {\n const dup = { ...(this.entity() as any) };\n delete dup.id;\n delete dup.Id;\n return this.customizeDuplicatedEntity(dup);\n }\n\n /** Override to clear additional fields (codes, slugs, refs)\n * before saving a duplicated entity. */\n protected customizeDuplicatedEntity(entity: any): any {\n return entity;\n }\n\n /* ── Internals ──────────────────────────────────────────────── */\n\n /** Resolve the bare `/<resource>/details` base URL — strips a\n * trailing `:id`, query string, fragment, trailing slash. */\n protected detailsBaseUrl(): string {\n let url = this.router.url || '';\n const q = url.indexOf('?');\n if (q >= 0) url = url.slice(0, q);\n const h = url.indexOf('#');\n if (h >= 0) url = url.slice(0, h);\n // If we're on /…/details/<id>, drop <id>; if on /…/details, leave it.\n const m = url.match(/^(.*?\\/details)(?:\\/[^/]+)?\\/?$/);\n return m ? m[1] : url;\n }\n\n // AbstractComponent declares `abstract ngOnDestroy()`, so this must exist.\n // There is genuinely nothing to tear down here; removing it would push the\n // requirement onto every consumer component.\n // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method\n ngOnDestroy(): void {\n // The route subscription is auto-unsubscribed via takeUntilDestroyed.\n // Subclasses can override to release their own resources.\n }\n}\n","import {\n Component,\n inject,\n Injector,\n OnDestroy, OnInit,\n Signal,\n signal,\n} from '@angular/core';\nimport { Observable, take } from 'rxjs';\nimport { Permissions } from '@elasticias/types';\nimport { CsvUtils } from '@elasticias/utils';\nimport { AbstractScreenComponent } from './abstract-screen.component';\nimport { ScreenStateEnum } from '../../config/screen-state.enum';\nimport { EfDatePresetKey, EfDateRange } from '../../entities/date-range.entity';\n\nexport type ReportWidgetStatus = 'loading' | 'ready' | 'error';\n\n/**\n * Handle returned by {@link AbstractReportScreenV2.widget}. Each widget owns\n * an independent loading/error lifecycle — one failing report block never\n * blanks its siblings.\n */\nexport interface ReportWidget<T> {\n /** Last successful payload — null until the first `ready`. */\n readonly data: Signal<T | null>;\n readonly status: Signal<ReportWidgetStatus>;\n /** Re-run this widget's loader against the current period. */\n reload(): void;\n}\n\n/**\n * Signal-first base for report/dashboard screens — the third V2 abstract,\n * alongside {@link AbstractSearchScreenV2} / AbstractDetailScreenV2.\n *\n * Owns the report CHASSIS only: period state (`dateRange`, seeded from the\n * config's `DEFAULT_PERIOD` preset), per-widget lifecycle (`widget()` +\n * `loadAll()`), `REPORT_STATIC_LISTS` preload, and Export-gated CSV\n * (Task 2). Widget COMPOSITION stays in each screen's template — a\n * metadata-driven report renderer was rejected in ADR-015 and this class\n * must not become its frontend half.\n *\n * `ScreenConfig` surface: `SCREEN` (backend screen code), `SERVICE` (NSwag\n * reports client), `DEFAULT_PERIOD`, `REPORT_STATIC_LISTS`.\n *\n * Subclasses typically:\n *\n * ```ts\n * export class FooDashboardComponent extends AbstractReportScreenV2 {\n * protected override getConfig() { return FooDashboardConfig; }\n * readonly kpisW = this.widget((start, end) =>\n * this.client.kpis(new GetFooKpisQuery({ start, end })));\n * }\n * ```\n *\n * Loaders close over the screen's own filter signals; the screen calls\n * `loadAll()` (period-wide) or `someW.reload()` (single widget) when its\n * filters change. Period-independent blocks (operational strips) load\n * outside the registry on purpose.\n */\n@Component({ template: '', standalone: true })\nexport abstract class AbstractReportScreenV2\n extends AbstractScreenComponent\n implements OnInit\n{\n protected readonly screenState = ScreenStateEnum.REPORT;\n protected readonly injector = inject(Injector);\n\n /** NSwag reports client resolved from `ScreenConfig.SERVICE` — expose a\n * typed getter in the screen: `get client() { return this.reportsService as XClient; }` */\n protected reportsService: any;\n\n private readonly registeredWidgets: ReportWidget<unknown>[] = [];\n\n /** Active period. Bound to `ef-datepicker-advanced`; every widget loader\n * receives its UTC-normalized start/end. */\n readonly dateRange = signal<EfDateRange>(this.buildDefaultDateRange());\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.reportsService = this.injector.get(this.getConfig()!.SERVICE as any);\n\n // Reinstate the period the user last chose before anything loads, so the\n // widgets fetch it once instead of fetching the default and refetching.\n this.dateRange.set(\n this.restorePersistedDateRange(this.dateRange(), key => this.rangeFromPreset(key)),\n );\n\n const lists = this.getConfig()?.REPORT_STATIC_LISTS ?? [];\n if (lists.length > 0) {\n this.initializeStaticLists(lists);\n this.loadReferenceData(this.getConfig()?.REF_DATA_OPTIONS);\n this.refDataLoaded$.pipe(take(1)).subscribe(() => this.loadAll());\n } else {\n this.loadAll();\n }\n }\n\n /* ── Period ─────────────────────────────────────────────────── */\n\n /** Wired to `<ef-datepicker-advanced (rangeChange)>`. */\n onDateRangeChange(range: EfDateRange): void {\n this.dateRange.set(range);\n this.persistDateRange(range);\n this.loadAll();\n }\n\n /** Default period from the config's `DEFAULT_PERIOD` preset. */\n protected buildDefaultDateRange(): EfDateRange {\n return this.rangeFromPreset(this.getConfig()?.DEFAULT_PERIOD ?? 'last_30_days');\n }\n\n /**\n * Resolve a built-in {@link EfDatePresetKey} to an inclusive day range\n * (both boundaries at 00:00 local). Unknown keys normalize to\n * `last_30_days`. Weeks start Monday (matches `$dateTrunc`, ADR-015).\n */\n protected rangeFromPreset(key: EfDatePresetKey): EfDateRange {\n const KNOWN: EfDatePresetKey[] = [\n 'today', 'this_week', 'this_month', 'last_30_days',\n 'last_90_days', 'this_quarter', 'this_year',\n ];\n const k = KNOWN.includes(key) ? key : 'last_30_days';\n const today = this.startOfToday();\n const end = new Date(today);\n let start = new Date(today);\n switch (k) {\n case 'today':\n break;\n case 'this_week': {\n const dow = (today.getDay() + 6) % 7;\n start.setDate(today.getDate() - dow);\n break;\n }\n case 'this_month':\n start = new Date(today.getFullYear(), today.getMonth(), 1);\n break;\n case 'last_90_days':\n start.setDate(today.getDate() - 89);\n break;\n case 'this_quarter':\n start = new Date(today.getFullYear(), Math.floor(today.getMonth() / 3) * 3, 1);\n break;\n case 'this_year':\n start = new Date(today.getFullYear(), 0, 1);\n break;\n case 'last_30_days':\n default:\n start.setDate(today.getDate() - 29);\n break;\n }\n return { start, end, presetKey: k, labelKey: `date_preset_${k}`, label: '' };\n }\n\n private startOfToday(): Date {\n const d = new Date();\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n }\n\n /**\n * Re-anchor a local-midnight Date to UTC midnight of the same calendar\n * date. NSwag serializes via toISOString(); for UTC+ users (Morocco)\n * local midnight would otherwise shift into the previous UTC day.\n */\n protected toUtcDate(d: Date): Date {\n return new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));\n }\n\n /* ── Widgets ────────────────────────────────────────────────── */\n\n /**\n * Register a report widget. The loader receives the current period's\n * UTC-normalized start/end and returns the NSwag observable; extra\n * filters are simply closed over from the screen's own signals.\n */\n protected widget<T>(\n loader: (start: Date, end: Date) => Observable<T>,\n ): ReportWidget<T> {\n const data = signal<T | null>(null);\n const status = signal<ReportWidgetStatus>('loading');\n const handle: ReportWidget<T> = {\n data: data.asReadonly(),\n status: status.asReadonly(),\n reload: () => {\n const { start, end } = this.dateRange();\n status.set('loading');\n loader(this.toUtcDate(start), this.toUtcDate(end)).subscribe({\n next: (value) => {\n data.set(value);\n status.set('ready');\n },\n error: () => status.set('error'),\n });\n },\n };\n this.registeredWidgets.push(handle);\n return handle;\n }\n\n /** Reload every registered widget against the current period. */\n loadAll(): void {\n for (const w of this.registeredWidgets) w.reload();\n }\n\n /* ── Grants + export ────────────────────────────────────────── */\n\n /** Export grant (ADR-011) on this screen's own code. Grants are loaded\n * once by `processGrants()` in ngOnInit — safe to call from templates. */\n canExport(): boolean {\n return this.context?.isGranted(Permissions.Export) ?? false;\n }\n\n /** CSV download gated by the Export grant — silently no-ops without it. */\n protected exportCsv(\n filename: string,\n rows: object[],\n columns: { key: string; header: string }[],\n ): void {\n if (!this.canExport()) return;\n // `CsvColumn<T>['key']` is `keyof T & string`, which is `never` for the\n // bare `object` type — widen to `Record<string, unknown>` so the\n // generic infers a `string`-keyed column, matching `columns` as declared.\n CsvUtils.download(\n filename,\n CsvUtils.toCsv(rows as Record<string, unknown>[], columns),\n );\n }\n\n // AbstractComponent declares `abstract ngOnDestroy()`, so this must exist.\n // There is genuinely nothing to tear down here; removing it would push the\n // requirement onto every consumer component.\n // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method\n ngOnDestroy(): void {\n // NSwag observables complete after one emission — nothing to tear down.\n }\n}\n","import { Component } from '@angular/core';\nimport { AbstractScreenComponent } from './abstract-screen.component';\n\n@Component({\n template: ''\n})\nexport abstract class AbstractSubScreenComponent extends AbstractScreenComponent {\n protected readonly screenState = null;\n\n override ngOnInit(): void {\n super.ngOnInit();\n }\n\n override ngAfterViewInit(): void {\n super.ngAfterViewInit();\n }\n}\n","import {\n Component,\n inject,\n Injector,\n OnDestroy, OnInit,\n signal,\n} from '@angular/core';\nimport { Permissions } from '@elasticias/types';\nimport { AbstractScreenComponent } from './abstract-screen.component';\n\n/**\n * Signal-first base for SUB-screens — self-contained fragments embedded\n * inside a host screen (dashboard strips, side panels, …) rather than\n * routed on their own. The V2 counterpart to the legacy\n * {@link AbstractSubScreenComponent}.\n *\n * A sub-screen typically borrows ANOTHER screen's identity: its config\n * sets `SCREEN` to the code whose grants gate the data it shows (e.g. a\n * recent-orders strip on the sales dashboard uses `'SalesOrders'`), so\n * `canRead()` and `ScreenContext` permissions line up with the backend\n * seed without any cross-screen plumbing in the component.\n *\n * `ScreenConfig` surface (same fields as list screens, reused here):\n * - `SCREEN` — screen code whose grants apply to this fragment\n * - `SERVICE` — NSwag client resolved into `serviceInstance`\n * - `SEARCH_REFERENTIALS_KEYS` / `SEARCH_STATIC_LISTS` — ref-data the\n * fragment's columns/labels need; loaded on init, `refDataLoaded$`\n * fires when ready (reference columns resolve reactively, so data\n * fetches don't have to wait for it)\n *\n * No criteria caching, no routing, no toolbar — a sub-screen renders one\n * `ef-card` (or similar) and owns only its data + collapse state.\n */\n@Component({ template: '', standalone: true })\nexport abstract class AbstractSubScreenV2\n extends AbstractScreenComponent\n implements OnInit\n{\n protected readonly screenState = null;\n protected readonly injector = inject(Injector);\n\n /** NSwag client resolved from `ScreenConfig.SERVICE` (null-safe: a\n * sub-screen fed entirely by inputs may omit SERVICE). */\n protected serviceInstance: any;\n\n /**\n * Collapse state, bound `[(collapsed)]` on the sub-screen's `ef-card`.\n * Starts collapsed: sub-screens are secondary content on their host\n * screen, so they open on demand. Subclasses that must start open set\n * `this.collapsed.set(false)` in their constructor.\n */\n readonly collapsed = signal(true);\n\n toggleCollapsed(): void {\n this.collapsed.update((c) => !c);\n }\n\n /** Read grant on the config's `SCREEN` — gate the whole fragment on\n * this so an unauthorized user gets nothing (not an erroring card). */\n canRead(): boolean {\n return this.context?.isGranted(Permissions.Read) ?? false;\n }\n\n override ngOnInit(): void {\n super.ngOnInit();\n const cfg = this.getConfig();\n if (cfg?.SERVICE) {\n this.serviceInstance = this.injector.get(cfg.SERVICE as any);\n }\n\n const hasDynamicRefs = (cfg?.SEARCH_REFERENTIALS_KEYS?.length ?? 0) > 0;\n const hasStaticLists = (cfg?.SEARCH_STATIC_LISTS?.length ?? 0) > 0;\n if (hasDynamicRefs) this.initializeReferenceKeys(cfg.SEARCH_REFERENTIALS_KEYS);\n if (hasStaticLists) this.initializeStaticLists(cfg.SEARCH_STATIC_LISTS);\n // No refs declared → no load, and (matching AbstractSearchScreenV2)\n // no refDataLoaded$ emission — don't wait on it in that case.\n if (hasDynamicRefs || hasStaticLists) {\n this.loadReferenceData(cfg.REF_DATA_OPTIONS);\n }\n }\n\n // AbstractComponent declares `abstract ngOnDestroy()`, so this must exist.\n // There is genuinely nothing to tear down here; removing it would push the\n // requirement onto every consumer component.\n // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method\n ngOnDestroy(): void {\n // NSwag observables complete after one emission — nothing to tear\n // down; subclasses override when they hold live subscriptions.\n }\n}\n","import { SortDirectionEnum } from '../entities/search.entity';\nimport type { EfDatePresetKey } from '../entities/date-range.entity';\n\nexport interface DefaultSort {\n field: string;\n direction: SortDirectionEnum;\n}\n\nexport interface LoadOptions {\n bypassCache?: boolean;\n ttl?: number;\n forceRefresh?: boolean;\n useSql?: boolean;\n}\n\nexport abstract class ScreenConfig {\n SCREEN!: string;\n SERVICE!: unknown;\n\n SEARCH_REFERENTIALS_KEYS!: string[];\n DETAILS_REFERENTIALS_KEYS!: string[];\n\n SEARCH_STATIC_LISTS: string[] = [];\n DETAILS_STATIC_LISTS: string[] = [];\n\n INVALIDATE_KEYS_ON_SAVE?: string[];\n REFRESH_ON_SAVE?: boolean;\n REF_DATA_OPTIONS?: LoadOptions;\n DEFAULT_SORT?: DefaultSort;\n\n /**\n * Backend entity type for the standardized change-history box. When set,\n * AbstractDetailScreenV2 auto-loads the record's audit trail (via the\n * AUDIT_HISTORY_SERVICE token) into its `auditEntries` signal — the screen\n * only needs `<ef-change-history [entries]=\"auditEntries()\" />`. Leave unset\n * to opt out. Must match the backend IAuditable.AuditEntityType (e.g. 'Client').\n */\n AUDIT_ENTITY_TYPE?: string;\n\n /**\n * Report screens (AbstractReportScreenV2): starting period preset for the\n * screen's ef-datepicker-advanced. Unset → 'last_30_days'.\n */\n DEFAULT_PERIOD?: EfDatePresetKey;\n\n /**\n * Report screens: translatable static lists preloaded before the first\n * loadAll() — same mechanism as SEARCH_STATIC_LISTS on list screens.\n */\n REPORT_STATIC_LISTS?: string[];\n}\n","// Abstract base classes\nexport { AbstractEntity } from './lib/abstract/abstract.entity';\nexport { AbstractComponent } from './lib/abstract/abstract.component';\n\n// Screen abstract components\nexport { AbstractScreenComponent } from './lib/abstract/screen/abstract-screen.component';\nexport { AbstractDetailScreenComponent } from './lib/abstract/screen/abstract-detail-screen.component';\nexport { AbstractSearchScreenComponent } from './lib/abstract/screen/abstract-search-screen.component';\nexport type { ScreenDatatableColumn } from './lib/abstract/screen/abstract-search-screen.component';\nexport { AbstractSearchScreenV2 } from './lib/abstract/screen/abstract-search-screen-v2.component';\nexport type { AdvancedSelectFilter } from './lib/abstract/screen/abstract-search-screen-v2.component';\nexport { AbstractDetailScreenV2 } from './lib/abstract/screen/abstract-detail-screen-v2.component';\nexport { AbstractReportScreenV2 } from './lib/abstract/screen/abstract-report-screen-v2.component';\nexport type { ReportWidget, ReportWidgetStatus } from './lib/abstract/screen/abstract-report-screen-v2.component';\nexport { AbstractSubScreenComponent } from './lib/abstract/screen/abstract-sub-screen.component';\nexport { AbstractSubScreenV2 } from './lib/abstract/screen/abstract-sub-screen-v2.component';\n\n// Services\nexport { SCREEN_REF_DATA_SERVICE } from './lib/services/screen-reference-data.service';\nexport type { ScreenReferenceDataService } from './lib/services/screen-reference-data.service';\nexport { AUDIT_HISTORY_SERVICE } from './lib/services/audit-history.service';\nexport type { AuditHistoryService } from './lib/services/audit-history.service';\n\n// Config\nexport { ScreenStateEnum, StateUtilsEnum } from './lib/config/screen-state.enum';\nexport { ScreenConfig } from './lib/config/screen-config';\nexport type { LoadOptions, DefaultSort } from './lib/config/screen-config';\nexport { ScreenContext } from './lib/config/screen-context';\nexport type { ReferenceDataProvider } from './lib/config/screen-context';\n\n// Entities\nexport { SearchEntity, SortDirectionEnum, PaginationEnum } from './lib/entities/search.entity';\nexport { ViewModelEntity } from './lib/entities/view-model.entity';\nexport type { EfDateRange, EfDatePresetKey } from './lib/entities/date-range.entity';\nexport type { ActiveFilter } from './lib/entities/active-filter.entity';\nexport type { EfDetailToolbarAction } from './lib/entities/detail-toolbar-action.entity';\nexport type { EfSearchToolbarAction } from './lib/entities/search-toolbar-action.entity';\nexport type {\n EfDataCardColumn,\n EfDataCardColumnType,\n EfDataCardColumnMobileRole,\n EfDataCardColumnAlign,\n EfDataCardSort,\n EfDataCardSortDirection,\n EfReferenceColumnOpts,\n EfDataCardExportRequest,\n} from './lib/entities/data-card-column.entity';\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-screens.mjs","sources":["../../../../libs/screens/src/lib/abstract/abstract.entity.ts","../../../../libs/screens/src/lib/abstract/abstract.component.ts","../../../../libs/screens/src/lib/config/screen-context.ts","../../../../libs/screens/src/lib/services/screen-reference-data.service.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-screen.component.ts","../../../../libs/screens/src/lib/config/screen-state.enum.ts","../../../../libs/screens/src/lib/entities/view-model.entity.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-detail-screen.component.ts","../../../../libs/screens/src/lib/entities/search.entity.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-search-screen.component.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-search-screen-v2.component.ts","../../../../libs/screens/src/lib/services/audit-history.service.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-detail-screen-v2.component.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-report-screen-v2.component.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-sub-screen.component.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-sub-screen-v2.component.ts","../../../../libs/screens/src/lib/config/screen-config.ts","../../../../libs/screens/src/index.ts","../../../../libs/screens/src/elasticias-screens.ts"],"sourcesContent":["export abstract class AbstractEntity {\n [key: string]: unknown;\n clone(entity: AbstractEntity): AbstractEntity {\n for (const field of Reflect.ownKeys(entity)) {\n if ((this as Record<string | symbol, unknown>)[field] == null) {\n (this as Record<string | symbol, unknown>)[field] = (entity as unknown as Record<string | symbol, unknown>)[field];\n }\n }\n return this;\n }\n\n newClone(): Record<string, unknown> {\n const cloneObj: Record<string, unknown> = {};\n for (const field of Reflect.ownKeys(this)) {\n cloneObj[field as string] = (this as Record<string | symbol, unknown>)[field];\n }\n return cloneObj;\n }\n\n update(entity: Record<string, unknown>): AbstractEntity {\n for (const field of Reflect.ownKeys(entity)) {\n if ((this as Record<string | symbol, unknown>)[field] != null) {\n (this as Record<string | symbol, unknown>)[field] = entity[field as string];\n }\n }\n return this;\n }\n\n buildEntity(entity: Record<string, unknown>): void {\n Object.keys(entity).forEach((key) => {\n (this as Record<string, unknown>)[key] = entity[key];\n });\n }\n\n clearFields(): void {\n for (const field of Reflect.ownKeys(this)) {\n (this as Record<string | symbol, unknown>)[field] = null;\n }\n }\n}\n","import { Component, Input, OnDestroy, OnInit } from '@angular/core';\nimport { PersistedState, PersistedStateOptions } from '@elasticias/utils';\nimport { Subject } from 'rxjs';\n\n@Component({ template: '' })\nexport abstract class AbstractComponent implements OnInit, OnDestroy {\n @Input() readOnly = false;\n protected destroyed$ = new Subject<void>();\n\n abstract ngOnInit(): void;\n abstract ngOnDestroy(): void;\n\n /**\n * Declare a piece of this component's state that should survive a page\n * refresh — an active period, a chosen tab, a collapsed rail.\n *\n * Nothing is read or written until the returned handle is used, so\n * calling this costs nothing and adds no storage dependency to\n * components that never touch it. Keep the key stable across releases\n * and namespaced to the screen, and pass `revive` for any shape holding\n * a `Date`: JSON hands those back as strings.\n *\n * ```ts\n * private readonly rail = this.persisted<boolean>('SALES_RAIL_OPEN');\n * ngOnInit() { this.open.set(this.rail.read() ?? true); }\n * ```\n */\n protected persisted<T>(key: string, options?: PersistedStateOptions<T>): PersistedState<T> {\n return new PersistedState<T>(key, options);\n }\n}\n","import { Signal, signal } from '@angular/core';\nimport { AbstractEntity } from '../abstract/abstract.entity';\nimport { Permissions } from '@elasticias/types';\n\n/**\n * Abstract interface for reference data providers.\n * Apps must implement this and provide it to ScreenContext.\n */\nexport interface ReferenceDataProvider {\n getReference(key: string): Signal<any[]>;\n hasReference(key: string): boolean;\n}\n\nexport class ScreenContext extends AbstractEntity {\n state: string;\n screenName!: string;\n language: string;\n group: unknown;\n private _refDataProvider?: ReferenceDataProvider;\n bundles: Map<string, Map<string, Map<string, string>>>;\n entity: unknown;\n grants: string[];\n duplicateMode = false;\n\n /**\n * Whether the screen may write the record it shows, for its current mode.\n * Set by `AbstractDetailScreenV2` to its own `canWrite` signal, so shared\n * components bound to `[context]` (ef-detail-toolbar's Save and its\n * `requiresWrite` custom actions) follow the same rule without each\n * screen passing it again. Undefined on screens that have no write mode\n * (search, report), where those components keep their default behaviour.\n */\n canWrite?: Signal<boolean>;\n\n constructor(\n state: string,\n group?: unknown,\n entity?: unknown,\n refDataProvider?: ReferenceDataProvider,\n bundles?: Map<string, Map<string, Map<string, string>>>,\n grants?: string[],\n screenName = '',\n language = 'fr'\n ) {\n super();\n this.state = state;\n this.group = group;\n this.entity = entity;\n this.screenName = screenName;\n this.language = language;\n this._refDataProvider = refDataProvider;\n this.bundles = bundles ?? new Map();\n this.grants = grants ?? [];\n }\n\n setReferenceDataProvider(provider: ReferenceDataProvider): void {\n this._refDataProvider = provider;\n }\n\n get ref() {\n return {\n get: (key: string): Signal<any[]> => {\n if (!this._refDataProvider) {\n console.warn('ReferenceDataProvider not set in ScreenContext. Returning empty signal.');\n return signal([]);\n }\n return this._refDataProvider.getReference(key);\n },\n has: (key: string): boolean => {\n return this._refDataProvider?.hasReference(key) ?? false;\n },\n };\n }\n\n getLabel(key: string): string {\n try {\n return this.bundles.get(this.language)!.get(this.screenName)!.get(key) ?? key;\n } catch {\n return key;\n }\n }\n\n isGranted(permission: Permissions): boolean {\n return this.grants?.some((value) => value === permission) ?? false;\n }\n\n /* ── Permission convenience getters ───────────────────────────────\n Shared components (ef-row-actions, ef-data-card auto actions cell,\n toolbars) read these to default-show / default-hide CRUD buttons\n against the current user's grants without re-importing\n Permissions at every call site. */\n\n get hasReadPermission(): boolean {\n return this.isGranted(Permissions.Read);\n }\n\n get hasCreatePermission(): boolean {\n return this.isGranted(Permissions.Create);\n }\n\n get hasEditPermission(): boolean {\n return this.isGranted(Permissions.Edit);\n }\n\n get hasDeletePermission(): boolean {\n return this.isGranted(Permissions.Delete);\n }\n\n get hasDuplicatePermission(): boolean {\n return this.isGranted(Permissions.Duplicate);\n }\n\n get hasPrintPermission(): boolean {\n return this.isGranted(Permissions.Print);\n }\n\n get hasExportPermission(): boolean {\n return this.isGranted(Permissions.Export);\n }\n\n get hasImportPermission(): boolean {\n return this.isGranted(Permissions.Import);\n }\n\n isReadOnly(): boolean {\n return (\n this.isGranted(Permissions.Read) &&\n !this.isGranted(Permissions.Create) &&\n !this.isGranted(Permissions.Edit) &&\n !this.isGranted(Permissions.Delete)\n );\n }\n}\n","import { InjectionToken, Signal } from '@angular/core';\nimport { ReferenceDataProvider } from '../config/screen-context';\nimport { LoadOptions } from '../config/screen-config';\n\n/**\n * Abstract interface for reference data services used by screen components.\n * Apps must implement this interface and provide it via SCREEN_REF_DATA_SERVICE token.\n *\n * Extends ReferenceDataProvider (getReference/hasReference for ScreenContext)\n * with methods for loading, refreshing, and invalidating reference data.\n */\nexport interface ScreenReferenceDataService extends ReferenceDataProvider {\n /**\n * Load dynamic reference data by keys\n * @param keys Array of reference data keys to load\n * @param options Optional load options (bypassCache, ttl, forceRefresh)\n */\n loadReferenceKeys(keys: string[], options?: LoadOptions): Promise<void>;\n\n /**\n * Load static reference data by type names\n * @param types Array of static reference type names\n * @param forceRefresh Force reload from server\n */\n loadStaticRefs(types: string[], forceRefresh?: boolean): Promise<void>;\n\n /**\n * Refresh reference data keys (force reload from server)\n * @param keys Array of keys to refresh\n * @param bypassCache Bypass cache entirely\n */\n refreshKeys(keys: string[], bypassCache?: boolean): Promise<void>;\n\n /**\n * Invalidate reference data keys (mark as stale)\n * @param keys Array of keys to invalidate\n */\n invalidateKeys(keys: string[]): Promise<void>;\n}\n\n/**\n * Injection token for the screen reference data service.\n * Apps must provide this token with their concrete implementation.\n *\n * @example\n * // In app module or component providers:\n * { provide: SCREEN_REF_DATA_SERVICE, useExisting: ReferenceDataService }\n */\nexport const SCREEN_REF_DATA_SERVICE = new InjectionToken<ScreenReferenceDataService>(\n 'SCREEN_REF_DATA_SERVICE'\n);\n","import { AfterViewInit, ChangeDetectorRef, Component, inject, Input, OnDestroy, OnInit, signal, ViewChild } from '@angular/core';\nimport { AbstractComponent } from '../abstract.component';\nimport { ScreenContext } from '../../config/screen-context';\nimport { ScreenConfig, LoadOptions } from '../../config/screen-config';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { NgForm } from '@angular/forms';\nimport { AppUtils, PersistedState, StorageUtils } from '@elasticias/utils';\nimport { EfDatePresetKey, EfDateRange } from '../../entities/date-range.entity';\nimport { Permissions } from '@elasticias/types';\nimport { ToastService, ConfirmDialogService, CacheService } from '@elasticias/core';\nimport { Subject } from 'rxjs';\nimport { ScreenReferenceDataService, SCREEN_REF_DATA_SERVICE } from '../../services/screen-reference-data.service';\n\n@Component({\n template: ''\n})\nexport abstract class AbstractScreenComponent extends AbstractComponent implements OnInit, AfterViewInit, OnDestroy {\n @Input() context!: ScreenContext;\n connectedUser: any;\n\n /** V1 only: the NgForm a V1 detail template declares as `#entityForm`.\n * V2 templates bind `[value]` / `(valueChangeEvent)` with no NgForm, so\n * this stays undefined there and everything below that walks it\n * (`disableAllControls`, `setFormErrors`, `isFormValid`) does nothing.\n * V2 screens use `AbstractDetailScreenV2.readOnlyMode()` bound as\n * `[efReadOnly]` on the form container, and `canWrite()` for saving. */\n @ViewChild('entityForm') entityForm!: NgForm;\n serverErrors = signal<{ [key: string]: string[] }>({});\n protected refDataLoaded$ = new Subject<void>();\n\n cacheService = inject(CacheService);\n changeDetector = inject(ChangeDetectorRef);\n toastService = inject(ToastService);\n confirmDialogService = inject(ConfirmDialogService);\n router = inject(Router);\n route = inject(ActivatedRoute);\n refDataService = inject(SCREEN_REF_DATA_SERVICE);\n\n currentUrl = '';\n\n protected abstract readonly screenState: string | null;\n get state(): string | null { return this.screenState; }\n screenStateKey = '';\n\n ngOnInit(): void {\n this.cacheService.configure(true);\n this.currentUrl = this.router.url;\n this.context = new ScreenContext(this.screenState ?? '', undefined, undefined, this.refDataService);\n\n this.screenStateKey = `SCREEN_STATE_${this.screenState}_${this.getBundleName()}`;\n this.context.screenName = this.getBundleName();\n this.processGrants();\n }\n\n /** The `isReadOnly()` branch below is the V1 read-only path. It never\n * fires usefully on a V2 screen (see `entityForm`), and its predicate\n * ignores the mode: Read+Create on an existing record counts as\n * writable. V2 detail screens rely on `readOnlyMode()` instead. */\n ngAfterViewInit(): void {\n this.changeDetector.detectChanges();\n if (this.context && this.context.isReadOnly()) {\n this.disableAllControls();\n }\n }\n\n processGrants() {\n const userGrants: any = AbstractScreenComponent.readGrants();\n if (userGrants && userGrants[this.context.screenName] && userGrants[this.context.screenName].permissions) {\n this.context.grants = userGrants[this.context.screenName].permissions;\n } else {\n this.context.grants = [];\n }\n this.changeDetector.detectChanges();\n }\n\n isFormValid(): boolean {\n if (this.context.isReadOnly()) { return true; }\n if (!this.entityForm) {\n return false;\n }\n return this.entityForm.valid ?? false;\n }\n\n getConfig(): any {\n return null;\n }\n\n /**\n * Read a query param from the activated route's snapshot. Shared\n * accessor for deep-links on both search and detail screens (e.g.\n * `?status=PendingApproval`, `?mode=duplicate`) so screens don't\n * reach into `route.snapshot.queryParamMap` themselves.\n */\n protected queryParam(name: string): string | null {\n return this.route.snapshot.queryParamMap.get(name);\n }\n\n /**\n * Grant check for ANY screen (not just this one's `SCREEN` code) —\n * e.g. an operational strip or report widget calling a\n * differently-gated endpoint. For this screen's own grants prefer\n * `context.isGranted(...)`.\n */\n protected hasGrant(screen: string, permission: Permissions): boolean {\n const grants = AbstractScreenComponent.readGrants();\n return !!grants?.[screen]?.permissions?.includes(permission);\n }\n\n /**\n * Screen grants, read from wherever the host app put them.\n *\n * Apps store these per tab in sessionStorage (they are refetched on a timer\n * and must not outlive the tab), so sessionStorage is checked first. The\n * localStorage fallback keeps apps working that persist them there instead.\n *\n * Reading only localStorage silently yielded `null` for every screen, which\n * left `context.grants` empty and hid every permission-gated control -- the\n * New and Export buttons and the row actions -- on every screen at once.\n */\n protected static readGrants(): Record<\n string,\n { permissions?: string[] }\n > | null {\n return (\n StorageUtils.getSession<Record<string, { permissions?: string[] }>>(\n 'CURRENT_USER_GRANTS',\n ) ??\n StorageUtils.getLocal<Record<string, { permissions?: string[] }>>(\n 'CURRENT_USER_GRANTS',\n )\n );\n }\n\n getBundleName(): string {\n const config = this.getConfig();\n if (config) {\n return config.SCREEN;\n } else {\n console.error('getConfig() method should be implemented !!');\n }\n return '';\n }\n\n setFormErrors(errors: { [key: string]: string[] }) {\n if (!errors || !this.entityForm) { return; }\n\n Object.keys(errors).forEach((field) => {\n const camelCaseField = AppUtils.toCamelCase(field);\n const control = this.entityForm.controls[camelCaseField];\n\n if (control) {\n control.setErrors({ serverError: errors[field] });\n control.markAsTouched();\n }\n });\n }\n\n referentialKeys: any;\n staticListKeys: string[] = [];\n\n initializeReferenceKeys(keys: string[]): void {\n if (!keys) return;\n const referencialKeys: any = {};\n\n keys.forEach(p => {\n referencialKeys[p] = {};\n });\n\n this.referentialKeys = referencialKeys;\n }\n\n initializeStaticLists(keys: string[]): void {\n if (!keys) return;\n this.staticListKeys = keys;\n }\n\n async loadReferenceData(options?: LoadOptions) {\n const loadPromises: Promise<void>[] = [];\n\n if (!AppUtils.isNullOrEmpty(this.referentialKeys)) {\n const dynamicKeys = Object.keys(this.referentialKeys);\n\n const dynamicPromise = this.refDataService\n .loadReferenceKeys(dynamicKeys, options)\n .catch((error: unknown) => {\n console.error('Failed to load dynamic reference data:', error);\n });\n\n loadPromises.push(dynamicPromise);\n }\n\n if (this.staticListKeys && this.staticListKeys.length > 0) {\n const staticPromise = this.refDataService\n .loadStaticRefs(this.staticListKeys)\n .catch((error: unknown) => {\n console.error('Failed to load static lists:', error);\n });\n\n loadPromises.push(staticPromise);\n }\n\n if (loadPromises.length === 0) {\n this.refDataLoaded$.next();\n return;\n }\n\n try {\n await Promise.all(loadPromises);\n this.refDataLoaded$.next();\n } catch (error) {\n console.error('Failed to load reference data:', error);\n this.refDataLoaded$.next();\n }\n }\n\n async refreshReferenceData(keys?: string[]) {\n const keysToRefresh = keys || Object.keys(this.referentialKeys || {});\n\n if (keysToRefresh.length === 0) {\n return;\n }\n\n try {\n await this.refDataService.refreshKeys(keysToRefresh, true);\n this.toastService.showSuccess('Reference data refreshed successfully', 'Success');\n } catch (error) {\n console.error('Failed to refresh reference data:', error);\n this.toastService.showError('Failed to refresh reference data', 'Error');\n }\n }\n\n async refreshStaticLists() {\n if (!this.staticListKeys || this.staticListKeys.length === 0) {\n return;\n }\n\n try {\n await this.refDataService.loadStaticRefs(this.staticListKeys, true);\n this.toastService.showSuccess('Static lists refreshed successfully', 'Success');\n } catch (error) {\n console.error('Failed to refresh static lists:', error);\n this.toastService.showError('Failed to refresh static lists', 'Error');\n }\n }\n\n async invalidateReference(key: string) {\n await this.refDataService.invalidateKeys([key]);\n }\n\n async invalidateReferences(keys: string[]) {\n await this.refDataService.invalidateKeys(keys);\n }\n\n /** The record the user acted on carries no id — it was removed by someone\n * else, the list is stale, or the route points at nothing. Say that,\n * rather than the internal \"Item [id] is undefined!\" this used to ship\n * to end users. Lives on the common base so every screen abstract\n * (search, detail and sub in V1 and V2, plus report-v2) says the same\n * thing — four copies of one string is how this file set drifts. */\n protected recordNotFound(): void {\n this.toastService.show({ severity: 'error', textKey: 'ef_error_record_not_found' });\n }\n\n handleErrors(errors: string[]) {\n if (errors && errors.length > 0) {\n errors.forEach(error => this.toastService.showError(error, 'Erreur de validation'));\n } else {\n this.toastService.showError('Une erreur inconnue est survenue', 'Erreur');\n }\n }\n\n setServerErrors(errors: { [key: string]: string[] }) {\n // Backend (FluentValidation) keys are PascalCase (e.g. `ClientType`);\n // template field bindings and the camelCased `setFormErrors` path use\n // camelCase. Normalize here so screens can read `serverErrors()['clientType']`\n // and pass it straight to an `ef-*` control's `[errors]` input.\n const normalized: { [key: string]: string[] } = {};\n if (errors) {\n Object.keys(errors).forEach((key) => {\n normalized[AppUtils.toCamelCase(key)] = errors[key];\n });\n }\n this.serverErrors.set(normalized);\n }\n\n /* ── Persisted date range ───────────────────────────────────────\n Opt-in. A screen that wants its period to survive a refresh\n calls `restorePersistedDateRange()` once, before its first\n load, and `persistDateRange()` from `onDateRangeChange()`.\n `AbstractReportScreenV2` already does both; list screens can\n opt in the same way. */\n\n private _dateRangeState?: PersistedState<EfDateRange>;\n\n /** Storage key for the persisted period. Namespaced by the screen\n * code so two dashboards never share a period. */\n protected dateRangeStateKey(): string {\n return `SCREEN_DATE_RANGE_${this.getConfig()?.SCREEN ?? 'UNKNOWN'}`;\n }\n\n protected dateRangeState(): PersistedState<EfDateRange> {\n return (this._dateRangeState ??= this.persisted<EfDateRange>(this.dateRangeStateKey(), {\n revive: raw => AbstractScreenComponent.reviveDateRange(raw),\n }));\n }\n\n /**\n * The period to open on: the one the user last chose, or `fallback`\n * when there is nothing stored.\n *\n * A relative preset is recomputed rather than replayed — someone who\n * picked \"This month\" in September and comes back in October means\n * October, not a frozen September window. Only `'custom'` restores\n * the literal dates, which is the case that has no other meaning.\n * Pass `fromPreset` (a screen's own preset resolver) to get that;\n * without it, a stored preset falls back to the default.\n */\n protected restorePersistedDateRange(\n fallback: EfDateRange,\n fromPreset?: (key: EfDatePresetKey) => EfDateRange,\n ): EfDateRange {\n const stored = this.dateRangeState().read();\n if (!stored) return fallback;\n if (stored.presetKey === 'custom') return stored;\n return fromPreset ? fromPreset(stored.presetKey) : fallback;\n }\n\n protected persistDateRange(range: EfDateRange): void {\n this.dateRangeState().write(range);\n }\n\n protected clearPersistedDateRange(): void {\n this.dateRangeState().clear();\n }\n\n /** JSON gives back ISO strings; hand back real `Date`s or nothing. */\n private static reviveDateRange(raw: unknown): EfDateRange | null {\n const v = raw as Partial<EfDateRange> | null;\n if (!v || typeof v !== 'object' || !v.presetKey) return null;\n const start = new Date(v.start as unknown as string);\n const end = new Date(v.end as unknown as string);\n if (isNaN(start.getTime()) || isNaN(end.getTime())) return null;\n return {\n start,\n end,\n presetKey: v.presetKey,\n label: v.label ?? '',\n labelKey: v.labelKey,\n };\n }\n\n clearServerErrors() {\n this.serverErrors.set({});\n }\n\n /** V1 only: disables the controls of `entityForm`. A no-op on V2\n * screens, which use `readOnlyMode()` + `[efReadOnly]`. */\n disableAllControls() {\n setTimeout(() => {\n if (this.entityForm && Object.keys(this.entityForm.controls).length > 0) {\n const controlNames = Object.keys(this.entityForm.controls);\n controlNames.forEach(controlName => {\n const control = this.entityForm.controls[controlName];\n if (control) {\n control.disable();\n }\n });\n }\n }, 10);\n }\n}\n","export enum ScreenStateEnum {\n READ_ONLY = 'READ_ONLY',\n DETAIL = 'DETAIL',\n SEARCH = 'SEARCH',\n CUSTOM = 'CUSTOM',\n REPORT = 'REPORT',\n}\n\nexport enum StateUtilsEnum {\n REMOVE = 'removeState',\n ADD = 'addState',\n DUPLICATE = 'duplicateState',\n EDIT = 'editState',\n EDIT_AFTER_ERROR = 'editAfterErrorState',\n ADD_AFTER_ERROR = 'addAfterErrorState',\n SAVE = 'afterSaveState',\n}\n","import { AbstractEntity } from '../abstract/abstract.entity';\n\nexport class ViewModelEntity extends AbstractEntity {\n constructor(entity: Record<string, unknown>) {\n super();\n this.clone(entity as unknown as AbstractEntity);\n }\n}\n","import {\n AfterViewInit,\n Component,\n inject,\n Injector,\n OnDestroy,\n OnInit,\n} from '@angular/core';\nimport { ScreenStateEnum } from '../../config/screen-state.enum';\nimport { ViewModelEntity } from '../../entities/view-model.entity';\nimport { AbstractScreenComponent } from './abstract-screen.component';\nimport { Location } from '@angular/common';\nimport { combineLatest } from 'rxjs';\n\n@Component({\n template: '',\n})\nexport abstract class AbstractDetailScreenComponent\n extends AbstractScreenComponent\n implements AfterViewInit, OnInit, OnDestroy\n{\n protected readonly screenState = ScreenStateEnum.DETAIL;\n\n entity: any = {};\n entityId: any;\n editionState = false;\n duplicateMode = false;\n\n private location = inject(Location);\n protected injector = inject(Injector);\n private serviceInstance: any;\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.serviceInstance = this.injector.get(this.getConfig()!.SERVICE as any);\n\n const screenConfig = this.getConfig();\n if (screenConfig) {\n const hasDynamicRefs = (screenConfig.DETAILS_REFERENTIALS_KEYS?.length ?? 0) > 0;\n const hasStaticLists = (screenConfig.DETAILS_STATIC_LISTS?.length ?? 0) > 0;\n\n if (hasDynamicRefs) {\n this.initializeReferenceKeys(screenConfig.DETAILS_REFERENTIALS_KEYS);\n }\n if (hasStaticLists) {\n this.initializeStaticLists(screenConfig.DETAILS_STATIC_LISTS);\n }\n if (hasDynamicRefs || hasStaticLists) {\n this.loadReferenceData(screenConfig.REF_DATA_OPTIONS);\n }\n }\n }\n\n override ngAfterViewInit(): void {\n super.ngAfterViewInit();\n combineLatest([this.route.paramMap, this.route.queryParamMap]).subscribe(\n ([params, queryParams]) => {\n this.entityId = params.get('id');\n this.duplicateMode = queryParams.get('mode') === 'duplicate';\n this.context.duplicateMode = this.duplicateMode;\n\n if (this.entityId) {\n this.editionState = !this.duplicateMode;\n this.loadData();\n } else {\n this.editionState = false;\n this.duplicateMode = false;\n this.context.duplicateMode = false;\n }\n },\n );\n }\n\n public loadData(): void {\n try {\n this.serviceInstance.get(this.entityId).subscribe({\n next: (result: any) => {\n this.entity = new ViewModelEntity(result);\n this.entity.id = this.entityId;\n this.afterLoad();\n },\n error: (_error: any) => {\n // Errors handled by global error handler\n },\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n protected afterLoad() {\n this.changeDetector.detectChanges();\n }\n\n abstract beforeSave(): void;\n\n save() {\n try {\n this.beforeSave();\n this.clearServerErrors();\n\n const isCreateOperation = !this.editionState || this.duplicateMode;\n const entityToSave = this.duplicateMode\n ? this.prepareEntityForDuplication()\n : this.entity;\n\n const saveOperation = isCreateOperation\n ? this.serviceInstance.create(entityToSave)\n : this.serviceInstance.update(this.entityId, this.entity);\n\n saveOperation.subscribe({\n next: (response: any) => {\n if (response && response.errors && response.errors.length > 0) {\n this.handleErrors(response.errors);\n } else {\n this.toastService.showSuccess();\n this.afterSave(response);\n }\n },\n error: (response: any) => {\n console.log(response);\n if (response.errors) {\n this.setServerErrors(response.errors);\n this.setFormErrors(response.errors);\n this.onSaveError(response.errors);\n }\n },\n });\n } catch (error: any) {\n this.toastService.showError(\n error?.message || \"Une erreur est survenue lors de l'enregistrement\",\n );\n }\n }\n\n protected onSaveError(_errors: { [key: string]: string[] }) {\n // Override in subclass to handle validation errors\n }\n\n protected afterSave(result: any) {\n const screenConfig = this.getConfig();\n if (screenConfig?.INVALIDATE_KEYS_ON_SAVE) {\n this.invalidateReferences(screenConfig.INVALIDATE_KEYS_ON_SAVE);\n\n if (screenConfig.REFRESH_ON_SAVE) {\n this.refreshReferenceData(screenConfig.INVALIDATE_KEYS_ON_SAVE);\n }\n }\n\n if (!this.editionState || this.duplicateMode) {\n const baseUrl = this.currentUrl.split('?')[0];\n const detailsIndex = baseUrl.indexOf('/details');\n const cleanBaseUrl =\n detailsIndex !== -1\n ? baseUrl.substring(0, detailsIndex + '/details'.length)\n : baseUrl;\n this.router.navigate([cleanBaseUrl, result]);\n return;\n }\n }\n\n protected prepareEntityForDuplication(): any {\n const duplicatedEntity = { ...this.entity };\n delete duplicatedEntity.id;\n delete duplicatedEntity.Id;\n return this.customizeDuplicatedEntity(duplicatedEntity);\n }\n\n protected customizeDuplicatedEntity(entity: any): any {\n return entity;\n }\n\n duplicate() {\n const baseUrl = this.currentUrl.split('?')[0];\n this.router.navigate([baseUrl], {\n queryParams: { mode: 'duplicate' },\n });\n }\n\n print() {\n // Override in subclass to implement print functionality\n }\n\n /**\n * Name of the record being deleted, so the confirmation can say what\n * it is about to destroy rather than asking about \"this item\".\n * Override in the screen and return whatever a user recognises the\n * record by — `return this.entity?.name;` is the usual body.\n */\n protected getDeleteConfirmName(): string | undefined {\n return undefined;\n }\n\n delete(): void {\n if (!this.entityId) {\n this.recordNotFound();\n return;\n }\n\n this.confirmDialogService.confirm({\n intent: 'delete',\n name: this.getDeleteConfirmName(),\n accept: () =>\n this.serviceInstance.delete(this.entityId).subscribe({\n next: (result: any) => {\n if (result && result.errors && result.errors.length > 0) {\n this.handleErrors(result.errors);\n } else {\n this.toastService.showSuccess();\n this.navigateBack();\n }\n },\n error: () => {\n // Errors handled by global error handler\n },\n }),\n });\n }\n\n navigateBack() {\n const currentUrl = this.router.url.split('?')[0];\n const detailsIndex = currentUrl.indexOf('/details');\n if (detailsIndex !== -1) {\n this.router.navigate([currentUrl.substring(0, detailsIndex)]);\n } else {\n this.location.back();\n }\n }\n}\n","import { AbstractEntity } from '../abstract/abstract.entity';\n\nexport enum SortDirectionEnum {\n ASC = 'Ascending',\n DESC = 'Descending',\n DEFAULT_SORT_FIELD = 'id',\n}\n\nexport enum PaginationEnum {\n DEFAULT_PAGE = 1,\n DEFAULT_PAGE_SIZE = 10,\n}\n\nexport class SearchEntity extends AbstractEntity {\n pagination: { pageNumber: number; pageSize: number } = {\n pageNumber: PaginationEnum.DEFAULT_PAGE,\n pageSize: PaginationEnum.DEFAULT_PAGE_SIZE,\n };\n\n sort: Array<{ field: string; sortDirection: string }> = [];\n\n totalPages = 0;\n totalCount = 0;\n items: AbstractEntity[] = [];\n start: Date | null = null;\n end: Date | null = null;\n startEndDateRanges: Date[] | null = null;\n\n constructor(entity: Record<string, unknown>) {\n super();\n this.buildEntity(entity);\n\n if (!this.pagination) {\n this.pagination = {\n pageNumber: PaginationEnum.DEFAULT_PAGE,\n pageSize: PaginationEnum.DEFAULT_PAGE_SIZE,\n };\n }\n\n if (!this.sort) {\n this.sort = [{ field: SortDirectionEnum.DEFAULT_SORT_FIELD, sortDirection: SortDirectionEnum.DESC }];\n }\n\n if (!this.startEndDateRanges && entity['start'] && entity['end']) {\n this.startEndDateRanges = [new Date(entity['start'] as string), new Date(entity['end'] as string)];\n }\n }\n\n getSearchCriteria(): Record<string, unknown> {\n const { items: _items, totalPages: _totalPages, totalCount: _totalCount, ...criteria } = this;\n return criteria;\n }\n}\n","import {\n AfterViewInit,\n Component,\n inject,\n Injector,\n OnDestroy,\n OnInit,\n ViewChild,\n} from '@angular/core';\nimport { ScreenStateEnum } from '../../config/screen-state.enum';\nimport { ViewModelEntity } from '../../entities/view-model.entity';\nimport { SearchEntity, SortDirectionEnum } from '../../entities/search.entity';\nimport { AbstractScreenComponent } from './abstract-screen.component';\nimport { Table, TableLazyLoadEvent } from 'primeng/table';\nimport { take } from 'rxjs';\n\n/**\n * Column definition interface for ef-datatable integration.\n * Kept minimal here to avoid circular dependency on @elasticias/ui.\n */\nexport interface ScreenDatatableColumn {\n field: string;\n header: string;\n type?: string;\n [key: string]: any;\n}\n\n@Component({\n template: '',\n standalone: true,\n})\nexport abstract class AbstractSearchScreenComponent\n extends AbstractScreenComponent\n implements AfterViewInit, OnInit, OnDestroy\n{\n protected readonly screenState = ScreenStateEnum.SEARCH;\n\n @ViewChild('pTable') pTable!: Table;\n\n entity: any = new ViewModelEntity({});\n searchEntity = new SearchEntity(this.entity);\n enableDateRangeFilter = true;\n isLazySearch = true;\n lastSearchEvent: TableLazyLoadEvent | null = null;\n\n tableColumns: any[] = [];\n\n protected injector = inject(Injector);\n private serviceInstance: any;\n private isInitialLoad = true;\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.serviceInstance = this.injector.get(this.getConfig()!.SERVICE as any);\n\n this.tableColumns = this.getTableColumns();\n\n const screenConfig = this.getConfig();\n const hasDynamicRefs = (screenConfig?.SEARCH_REFERENTIALS_KEYS?.length ?? 0) > 0;\n const hasStaticLists = (screenConfig?.SEARCH_STATIC_LISTS?.length ?? 0) > 0;\n\n if (hasDynamicRefs || hasStaticLists) {\n if (hasDynamicRefs) {\n this.initializeReferenceKeys(screenConfig!.SEARCH_REFERENTIALS_KEYS);\n }\n\n if (hasStaticLists) {\n this.initializeStaticLists(screenConfig!.SEARCH_STATIC_LISTS);\n }\n\n this.loadReferenceData(screenConfig!.REF_DATA_OPTIONS);\n\n this.refDataLoaded$.pipe(take(1)).subscribe(() => {\n this.triggerSearchIfNeeded();\n });\n } else {\n this.triggerSearchIfNeeded();\n }\n }\n\n protected getTableColumns(): any[] {\n return [];\n }\n\n private triggerSearchIfNeeded() {\n const cachedCriteria = this.cacheService.getCache<any>(this.screenStateKey);\n if (cachedCriteria) {\n this.searchEntity = new SearchEntity(cachedCriteria);\n this.entity.buildEntity(this.searchEntity);\n this.searchEntity.items = [];\n\n if (this.searchEntity.startEndDateRanges) {\n this.entity.startEndDateRanges = [\n new Date(this.searchEntity.start!),\n new Date(this.searchEntity.end!),\n ];\n }\n\n this.changeDetector.detectChanges();\n this.search();\n } else {\n this.search();\n }\n }\n\n onLazyLoad(event: TableLazyLoadEvent): void {\n if (this.isInitialLoad) {\n this.isInitialLoad = false;\n return;\n }\n\n if (this.isReactiveBindingEcho(event)) {\n return;\n }\n\n this.search(event);\n }\n\n private isReactiveBindingEcho(event: TableLazyLoadEvent): boolean {\n if (!this.searchEntity.sort || this.searchEntity.sort.length === 0) {\n return false;\n }\n\n const currentSort = this.searchEntity.sort[0];\n const eventSortField = Array.isArray(event.sortField)\n ? event.sortField[0]\n : event.sortField;\n const eventSortDirection =\n event.sortOrder === 1 ? SortDirectionEnum.ASC : SortDirectionEnum.DESC;\n\n const currentPage = this.searchEntity.pagination?.pageNumber || 1;\n const currentPageSize = this.searchEntity.pagination?.pageSize || 10;\n const eventPage = this.getPageNumber(event);\n const eventPageSize = event.rows || 10;\n\n return (\n currentSort.field === eventSortField &&\n currentSort.sortDirection === eventSortDirection &&\n currentPage === eventPage &&\n currentPageSize === eventPageSize\n );\n }\n\n private prepareSearch(event: TableLazyLoadEvent | null): void {\n this.searchEntity.buildEntity(this.entity);\n const e = event || this.lastSearchEvent || { first: 0, rows: 10 };\n\n this.searchEntity.pagination = {\n pageNumber: this.getPageNumber(e),\n pageSize: e.rows || 10,\n };\n\n if (this.entity.startEndDateRanges) {\n this.searchEntity.start = this.entity.startEndDateRanges[0];\n this.searchEntity.end = this.entity.startEndDateRanges[1];\n } else {\n this.searchEntity.start = null;\n this.searchEntity.end = null;\n }\n\n if (this.isLazySearch) {\n if (e.sortField) {\n const sortField = this.getSortField(e);\n this.searchEntity.sort = [\n {\n field: sortField,\n sortDirection: this.getSortDirection(e),\n },\n ];\n } else if (!this.searchEntity.sort || this.searchEntity.sort.length === 0) {\n const defaultSort = this.getConfig()?.DEFAULT_SORT;\n this.searchEntity.sort = [\n {\n field: defaultSort?.field || 'id',\n sortDirection: defaultSort?.direction || SortDirectionEnum.DESC,\n },\n ];\n }\n }\n }\n\n protected search(event: TableLazyLoadEvent | null = null): void {\n this.prepareSearch(event);\n\n this.serviceInstance.search(this.searchEntity).subscribe({\n next: (result: any) => {\n this.lastSearchEvent = event;\n this.searchEntity = Object.assign(new SearchEntity({}), this.searchEntity, result);\n this.cacheService.setCache(this.screenStateKey, this.searchEntity);\n this.changeDetector.detectChanges();\n },\n error: () => {\n // Errors handled by global error handler\n },\n });\n }\n\n paginate(event: any) {\n const pageNumber = this.getPageNumber(event);\n const pageSize = event.rows;\n\n this.searchEntity.pagination.pageNumber = pageNumber;\n this.searchEntity.pagination.pageSize = pageSize;\n\n if (\n this.searchEntity.items == null ||\n this.searchEntity.items.length === 0\n ) {\n return;\n }\n }\n\n getPageNumber(event: TableLazyLoadEvent): number {\n return event.first != null\n ? Math.floor(event.first / (event.rows || 10)) + 1\n : 1;\n }\n\n getSortField(event: TableLazyLoadEvent): string {\n return Array.isArray(event.sortField)\n ? event.sortField[0]\n : event.sortField || 'id';\n }\n\n getSortDirection(event: TableLazyLoadEvent): string {\n return event.sortOrder === 1\n ? SortDirectionEnum.ASC\n : SortDirectionEnum.DESC;\n }\n\n navigateToDetails(id?: any): void {\n const path =\n id || id === 0\n ? `${this.currentUrl}/details/${id}`\n : `${this.currentUrl}/details`;\n this.router.navigate([path]);\n }\n\n add() {\n this.router.navigate([this.currentUrl.concat('/details')]);\n }\n\n edit(id: any) {\n if (!id) {\n this.recordNotFound();\n return;\n }\n this.router.navigate([this.currentUrl.concat('/details/'), id]);\n }\n\n /**\n * Name of the row being deleted, so the confirmation can say what it\n * is about to destroy rather than asking about \"this item\". Override\n * in the screen — look the row up in the loaded results and return\n * whatever a user would recognise it by.\n *\n * ```ts\n * protected override getDeleteConfirmName(id: any) {\n * return this.searchEntity.items?.find((r: any) => r.id === id)?.name;\n * }\n * ```\n */\n protected getDeleteConfirmName(_id: any): string | undefined {\n return undefined;\n }\n\n delete(id: any): void {\n if (!id) {\n this.recordNotFound();\n return;\n }\n\n this.confirmDialogService.confirm({\n intent: 'delete',\n name: this.getDeleteConfirmName(id),\n accept: () =>\n this.serviceInstance.delete(id).subscribe({\n next: (result: any) => {\n if (result && result.errors && result.errors.length > 0) {\n this.handleErrors(result.errors);\n } else {\n this.search();\n this.toastService.showSuccess();\n }\n },\n error: () => {\n // Errors handled by global error handler\n },\n }),\n });\n }\n\n duplicate(id: any) {\n if (!id) {\n this.recordNotFound();\n return;\n }\n this.router.navigate(\n [this.currentUrl.concat('/details/'), id],\n { queryParams: { mode: 'duplicate' } }\n );\n }\n\n clear(): void {\n this.entity.clearFields();\n this.searchEntity.clearFields();\n this.searchEntity = new SearchEntity({});\n\n this.lastSearchEvent = null;\n this.isInitialLoad = true;\n\n this.cacheService.setCache(this.screenStateKey, this.searchEntity);\n\n if (this.pTable) {\n this.pTable.first = 0;\n this.pTable.reset();\n }\n\n this.changeDetector.detectChanges();\n }\n\n ngOnDestroy(): void {\n this.destroyed$.next();\n this.destroyed$.complete();\n }\n}\n","import {\n Component,\n computed,\n inject,\n Injector,\n OnDestroy, OnInit,\n signal,\n} from '@angular/core';\nimport { take } from 'rxjs';\nimport { AbstractScreenComponent } from './abstract-screen.component';\nimport { ScreenStateEnum } from '../../config/screen-state.enum';\nimport { ActiveFilter } from '../../entities/active-filter.entity';\nimport { CsvUtils } from '@elasticias/utils';\nimport { TranslateService } from '@ngx-translate/core';\nimport {\n EfDataCardColumn,\n EfDataCardExportRequest,\n EfDataCardSort,\n EfReferenceColumnOpts,\n} from '../../entities/data-card-column.entity';\nimport { EfDateRange } from '../../entities/date-range.entity';\nimport {\n PaginationEnum,\n SearchEntity,\n SortDirectionEnum,\n} from '../../entities/search.entity';\n\n/**\n * Declarative definition of an advanced-search select filter rendered in\n * the filter drawer. One `<ef-select>` is rendered per entry; the screen\n * stays type-agnostic — `key` is simply the criteria property name sent to\n * the backend (which must expose a matching typed query prop, e.g.\n * `CityIds: List<int>`, `ClientIds: List<string>`, a scalar code, …). Works\n * for both single-select (`multiple` omitted/false → scalar value) and\n * multi-select (`multiple: true` → array value).\n */\nexport interface AdvancedSelectFilter {\n /** Criteria property name sent to the backend (must match a typed query prop). */\n key: string;\n /** Reference-data key supplying the options (e.g. `'cities'`). */\n refKey: string;\n /** i18n key for the field label (rendered by `ef-select`). */\n labelKey: string;\n /** Multi-select when `true` (array value); single-select otherwise (scalar). */\n multiple?: boolean;\n /** Option value field (default `'code'`). */\n valueField?: string;\n /** Option label field (default `'label'`). */\n labelField?: string;\n /** Placeholder i18n key (default `'common_all'`). */\n placeholderKey?: string;\n}\n\n/**\n * Signal-first counterpart to {@link AbstractSearchScreenComponent}.\n *\n * Built for V2 + zoneless apps: state is exposed as signals\n * (`items`, `loading`, `errorMsg`, `totalCount`, `criteria`) and the\n * class is intentionally **decoupled from PrimeNG `<p-table>`** —\n * subclasses render however they want (Comptoir `.tbl` patterns,\n * cards, virtual lists, …) and call the helpers below to mutate the\n * search criteria + re-execute.\n *\n * Same `ScreenConfig` surface as the legacy abstract:\n * - `SCREEN` (string code matching backend grants)\n * - `SERVICE` (NSwag client class with `search(criteria)` method)\n * - `SEARCH_REFERENTIALS_KEYS` / `SEARCH_STATIC_LISTS` for ref-data\n * - `DEFAULT_SORT` for first load\n *\n * Subclasses typically:\n *\n * ```ts\n * @Component({ ... })\n * export class FooComponent extends AbstractSearchScreenV2<FooDto> {\n * protected override getConfig() { return FooConfig; }\n * readonly rows = computed(() => this.items().map(toRow));\n * }\n * ```\n */\n@Component({ template: '', standalone: true })\nexport abstract class AbstractSearchScreenV2<TItem = any>\n extends AbstractScreenComponent\n implements OnInit\n{\n protected readonly screenState = ScreenStateEnum.SEARCH;\n protected readonly injector = inject(Injector);\n private serviceInstance: any;\n\n /**\n * Translate lazily, through the injector.\n *\n * Taking `TranslateService` as a field injection makes it a hard\n * construction-time requirement of every screen that extends this base,\n * which is more than the one method needing it deserves — and it is the\n * same shape as the DI cycle ADR-021 records in the app. Resolving it\n * here keeps the dependency optional: an app without ngx-translate gets\n * the key back rather than a crash.\n */\n protected t(key: string, params?: Record<string, unknown>): string {\n const translate = this.injector.get(TranslateService, null);\n return translate ? translate.instant(key, params) : key;\n }\n\n /** Monotonic guard: bumped on every `search()` call so an\n * out-of-order (stale) response from an earlier search can be\n * dropped instead of overwriting the latest results. */\n private searchSeq = 0;\n\n /** Current search results — populated after each `search()`. */\n readonly items = signal<TItem[]>([]);\n readonly totalCount = signal(0);\n readonly loading = signal(false);\n readonly errorMsg = signal<string | null>(null);\n\n /** Live search criteria (paging, sort, text, dates, custom). */\n readonly criteria = signal<SearchEntity>(new SearchEntity({}));\n\n /**\n * Active date-range filter shown in `ef-datepicker-advanced`'s\n * trigger. Display-only at construction time — actually filters\n * the search once `onDateRangeChange()` fires (or a screen wires\n * one in `ngOnInit`).\n *\n * Override `buildDefaultDateRange()` per screen to ship a\n * different starting preset.\n */\n readonly dateRange = signal<EfDateRange>(this.buildDefaultDateRange());\n\n /* ── Filter-bar UI state (DRY) ──────────────────────────────────\n Identical across every list screen — lifted up so subclasses\n don't re-declare. `clear()` resets all four signals. */\n\n /** Free-text search input value — bound `[(searchText)]` on\n * ef-smart-bar; drives `runSearch()`. */\n readonly searchQuery = signal('');\n\n /** Active status pill-group selection (defaults to `'all'`). */\n readonly statusFilter = signal<string>('all');\n\n /** Whether the advanced-filter drawer is open. */\n readonly drawerOpen = signal(false);\n\n /** Active named filter chips shown in the smart-bar. */\n readonly activeFilters = signal<ActiveFilter[]>([]);\n\n /* ── Advanced-filter selects (DRY) ──────────────────────────────\n Declarative `<ef-select>` filters rendered in the filter drawer.\n Override `advancedFilters` per screen; the base owns the value\n state, the apply→criteria push, and the reset. Type-agnostic:\n each `key` maps to a typed backend query prop of any shape. */\n\n /** Advanced-filter select definitions. Empty = no advanced filters. */\n readonly advancedFilters: AdvancedSelectFilter[] = [];\n\n /** Criteria key of the screen's activation tri-state filter\n * (`ef-activation-filter`), e.g. `'isActive'`. When set, the base\n * applies, baseline-clears, and cache-restores the boolean like any\n * declared advanced filter — the screen only binds the component to\n * `advancedValues()` / `setAdvancedValue()`. `null` = no activation\n * filter. */\n protected readonly activationFilterKey: string | null = null;\n\n /** Live values per advanced filter, keyed by `AdvancedSelectFilter.key`. */\n readonly advancedValues = signal<Record<string, unknown>>({});\n\n /** Store the picked value(s) for one advanced filter (no search yet —\n * the drawer's `(apply)` runs it). */\n setAdvancedValue(key: string, value: unknown): void {\n this.advancedValues.update((v) => ({ ...v, [key]: value }));\n }\n\n /** Push every advanced-filter value into the criteria as typed\n * top-level props and re-run the search. Wired to the drawer's\n * `(apply)`. Every DECLARED key is written on apply — a cleared\n * control must actively remove its (possibly cache-restored)\n * criteria value, not silently leave it behind. */\n applyAdvancedFilters(): void {\n const patch: Record<string, any> = {};\n for (const f of this.advancedFilters) patch[f.key] = undefined;\n if (this.activationFilterKey) patch[this.activationFilterKey] = undefined;\n Object.assign(patch, this.advancedValues());\n this.patchCriteria(patch);\n }\n\n /* ── Selection (DRY) ────────────────────────────────────────────\n Per-row checkbox state, used by `ef-bulk-bar` and the auto\n row-actions cell. */\n\n /** Selected row ids — keyed by `String(rowId(row))`. */\n readonly selected = signal<ReadonlySet<string>>(new Set());\n\n /** Live count derived from `selected`. */\n readonly selectionCount = computed(() => this.selected().size);\n\n /* ── Sort indicator (DRY) ───────────────────────────────────────\n ef-data-card consumes `[sort]` as `{ field, direction: 'asc' |\n 'desc' }`. The base criteria stores the legacy\n 'Ascending' / 'Descending' strings — convert lazily here. */\n\n readonly currentSort = computed<EfDataCardSort | null>(() => {\n const s = this.criteria().sort?.[0];\n if (!s?.field) return null;\n return {\n field: s.field,\n direction: (s.sortDirection ?? '').toLowerCase().startsWith('asc')\n ? 'asc'\n : 'desc',\n };\n });\n\n /* ── Row-actions standard surface ───────────────────────────────\n Subclasses can flip these off when a particular CRUD action\n isn't applicable. Defaults are all-on; permission filtering\n still happens at render time via ScreenContext, so an action\n that the user can't perform is hidden regardless of these\n flags. */\n\n readonly showViewAction = signal(true);\n readonly showEditAction = signal(true);\n readonly showDuplicateAction = signal(true);\n readonly showDeleteAction = signal(true);\n\n /**\n * PK accessor for a row. Default returns `row?.id` — override when\n * the backend names its primary key something else (e.g. sales-orders'\n * `orderId`). Used by the row-actions dispatcher and as the implicit\n * navigateToDetails / edit / delete argument.\n */\n rowId(row: any): any {\n return row?.id;\n }\n\n /**\n * Dispatch helper wired to ef-data-card's `(rowAction)` output and\n * the auto-rendered row-actions cell. Routes the standard four\n * actions to the inherited methods so subclasses don't have to\n * declare per-screen rowActions arrays.\n */\n onRowAction(\n action: 'view' | 'edit' | 'duplicate' | 'delete',\n row: any,\n ): void {\n const id = this.rowId(row);\n switch (action) {\n case 'view':\n this.navigateToDetails(id);\n break;\n case 'edit':\n this.edit(id);\n break;\n case 'duplicate':\n this.duplicate(id);\n break;\n case 'delete':\n this.delete(id);\n break;\n }\n }\n\n /* ── Date-range filter (DRY) ────────────────────────────────────\n Wired to ef-datepicker-advanced. The default range is\n `last_30_days` — override `buildDefaultDateRange()` per screen\n if a different starting preset is needed. */\n\n /**\n * Wired to `<ef-datepicker-advanced (rangeChange)>` — stores the\n * range for trigger display and pushes it into the search criteria\n * so the next `search()` filters by it.\n */\n onDateRangeChange(range: EfDateRange): void {\n this.dateRange.set(range);\n this.setDateRange(range.start, range.end);\n }\n\n /**\n * Reset the date range to the default. Called automatically by\n * `clear()` so screens don't have to remember to invoke it from\n * their own `clearAll()` orchestration.\n */\n protected resetDateRange(): void {\n this.dateRange.set(this.buildDefaultDateRange());\n }\n\n /**\n * Build the default `EfDateRange`. Override per screen to ship a\n * different default — e.g., a 90-day window for low-velocity\n * catalogues. Default: last 30 days.\n */\n protected buildDefaultDateRange(): EfDateRange {\n return {\n start: this.daysAgo(29),\n end: this.startOfToday(),\n presetKey: 'last_30_days',\n labelKey: 'date_preset_last_30_days',\n label: '30 derniers jours',\n };\n }\n\n /** Today at 00:00 local time. */\n protected startOfToday(): Date {\n const d = new Date();\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n }\n\n /** N days before today, at 00:00 local time. */\n protected daysAgo(n: number): Date {\n const t = this.startOfToday();\n t.setDate(t.getDate() - n);\n return t;\n }\n\n /* ── Filter-bar handlers (DRY) ──────────────────────────────────\n Wired to ef-smart-bar / pill-group / filter-drawer / chip\n removal. None of these need overriding — subclasses use them\n through inherited template bindings. */\n\n /** Wired to filter-drawer's `(apply)` — pushes the current\n * searchQuery into the criteria and re-runs the search. */\n runSearch(): void {\n this.setSearchText(this.searchQuery());\n }\n\n /** Pill-group click handler. Stores the selected status code; the\n * search itself only re-runs once the consumer pushes the value\n * into the criteria (or wires it via beforeSearch). */\n setStatus(key: string): void {\n this.statusFilter.set(key);\n }\n\n toggleDrawer(): void {\n this.drawerOpen.update((o) => !o);\n }\n\n /** Drop a chip from the active-filters list. */\n removeFilter(key: string): void {\n this.activeFilters.update((filters) =>\n filters.filter((f) => f.key !== key),\n );\n }\n\n /* ── Selection helpers (DRY) ────────────────────────────────────\n Mutate `selected` (Set<string>); template binds via\n `[checked]=\"isSelected(rowId(row))\"` and\n `(change)=\"toggleSelection(rowId(row))\"`. */\n\n toggleSelection(id: string): void {\n this.selected.update((set) => {\n const next = new Set(set);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }\n\n /** Toggle every visible row in or out of the selection in one shot. */\n toggleAllSelection(): void {\n const all = this.items().map((item) => String(this.rowId(item)));\n this.selected.update((set) =>\n set.size === all.length ? new Set() : new Set(all),\n );\n }\n\n isSelected(id: string): boolean {\n return this.selected().has(id);\n }\n\n /* ── Column builders (DRY) ──────────────────────────────────────\n Convenience helpers that return a fully-formed EfDataCardColumn\n with sensible per-type defaults. Pass `opts` to override any\n property — `opts` always wins over the builder's defaults. */\n\n /** Selection checkbox column — paired with `efColumnTemplate=\"select\"`\n * for the row's checkbox. 40px wide, no other props. */\n protected addSelectColumn(width = '40px'): EfDataCardColumn {\n return { id: 'select', width };\n }\n\n /** Plain text column. */\n protected addTextColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return { id: field, ...opts, field, headerKey, type: 'text' };\n }\n\n /** Monospace column — JetBrains Mono with tabular-nums; for codes,\n * IDs, refs, anything where character alignment matters. */\n protected addMonoColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return { id: field, ...opts, field, headerKey, type: 'mono' };\n }\n\n /** Number column — end-aligned, integer by default. Override\n * `minFractionDigits` / `maxFractionDigits` via opts for decimals. */\n protected addNumberColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return {\n id: field,\n minFractionDigits: 0,\n maxFractionDigits: 0,\n ...opts,\n field,\n headerKey,\n type: 'number',\n align: opts.align ?? 'end',\n };\n }\n\n /** Money column — end-aligned. ISO currency code defaults to `'MAD'`\n * (Elasticias' primary tenant locale); pass `opts.currencyCode` for\n * euros / USD / etc. */\n protected addMoneyColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return {\n id: field,\n currencyCode: 'MAD',\n ...opts,\n field,\n headerKey,\n type: 'money',\n align: opts.align ?? 'end',\n };\n }\n\n /** Date column — formats as `dd/MM/yyyy` by default. */\n protected addDateColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return { id: field, ...opts, field, headerKey, type: 'date' };\n }\n\n /** Datetime column — formats as `dd/MM/yyyy HH:mm` by default. */\n protected addDatetimeColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return { id: field, ...opts, field, headerKey, type: 'datetime' };\n }\n\n /** Boolean column — renders the `bool yes / bool no` indicator. */\n protected addBooleanColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return { id: field, ...opts, field, headerKey, type: 'boolean' };\n }\n\n /** Static-class chip column — renders `chip <chipPrefix><value>`.\n * Use `addStatusColumn` for reference_data-driven palettes. */\n protected addChipColumn(\n field: string,\n headerKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return {\n id: field,\n chipPrefix: 'chip-',\n ...opts,\n field,\n headerKey,\n type: 'chip',\n };\n }\n\n /** Status chip column — palette + label resolved from\n * `reference_data` via `referenceKey`. Sortable by default. */\n protected addStatusColumn(\n field: string,\n headerKey: string,\n referenceKey: string,\n opts: Partial<EfDataCardColumn> = {},\n ): EfDataCardColumn {\n return {\n id: field,\n sortable: true,\n ...opts,\n field,\n headerKey,\n type: 'status',\n referenceKey,\n };\n }\n\n /** Reference column — looks up `field`'s value in the reference\n * list keyed by `referenceKey`, renders the matching item's label.\n * Defaults: `valueField: 'id'`, `labelField: 'label'`. */\n protected addReferenceColumn(\n field: string,\n headerKey: string,\n referenceKey: string,\n opts: EfReferenceColumnOpts = {},\n ): EfDataCardColumn {\n const { valueField, labelField, ...rest } = opts;\n return {\n id: field,\n ...rest,\n field,\n headerKey,\n type: 'reference',\n referenceKey,\n referenceValueField: valueField ?? rest.referenceValueField ?? 'code',\n referenceLabelField: labelField ?? rest.referenceLabelField ?? 'label',\n };\n }\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.serviceInstance = this.injector.get(this.getConfig()!.SERVICE as any);\n\n const cfg = this.getConfig();\n const hasDynamicRefs = (cfg?.SEARCH_REFERENTIALS_KEYS?.length ?? 0) > 0;\n const hasStaticLists = (cfg?.SEARCH_STATIC_LISTS?.length ?? 0) > 0;\n\n // Busy from the first frame, not from the first request.\n //\n // A screen with referentials waits for them before it searches at all, and\n // `loading` used to stay false for that entire window — so the table spent\n // it showing \"nothing here yet\" to someone whose data was still being\n // fetched. Six of the twelve list screens take that branch, including the\n // one where this was measured at 910ms. `search()` sets the same flag\n // again when it finally runs, so setting it here is idempotent.\n this.loading.set(true);\n\n if (hasDynamicRefs || hasStaticLists) {\n if (hasDynamicRefs)\n this.initializeReferenceKeys(cfg!.SEARCH_REFERENTIALS_KEYS);\n if (hasStaticLists) this.initializeStaticLists(cfg!.SEARCH_STATIC_LISTS);\n this.loadReferenceData(cfg!.REF_DATA_OPTIONS);\n this.refDataLoaded$.pipe(take(1)).subscribe(() => {\n this.bootstrapInitialSearch();\n this.applyDeepLinkStatus();\n });\n } else {\n this.bootstrapInitialSearch();\n this.applyDeepLinkStatus();\n }\n }\n\n /**\n * Deep-link support: `/<list>?status=<code>` pre-selects the status\n * pill after the initial criteria bootstrap (so the reset doesn't\n * clobber it). Runs through `setStatus()`, so a subclass override\n * that pushes the status into the criteria (the usual pattern) gets\n * the deep-linked value too. No-op without the query param.\n */\n private applyDeepLinkStatus(): void {\n const status = this.queryParam('status');\n if (status) this.setStatus(status);\n }\n\n /** Restore criteria from cache (returning to a screen) or seed defaults. */\n private bootstrapInitialSearch(): void {\n const cached = this.cacheService.getCache<any>(this.screenStateKey);\n if (cached) {\n this.criteria.set(new SearchEntity(cached));\n this.restoreFilterUiFromCriteria(cached);\n } else {\n const cfg = this.getConfig();\n const fresh = new SearchEntity({});\n if (cfg?.DEFAULT_SORT) {\n fresh.sort = [\n {\n field: cfg.DEFAULT_SORT.field,\n sortDirection: cfg.DEFAULT_SORT.direction,\n },\n ];\n }\n fresh.pagination = {\n pageNumber: PaginationEnum.DEFAULT_PAGE,\n pageSize: PaginationEnum.DEFAULT_PAGE_SIZE,\n };\n this.criteria.set(fresh);\n }\n this.search();\n }\n\n /**\n * Cache-restore sync: when a revisit restores cached criteria,\n * reflect the restored filters back into the filter-bar UI state so\n * what the drawer / search box displays matches what the search will\n * actually send (otherwise a stale criteria filter keeps applying\n * while every control reads \"Tous\"). Base handles the free-text\n * input and the declared advanced filters; override (calling super)\n * to sync screen-specific state — status pill, custom switches, ….\n */\n protected restoreFilterUiFromCriteria(cached: Record<string, any>): void {\n this.searchQuery.set(cached['searchText'] ?? '');\n const next: Record<string, unknown> = {};\n for (const f of this.advancedFilters) {\n const value = cached[f.key];\n if (value !== undefined && value !== null) next[f.key] = value;\n }\n const activationKey = this.activationFilterKey;\n if (activationKey && typeof cached[activationKey] === 'boolean') {\n next[activationKey] = cached[activationKey];\n }\n if (Object.keys(next).length) {\n this.advancedValues.update((cur) => ({ ...cur, ...next }));\n }\n }\n\n /**\n * Run a search with the current `criteria()`. Always populates\n * `items` / `totalCount` / `loading` / `errorMsg` and persists the\n * criteria to cache on success so revisits can restore.\n */\n search(): void {\n this.loading.set(true);\n this.errorMsg.set(null);\n\n // Stale responses are dropped so the latest issued search always\n // wins, even if an earlier in-flight search resolves later.\n const seq = ++this.searchSeq;\n\n this.serviceInstance.search(this.criteria()).subscribe({\n next: (result: any) => {\n if (seq !== this.searchSeq) return;\n this.items.set((result?.items ?? []) as TItem[]);\n this.totalCount.set(result?.totalCount ?? 0);\n this.cacheService.setCache(this.screenStateKey, this.criteria());\n this.loading.set(false);\n },\n error: (err: any) => {\n if (seq !== this.searchSeq) return;\n console.error('Search failed', err);\n this.errorMsg.set(err?.message ?? 'Erreur de chargement');\n this.loading.set(false);\n },\n });\n }\n\n /* ── Convenience criteria mutators ───────────────────────────── */\n\n setSearchText(text: string): void {\n this.criteria.update((c) =>\n this.cloneCriteria(c, { searchText: text || undefined, page: 1 }),\n );\n this.search();\n }\n\n setPage(pageNumber: number, pageSize?: number): void {\n this.criteria.update((c) =>\n this.cloneCriteria(c, {\n page: pageNumber,\n pageSize: pageSize ?? c.pagination.pageSize,\n }),\n );\n this.search();\n }\n\n setSort(field: string, direction: string = SortDirectionEnum.DESC): void {\n // Normalize `'asc' | 'desc'` (ef-data-card emits these) to the\n // backend's legacy `'Ascending' | 'Descending'` strings, so\n // subclasses don't need to override `setSort` just for that.\n const normalized = (direction || '').toLowerCase().startsWith('asc')\n ? 'Ascending'\n : 'Descending';\n this.criteria.update((c) =>\n this.cloneCriteria(c, { sort: [{ field, sortDirection: normalized }] }),\n );\n this.search();\n }\n\n setDateRange(start: Date | null, end: Date | null): void {\n this.criteria.update((c) => this.cloneCriteria(c, { start, end, page: 1 }));\n this.search();\n }\n\n /** Patch arbitrary extra fields onto the criteria (for module-specific filters). */\n patchCriteria(patch: Record<string, any>): void {\n this.criteria.update((c) =>\n this.cloneCriteria(c, { extra: patch, page: 1 }),\n );\n this.search();\n }\n\n /** Reset everything to defaults and re-fetch. Subclasses bind this\n * to ef-smart-bar's `(clear)` output directly — no per-screen\n * `clearAll()` orchestration needed. */\n clear(): void {\n const cfg = this.getConfig();\n const fresh = new SearchEntity({});\n if (cfg?.DEFAULT_SORT) {\n fresh.sort = [\n {\n field: cfg.DEFAULT_SORT.field,\n sortDirection: cfg.DEFAULT_SORT.direction,\n },\n ];\n }\n this.criteria.set(fresh);\n\n // Reset all the shared filter-bar / selection signals so\n // subclasses don't have to track each one individually.\n this.searchQuery.set('');\n this.statusFilter.set('all');\n this.drawerOpen.set(false);\n this.activeFilters.set([]);\n this.advancedValues.set({});\n this.selected.set(new Set());\n this.resetDateRange();\n\n this.cacheService.setCache(this.screenStateKey, fresh);\n this.search();\n }\n\n /* ── CSV export ───────────────────────────────────────────────── */\n\n /**\n * Rows fetched per request while exporting.\n *\n * `PaginationCriteriaValidator` caps PageSize at 100, but no ERP search\n * query currently subclasses `PaginationQueryValidator`, so nothing\n * enforces it today. 100 is therefore the documented contract rather\n * than a wall: staying inside it keeps the export honest if the\n * validator is ever wired up, and keeps one request from asking a Mongo\n * collection for twenty thousand documents at once.\n */\n private static readonly EXPORT_PAGE_SIZE = 100;\n\n /**\n * Upper bound on an export. A tenant with 20k orders would otherwise\n * fire 200 sequential requests on one click. When the result set is\n * larger, the file holds the first `EXPORT_MAX_ROWS` and the user is\n * told so rather than handed a silently truncated file.\n */\n private static readonly EXPORT_MAX_ROWS = 5000;\n\n readonly exporting = signal(false);\n\n /**\n * Write the current result set to a CSV, honouring the active search,\n * filters and sort, with the columns the viewer can actually see.\n *\n * The card raises this because Export lives beside Density and Columns —\n * all three act on the result set — but only the screen knows the query,\n * so the fetching happens here.\n */\n exportCsv(request: EfDataCardExportRequest): void {\n if (this.exporting()) return;\n\n const columns = request.columns.filter((c) => c.exportable !== false);\n if (columns.length === 0) {\n // Returning quietly here would make Export a control that looks\n // like it acts and does not, which is the exact failure the inert\n // bulk bars were removed for.\n this.toastService.showInfo(this.t('common_export_no_columns'));\n return;\n }\n\n this.exporting.set(true);\n void this.collectExportRows()\n .then(({ rows, truncated }) => {\n if (rows.length === 0) {\n this.toastService.showInfo(this.t('common_export_empty'));\n return;\n }\n\n const flattened = rows.map((row) => {\n const record: Record<string, unknown> = {};\n for (const col of columns) {\n record[col.id] = request.resolveCell(row, col);\n }\n return record;\n });\n\n const csv = CsvUtils.toCsv(\n flattened,\n columns.map((col) => ({\n key: col.id,\n header: col.headerKey ? this.t(col.headerKey) : (col.header ?? col.id),\n })),\n );\n\n CsvUtils.download(this.exportFileName(), csv);\n\n if (truncated) {\n this.toastService.showInfo(\n this.t('common_export_truncated', {\n count: AbstractSearchScreenV2.EXPORT_MAX_ROWS,\n }),\n );\n }\n })\n .catch(() => this.toastService.showError(this.t('common_export_failed')))\n .finally(() => this.exporting.set(false));\n }\n\n /** Page through the current criteria until the result set is exhausted. */\n private async collectExportRows(): Promise<{ rows: any[]; truncated: boolean }> {\n const pageSize = AbstractSearchScreenV2.EXPORT_PAGE_SIZE;\n const max = AbstractSearchScreenV2.EXPORT_MAX_ROWS;\n const rows: any[] = [];\n let page = 1;\n\n for (;;) {\n const criteria = this.cloneCriteria(this.criteria(), { page, pageSize });\n const result: any = await new Promise((resolve, reject) =>\n this.serviceInstance\n .search(criteria)\n .pipe(take(1))\n .subscribe({ next: resolve, error: reject }),\n );\n\n const batch: any[] = result?.items ?? [];\n rows.push(...batch);\n\n const total: number = result?.totalCount ?? rows.length;\n if (rows.length >= max) return { rows: rows.slice(0, max), truncated: total > max };\n if (batch.length < pageSize || rows.length >= total) return { rows, truncated: false };\n page += 1;\n }\n }\n\n\n /** `<screen>-YYYY-MM-DD-HHmm.csv`, so repeated exports do not collide. */\n private exportFileName(): string {\n const d = new Date();\n const pad = (n: number) => String(n).padStart(2, '0');\n const stamp =\n `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` +\n `-${pad(d.getHours())}${pad(d.getMinutes())}`;\n const screen = (this.getConfig()?.SCREEN ?? 'export').toString().toLowerCase();\n return `${screen}-${stamp}.csv`;\n }\n\n private cloneCriteria(\n c: SearchEntity,\n patch: {\n searchText?: string | undefined;\n page?: number;\n pageSize?: number;\n sort?: SearchEntity['sort'];\n start?: Date | null;\n end?: Date | null;\n extra?: Record<string, any>;\n },\n ): SearchEntity {\n const next = new SearchEntity({});\n Object.assign(next, c);\n if ('searchText' in patch) (next as any).searchText = patch.searchText;\n if (patch.page !== undefined || patch.pageSize !== undefined) {\n next.pagination = {\n pageNumber: patch.page ?? c.pagination.pageNumber,\n pageSize: patch.pageSize ?? c.pagination.pageSize,\n };\n }\n if (patch.sort !== undefined) next.sort = patch.sort;\n if (patch.start !== undefined) next.start = patch.start;\n if (patch.end !== undefined) next.end = patch.end;\n if (patch.extra) Object.assign(next, patch.extra);\n return next;\n }\n\n /* ── Navigation helpers ─────────────────────────────────────────\n V2 routing convention (matches v1):\n /<list>/details → AbstractDetailScreenV2 in create mode\n /<list>/details/:id → AbstractDetailScreenV2 in edit mode\n /<list>/details/:id?mode=duplicate → duplicate-as-template\n\n `currentUrl` cached on `AbstractScreenComponent.ngOnInit` is\n not reliable (Router.url isn't committed yet during route\n activation, so it holds the previous URL). Read `router.url`\n at call time via `resolveListUrl()` instead. */\n\n /** Resolve the list-screen URL at call time. Drops query / fragment\n * and strips a trailing slash. */\n protected resolveListUrl(): string {\n let url = this.router.url || this.currentUrl || '';\n const q = url.indexOf('?');\n if (q >= 0) url = url.slice(0, q);\n const h = url.indexOf('#');\n if (h >= 0) url = url.slice(0, h);\n return url.replace(/\\/$/, '');\n }\n\n navigateToDetails(id?: any): void {\n const base = `${this.resolveListUrl()}/details`;\n if (id == null && id !== 0) {\n this.router.navigate([base]);\n return;\n }\n this.router.navigate([base, id]);\n }\n\n /** Open the create form. */\n add(): void {\n this.router.navigate([`${this.resolveListUrl()}/details`]);\n }\n\n edit(id: any): void {\n if (!id) {\n this.recordNotFound();\n return;\n }\n this.router.navigate([`${this.resolveListUrl()}/details`, id]);\n }\n\n /**\n * Name of the row being deleted, so the confirmation can say what it\n * is about to destroy — \"Delete ANDALOCY PARFUMS?\" rather than\n * \"Delete?\". Override in the screen; returning `undefined` keeps the\n * generic message, which still reads correctly.\n *\n * ```ts\n * protected override getDeleteConfirmName(id: any) {\n * return this.items().find(r => r.id === id)?.name;\n * }\n * ```\n */\n protected getDeleteConfirmName(_id: any): string | undefined {\n return undefined;\n }\n\n delete(id: any): void {\n if (!id) {\n this.recordNotFound();\n return;\n }\n this.confirmDialogService.confirm({\n intent: 'delete',\n name: this.getDeleteConfirmName(id),\n accept: () =>\n this.serviceInstance.delete(id).subscribe({\n next: (result: any) => {\n if (result?.errors?.length) {\n this.handleErrors(result.errors);\n } else {\n this.search();\n this.toastService.showSuccess();\n }\n },\n // The HTTP error interceptor surfaces the message (toast). Swallow\n // here so a rejected delete (e.g. a 422 business-rule violation)\n // doesn't bubble up as an unhandled error.\n error: () => undefined,\n }),\n });\n }\n\n duplicate(id: any): void {\n if (!id) {\n this.recordNotFound();\n return;\n }\n this.router.navigate([`${this.resolveListUrl()}/details`, id], {\n queryParams: { mode: 'duplicate' },\n });\n }\n\n // AbstractComponent declares `abstract ngOnDestroy()`, so this must exist.\n // There is genuinely nothing to tear down here; removing it would push the\n // requirement onto every consumer component.\n // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method\n ngOnDestroy(): void {\n // Subclasses can override to clean up subscriptions; nothing to\n // tear down on the base since search subscriptions auto-complete.\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport { Observable } from 'rxjs';\n\n/**\n * Abstract contract for the change-history (audit trail) backend client used by\n * {@link AbstractDetailScreenV2}. Apps provide their NSwag-generated `AuditClient`\n * via the {@link AUDIT_HISTORY_SERVICE} token — kept abstract so `@elasticias/screens`\n * stays decoupled from any app's generated API client.\n */\nexport interface AuditHistoryService {\n /**\n * Fetch the change-history for a single record, newest first.\n * @param entityType Stable backend entity type discriminator (e.g. `'Client'`).\n * @param id Record identifier.\n */\n get(entityType: string, id: string): Observable<any[]>;\n}\n\n/**\n * Injection token for the change-history client. Provide it once at app root:\n *\n * @example\n * { provide: AUDIT_HISTORY_SERVICE, useExisting: AuditClient }\n *\n * Detail screens then only declare `static AUDIT_ENTITY_TYPE = 'Client'` on\n * their config — {@link AbstractDetailScreenV2} loads the history automatically\n * into its `auditEntries` signal.\n */\nexport const AUDIT_HISTORY_SERVICE = new InjectionToken<AuditHistoryService>(\n 'AUDIT_HISTORY_SERVICE'\n);\n","import {\n Component,\n DestroyRef,\n Injector,\n OnDestroy, OnInit,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { Location } from '@angular/common';\nimport { combineLatest } from 'rxjs';\nimport { EfShortcutService } from '@elasticias/core';\nimport { AbstractScreenComponent } from './abstract-screen.component';\nimport { ScreenStateEnum } from '../../config/screen-state.enum';\nimport { EfDetailToolbarAction } from '../../entities/detail-toolbar-action.entity';\nimport { ViewModelEntity } from '../../entities/view-model.entity';\nimport { AUDIT_HISTORY_SERVICE } from '../../services/audit-history.service';\n\n/**\n * Signal-first counterpart to {@link AbstractDetailScreenComponent}.\n *\n * Same business mechanism as v1 but signal-based and zoneless-friendly:\n * `entity` / `entityId` / `editionState` / `duplicateMode` / `loading`\n * / `errorMsg` are all writable signals.\n *\n * Routing convention (V2):\n * - `/<resource>/details` → new (create mode, `editionState=false`)\n * - `/<resource>/details/:id` → edit mode (loads via `service.get(id)`)\n * - `/<resource>/details/:id?mode=duplicate` → loads then strips id on save\n *\n * The same component handles all three paths — the route param +\n * `mode` query string drives the state. After a successful create\n * (or duplicate-save), the screen navigates to\n * `/<resource>/details/<new-id>` so the user lands in edit mode.\n *\n * Subclasses typically override:\n * - `getConfig()` — returns ScreenConfig with SERVICE\n * - `beforeSave(): boolean` — return false to cancel save\n * (default: true)\n * - `afterLoad()` — post-process loaded entity\n * - `afterSave(result)` — default invalidates refs + navigates\n * to the new edit URL after create\n * - `onSaveError(errors)` — surface form-level validation errors\n * - `customizeDuplicatedEntity` — clean fields before duplicating\n *\n * ```ts\n * @Component({ ... })\n * export class FooDetailComponent extends AbstractDetailScreenV2<FooDto> {\n * override getConfig() { return FooConfig; }\n *\n * protected override beforeSave(): boolean {\n * // validate this.entity() shape; return false to cancel\n * return true;\n * }\n * }\n * ```\n */\n@Component({ template: '', standalone: true })\nexport abstract class AbstractDetailScreenV2<TItem extends object = any>\n extends AbstractScreenComponent\n implements OnInit\n{\n protected readonly screenState = ScreenStateEnum.DETAIL;\n protected readonly injector = inject(Injector);\n protected readonly location = inject(Location);\n private readonly destroyRef = inject(DestroyRef);\n private readonly auditHistoryService = inject(AUDIT_HISTORY_SERVICE, { optional: true });\n private readonly shortcuts = inject(EfShortcutService);\n\n /** Distinguishes this instance's registration from any other detail\n * screen alive at once (the outgoing and incoming routed component\n * can briefly coexist), the same convention ef-row-actions uses:\n * a shared static id would let one instance's disposer unregister\n * a still-live sibling's entry. */\n private static nextInstanceId = 0;\n private readonly instanceId = AbstractDetailScreenV2.nextInstanceId++;\n\n protected serviceInstance: any;\n\n constructor() {\n super();\n // Every detail screen inherits mod+s with no per-screen wiring, and\n // it doubles as the fix for the browser's own Save Page dialog\n // otherwise popping up on top of it.\n this.shortcuts.register({\n id: `abstract-detail-screen-v2.${this.instanceId}.save`,\n keys: 'mod+s',\n labelKey: 'common_save',\n group: 'shortcut_group_screen',\n // Gated here as well as inside save(): a subclass that overrides\n // save() without calling super must still not be reachable from\n // the keyboard by a user who cannot write.\n handler: () => {\n if (this.canWrite()) this.save();\n },\n });\n }\n\n /**\n * Change-history entries for the loaded record, newest first. Populated\n * automatically when the config sets `AUDIT_ENTITY_TYPE` and an\n * `AUDIT_HISTORY_SERVICE` is provided. Bind it directly:\n * `<ef-change-history [entries]=\"auditEntries()\" />`.\n */\n readonly auditEntries = signal<any[]>([]);\n\n /** Loaded entity. Empty object when on `/details` (create mode). */\n readonly entity = signal<TItem>(<TItem>{});\n\n /** PK from the route param, or `null` on `/details` (new). */\n readonly entityId = signal<any>(null);\n\n /** Edit-mode flag — true when an id is present and we're not duplicating. */\n readonly editionState = signal(false);\n\n /**\n * When true, the loaded entity is treated as a template — saving\n * runs `service.create()` instead of `service.update()`. Set by\n * the `?mode=duplicate` query param.\n */\n readonly duplicateMode = signal(false);\n\n /**\n * Bumped every time `processGrants()` (re)reads the user's grants.\n * `context` is a plain object, not a signal, so without this a\n * `canWrite()` read before the grants arrive would memoize `false`\n * and the route subscription re-setting `editionState(false)` to the\n * same value would never invalidate it.\n */\n private readonly grantsVersion = signal(0);\n\n /**\n * Whether the user may write the record on screen, for the mode it is\n * in: an existing record (edit mode, not duplicating) needs Edit; a new\n * record or a duplicate needs Create. Read is not enough for either,\n * which is how a Read-only user got a fully editable, savable form.\n *\n * Bind its negation on the form container to disable every ef-* control:\n * `<div class=\"form\" [efReadOnly]=\"readOnlyMode()\">`. ef-detail-toolbar\n * reads it through `context.canWrite` to hide Save, so screens pass\n * nothing for that. The backend still enforces the same grants; this is\n * the UI agreeing with it.\n */\n readonly canWrite = computed(() => {\n this.grantsVersion();\n const ctx = this.context;\n if (!ctx) return false;\n const editingExisting = this.editionState() && !this.duplicateMode();\n return editingExisting ? ctx.hasEditPermission : ctx.hasCreatePermission;\n });\n\n /** `!canWrite()`, named for the `[efReadOnly]` binding it feeds. */\n readonly readOnlyMode = computed(() => !this.canWrite());\n\n /** True while service.get / create / update / delete is in flight. */\n readonly loading = signal(false);\n\n /** Last load / save error message — empty string when none. */\n readonly errorMsg = signal<string | null>(null);\n\n /**\n * Reactive list of custom actions for `<ef-detail-toolbar>`'s\n * `[customActions]` input — recomputes whenever editionState /\n * duplicateMode flip. Default contents:\n * - Edit mode → empty (the standard `print | duplicate |\n * delete | save` row covers it)\n * - Create mode → `[Cancel]` — navigates back to the list\n * - Duplicate mode → `[Cancel]` — drops `?mode=duplicate` and\n * returns to edit view of the source entity\n *\n * Subclasses override `getCustomActions()` to add screen-specific\n * actions (Approve / Print PDF / Mark as paid / etc.). Call\n * `super.getCustomActions()` to keep the Cancel default.\n */\n readonly customActions = computed<ReadonlyArray<EfDetailToolbarAction>>(\n () => this.getCustomActions(),\n );\n\n /**\n * Builder for `customActions`. Override per screen to add or\n * replace the defaults. Pure function — reads other signals\n * freely, returns a fresh array each call.\n */\n protected getCustomActions(): EfDetailToolbarAction[] {\n // Edit mode: standard right-side group is enough; let subclass\n // append Preview / Print PDF / etc. by overriding this method.\n if (this.editionState()) return [];\n\n // Create / duplicate mode: a Cancel button. See cancel().\n return [\n {\n id: 'cancel',\n labelKey: 'common_cancel',\n icon: 'pi pi-times',\n severity: 'ghost',\n command: () => this.cancel(),\n },\n ];\n }\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.serviceInstance = this.injector.get(this.getConfig()!.SERVICE as any);\n\n // Reference / static lists for the detail context (different\n // set than the search screen's — `DETAILS_*` not `SEARCH_*`).\n const cfg = this.getConfig();\n if (cfg) {\n const hasDynamicRefs = (cfg.DETAILS_REFERENTIALS_KEYS?.length ?? 0) > 0;\n const hasStaticLists = (cfg.DETAILS_STATIC_LISTS?.length ?? 0) > 0;\n if (hasDynamicRefs) this.initializeReferenceKeys(cfg.DETAILS_REFERENTIALS_KEYS);\n if (hasStaticLists) this.initializeStaticLists(cfg.DETAILS_STATIC_LISTS);\n if (hasDynamicRefs || hasStaticLists) this.loadReferenceData(cfg.REF_DATA_OPTIONS);\n }\n\n // Wire route params → load (or reset to empty on /details).\n combineLatest([this.route.paramMap, this.route.queryParamMap])\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(([params, queryParams]) => {\n const id = params.get('id');\n const isDuplicate = queryParams.get('mode') === 'duplicate';\n\n this.entityId.set(id);\n this.duplicateMode.set(isDuplicate);\n this.context.duplicateMode = isDuplicate;\n this.editionState.set(!!id && !isDuplicate);\n\n if (id) {\n this.loadData();\n } else {\n // New mode — reset to a fresh empty entity, no history yet.\n this.entity.set(<TItem>{});\n this.auditEntries.set([]);\n this.afterLoad();\n }\n });\n }\n\n override processGrants(): void {\n // Stamp before super: it ends in detectChanges(), which renders an\n // ef-detail-toolbar bound to this context. A toolbar that first sees\n // the context without canWrite memoizes \"unknown\" (Save shown) and,\n // the context being the same object, never re-reads it.\n this.context.canWrite = this.canWrite;\n // Bumped before super too, so the render inside it recomputes\n // canWrite from the grants super is about to set rather than from a\n // value memoized on an earlier read.\n this.grantsVersion.update(v => v + 1);\n super.processGrants();\n }\n\n /**\n * Merge a partial patch into the `entity` signal — the canonical\n * way for form inputs to write back. Spread-immutably so OnPush\n * change detection picks it up.\n *\n * ```html\n * <ef-input-text\n * variant=\"comptoir\"\n * [value]=\"title()\"\n * (valueChangeEvent)=\"patchEntity({ title: $event })\"\n * />\n * ```\n */\n patchEntity(patch: Partial<TItem>): void {\n this.entity.update(current => ({ ...(current as object), ...patch }) as TItem);\n }\n\n /** Fetch the entity from the backend and populate `entity`. */\n loadData(): void {\n const id = this.entityId();\n if (!id) return;\n\n this.loading.set(true);\n this.errorMsg.set(null);\n\n this.serviceInstance.get(id).subscribe({\n next: (result: any) => {\n const vm = new ViewModelEntity(result) as unknown as TItem;\n (vm as any).id = id;\n this.entity.set(vm);\n this.loading.set(false);\n this.afterLoad();\n this.loadAuditHistory();\n },\n error: (err: any) => {\n console.error('AbstractDetailScreenV2.loadData failed', err);\n this.errorMsg.set(err?.message ?? 'Erreur de chargement');\n this.loading.set(false);\n },\n });\n }\n\n /**\n * Persist the entity. Routes to `service.create()` when in new\n * or duplicate mode, `service.update(id, entity)` when editing.\n * Subclass `beforeSave()` can return `false` to cancel.\n *\n * A no-op when `canWrite()` is false, checked before `beforeSave()` so\n * a screen's validation never toasts at a user who could not save\n * anyway.\n */\n save(): void {\n if (!this.canWrite()) return;\n\n const proceed = this.beforeSave();\n if (proceed === false) return;\n\n this.clearServerErrors();\n\n const isCreate = !this.editionState() || this.duplicateMode();\n const payload = this.duplicateMode()\n ? this.prepareEntityForDuplication()\n : this.entity();\n\n this.loading.set(true);\n const op = isCreate\n ? this.serviceInstance.create(payload)\n : this.serviceInstance.update(this.entityId(), payload);\n\n op.subscribe({\n next: (response: any) => {\n this.loading.set(false);\n if (response?.errors?.length) {\n this.handleErrors(response.errors);\n return;\n }\n this.toastService.showSuccess();\n this.afterSave(response);\n },\n error: (response: any) => {\n this.loading.set(false);\n if (response?.errors) {\n this.setServerErrors(response.errors);\n this.setFormErrors(response.errors);\n this.onSaveError(response.errors);\n }\n },\n });\n }\n\n /**\n * Soft-delete-then-navigate-back. Confirms with the user first.\n */\n /**\n * Name of the record being deleted, so the confirmation can say what\n * it is about to destroy — \"Delete ANDALOCY PARFUMS?\" rather than\n * \"Delete?\". Override in the screen; returning `undefined` keeps the\n * generic message, which still reads correctly.\n *\n * ```ts\n * protected override getDeleteConfirmName() {\n * return this.entity()?.name;\n * }\n * ```\n */\n protected getDeleteConfirmName(): string | undefined {\n return undefined;\n }\n\n delete(): void {\n if (!this.context?.hasDeletePermission) return;\n\n const id = this.entityId();\n if (!id) {\n this.recordNotFound();\n return;\n }\n\n this.confirmDialogService.confirm({\n intent: 'delete',\n name: this.getDeleteConfirmName(),\n accept: () =>\n this.serviceInstance.delete(id).subscribe({\n next: (result: any) => {\n if (result?.errors?.length) {\n this.handleErrors(result.errors);\n } else {\n this.toastService.showSuccess();\n this.navigateBack();\n }\n },\n // The HTTP error interceptor surfaces the message (toast).\n // Swallow here so a rejected delete (e.g. a 422 business-rule\n // violation) doesn't bubble up as an unhandled error.\n error: () => undefined,\n }),\n });\n }\n\n /** Navigate to `/details/:id?mode=duplicate` so the abstract can\n * reload the source entity, treat it as a template, and persist\n * via `service.create()` after the user hits Save.\n * Without the id, the duplicate route would have nothing to\n * fetch — `entity` would be empty and the clone-as-template\n * flow would fall back to creating a blank record.\n * Needs Create: a duplicate is saved through `service.create()`, so\n * opening one without Create would only lead to a read-only form. */\n duplicate(): void {\n if (!this.context?.hasCreatePermission) return;\n\n const id = this.entityId();\n const base = this.detailsBaseUrl();\n if (id == null) {\n // No source record (already on /details with no id) —\n // just open the create form.\n this.router.navigate([base]);\n return;\n }\n this.router.navigate([base, id], {\n queryParams: { mode: 'duplicate' },\n });\n }\n\n /**\n * Cancel handler for the default toolbar action:\n * - Duplicate mode → drop `?mode=duplicate` and return to\n * `/details/:id`. The route subscription re-fires and reloads\n * the source entity, discarding any in-memory edits.\n * - Create mode (no id) → navigate back to the list.\n *\n * Subclasses may override to add a confirm dialog when the form\n * is dirty.\n */\n cancel(): void {\n if (this.duplicateMode() && this.entityId() != null) {\n this.router.navigate([this.detailsBaseUrl(), this.entityId()]);\n return;\n }\n this.navigateBack();\n }\n\n /** Navigate back to the list (strip `/details` and any id). */\n navigateBack(): void {\n const url = (this.router.url || '').split('?')[0];\n const idx = url.indexOf('/details');\n if (idx !== -1) {\n this.router.navigate([url.substring(0, idx)]);\n } else {\n this.location.back();\n }\n }\n\n /** Subclass print hook — no-op default. */\n print(): void { /* no-op */ }\n\n /**\n * Load the standardized change-history into `auditEntries` when the config\n * opts in via `AUDIT_ENTITY_TYPE` and an `AUDIT_HISTORY_SERVICE` is provided.\n * Called automatically after a successful `loadData()`. Failures degrade to\n * an empty history rather than blocking the screen.\n */\n protected loadAuditHistory(): void {\n this.auditEntries.set([]);\n\n const entityType = this.getConfig()?.AUDIT_ENTITY_TYPE;\n const id = this.entityId();\n\n // No service provided, screen not opted in, or no id yet → empty box.\n if (!this.auditHistoryService || !entityType || !id) {\n return;\n }\n\n // Fully defensive: a missing/misconfigured audit client (no provider,\n // wrong shape, get() throwing, or an HTTP failure) must never break the\n // detail screen — it just leaves the history empty.\n try {\n const result$ = this.auditHistoryService.get(entityType, id);\n if (!result$ || typeof result$.subscribe !== 'function') {\n return;\n }\n result$.subscribe({\n next: (entries) => this.auditEntries.set(entries ?? []),\n error: () => this.auditEntries.set([]),\n });\n } catch {\n this.auditEntries.set([]);\n }\n }\n\n /* ── Override hooks ─────────────────────────────────────────── */\n\n /**\n * Called right before `save()` dispatches to the backend. Return\n * `false` to cancel (e.g., form validation failed). Default: no-op.\n */\n protected beforeSave(): boolean | void {\n return true;\n }\n\n /** Override to post-process the loaded `entity` (or to refresh\n * derived signals). Default: no-op. */\n protected afterLoad(): void { /* no-op */ }\n\n /**\n * Default post-save behaviour:\n * - invalidate / refresh reference data per ScreenConfig\n * - after a CREATE (or duplicate-save), navigate to\n * `/details/<new-id>` so the user lands in edit mode\n */\n protected afterSave(result: any): void {\n const cfg = this.getConfig();\n if (cfg?.INVALIDATE_KEYS_ON_SAVE) {\n this.invalidateReferences(cfg.INVALIDATE_KEYS_ON_SAVE);\n if (cfg.REFRESH_ON_SAVE) {\n this.refreshReferenceData(cfg.INVALIDATE_KEYS_ON_SAVE);\n }\n }\n\n const isCreate = !this.editionState() || this.duplicateMode();\n if (isCreate) {\n const newId = typeof result === 'object' ? (result?.id ?? result) : result;\n this.router.navigate([this.detailsBaseUrl(), newId]);\n } else {\n // Update succeeded in place — refresh the change-history so the new\n // entry shows without a manual reload.\n this.loadAuditHistory();\n }\n }\n\n /** Override to surface form-level validation errors after a 4xx\n * response. Default: no-op (errors are already on `serverErrors`). */\n protected onSaveError(_errors: { [key: string]: string[] }): void { /* no-op */ }\n\n /** Strip id (if present) from the entity before a duplicate save. */\n protected prepareEntityForDuplication(): any {\n const dup = { ...(this.entity() as any) };\n delete dup.id;\n delete dup.Id;\n return this.customizeDuplicatedEntity(dup);\n }\n\n /** Override to clear additional fields (codes, slugs, refs)\n * before saving a duplicated entity. */\n protected customizeDuplicatedEntity(entity: any): any {\n return entity;\n }\n\n /* ── Internals ──────────────────────────────────────────────── */\n\n /** Resolve the bare `/<resource>/details` base URL — strips a\n * trailing `:id`, query string, fragment, trailing slash. */\n protected detailsBaseUrl(): string {\n let url = this.router.url || '';\n const q = url.indexOf('?');\n if (q >= 0) url = url.slice(0, q);\n const h = url.indexOf('#');\n if (h >= 0) url = url.slice(0, h);\n // If we're on /…/details/<id>, drop <id>; if on /…/details, leave it.\n const m = url.match(/^(.*?\\/details)(?:\\/[^/]+)?\\/?$/);\n return m ? m[1] : url;\n }\n\n // AbstractComponent declares `abstract ngOnDestroy()`, so this must exist.\n // There is genuinely nothing to tear down here; removing it would push the\n // requirement onto every consumer component.\n // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method\n ngOnDestroy(): void {\n // The route subscription is auto-unsubscribed via takeUntilDestroyed.\n // Subclasses can override to release their own resources.\n }\n}\n","import {\n Component,\n inject,\n Injector,\n OnDestroy, OnInit,\n Signal,\n signal,\n} from '@angular/core';\nimport { Observable, take } from 'rxjs';\nimport { Permissions } from '@elasticias/types';\nimport { CsvUtils } from '@elasticias/utils';\nimport { AbstractScreenComponent } from './abstract-screen.component';\nimport { ScreenStateEnum } from '../../config/screen-state.enum';\nimport { EfDatePresetKey, EfDateRange } from '../../entities/date-range.entity';\n\nexport type ReportWidgetStatus = 'loading' | 'ready' | 'error';\n\n/**\n * Handle returned by {@link AbstractReportScreenV2.widget}. Each widget owns\n * an independent loading/error lifecycle — one failing report block never\n * blanks its siblings.\n */\nexport interface ReportWidget<T> {\n /** Last successful payload — null until the first `ready`. */\n readonly data: Signal<T | null>;\n readonly status: Signal<ReportWidgetStatus>;\n /** Re-run this widget's loader against the current period. */\n reload(): void;\n}\n\n/**\n * Signal-first base for report/dashboard screens — the third V2 abstract,\n * alongside {@link AbstractSearchScreenV2} / AbstractDetailScreenV2.\n *\n * Owns the report CHASSIS only: period state (`dateRange`, seeded from the\n * config's `DEFAULT_PERIOD` preset), per-widget lifecycle (`widget()` +\n * `loadAll()`), `REPORT_STATIC_LISTS` preload, and Export-gated CSV\n * (Task 2). Widget COMPOSITION stays in each screen's template — a\n * metadata-driven report renderer was rejected in ADR-015 and this class\n * must not become its frontend half.\n *\n * `ScreenConfig` surface: `SCREEN` (backend screen code), `SERVICE` (NSwag\n * reports client), `DEFAULT_PERIOD`, `REPORT_STATIC_LISTS`.\n *\n * Subclasses typically:\n *\n * ```ts\n * export class FooDashboardComponent extends AbstractReportScreenV2 {\n * protected override getConfig() { return FooDashboardConfig; }\n * readonly kpisW = this.widget((start, end) =>\n * this.client.kpis(new GetFooKpisQuery({ start, end })));\n * }\n * ```\n *\n * Loaders close over the screen's own filter signals; the screen calls\n * `loadAll()` (period-wide) or `someW.reload()` (single widget) when its\n * filters change. Period-independent blocks (operational strips) load\n * outside the registry on purpose.\n */\n@Component({ template: '', standalone: true })\nexport abstract class AbstractReportScreenV2\n extends AbstractScreenComponent\n implements OnInit\n{\n protected readonly screenState = ScreenStateEnum.REPORT;\n protected readonly injector = inject(Injector);\n\n /** NSwag reports client resolved from `ScreenConfig.SERVICE` — expose a\n * typed getter in the screen: `get client() { return this.reportsService as XClient; }` */\n protected reportsService: any;\n\n private readonly registeredWidgets: ReportWidget<unknown>[] = [];\n\n /** Active period. Bound to `ef-datepicker-advanced`; every widget loader\n * receives its UTC-normalized start/end. */\n readonly dateRange = signal<EfDateRange>(this.buildDefaultDateRange());\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.reportsService = this.injector.get(this.getConfig()!.SERVICE as any);\n\n // Reinstate the period the user last chose before anything loads, so the\n // widgets fetch it once instead of fetching the default and refetching.\n this.dateRange.set(\n this.restorePersistedDateRange(this.dateRange(), key => this.rangeFromPreset(key)),\n );\n\n const lists = this.getConfig()?.REPORT_STATIC_LISTS ?? [];\n if (lists.length > 0) {\n this.initializeStaticLists(lists);\n this.loadReferenceData(this.getConfig()?.REF_DATA_OPTIONS);\n this.refDataLoaded$.pipe(take(1)).subscribe(() => this.loadAll());\n } else {\n this.loadAll();\n }\n }\n\n /* ── Period ─────────────────────────────────────────────────── */\n\n /** Wired to `<ef-datepicker-advanced (rangeChange)>`. */\n onDateRangeChange(range: EfDateRange): void {\n this.dateRange.set(range);\n this.persistDateRange(range);\n this.loadAll();\n }\n\n /** Default period from the config's `DEFAULT_PERIOD` preset. */\n protected buildDefaultDateRange(): EfDateRange {\n return this.rangeFromPreset(this.getConfig()?.DEFAULT_PERIOD ?? 'last_30_days');\n }\n\n /**\n * Resolve a built-in {@link EfDatePresetKey} to an inclusive day range\n * (both boundaries at 00:00 local). Unknown keys normalize to\n * `last_30_days`. Weeks start Monday (matches `$dateTrunc`, ADR-015).\n */\n protected rangeFromPreset(key: EfDatePresetKey): EfDateRange {\n const KNOWN: EfDatePresetKey[] = [\n 'today', 'this_week', 'this_month', 'last_30_days',\n 'last_90_days', 'this_quarter', 'this_year',\n ];\n const k = KNOWN.includes(key) ? key : 'last_30_days';\n const today = this.startOfToday();\n const end = new Date(today);\n let start = new Date(today);\n switch (k) {\n case 'today':\n break;\n case 'this_week': {\n const dow = (today.getDay() + 6) % 7;\n start.setDate(today.getDate() - dow);\n break;\n }\n case 'this_month':\n start = new Date(today.getFullYear(), today.getMonth(), 1);\n break;\n case 'last_90_days':\n start.setDate(today.getDate() - 89);\n break;\n case 'this_quarter':\n start = new Date(today.getFullYear(), Math.floor(today.getMonth() / 3) * 3, 1);\n break;\n case 'this_year':\n start = new Date(today.getFullYear(), 0, 1);\n break;\n case 'last_30_days':\n default:\n start.setDate(today.getDate() - 29);\n break;\n }\n return { start, end, presetKey: k, labelKey: `date_preset_${k}`, label: '' };\n }\n\n private startOfToday(): Date {\n const d = new Date();\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n }\n\n /**\n * Re-anchor a local-midnight Date to UTC midnight of the same calendar\n * date. NSwag serializes via toISOString(); for UTC+ users (Morocco)\n * local midnight would otherwise shift into the previous UTC day.\n */\n protected toUtcDate(d: Date): Date {\n return new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));\n }\n\n /* ── Widgets ────────────────────────────────────────────────── */\n\n /**\n * Register a report widget. The loader receives the current period's\n * UTC-normalized start/end and returns the NSwag observable; extra\n * filters are simply closed over from the screen's own signals.\n */\n protected widget<T>(\n loader: (start: Date, end: Date) => Observable<T>,\n ): ReportWidget<T> {\n const data = signal<T | null>(null);\n const status = signal<ReportWidgetStatus>('loading');\n const handle: ReportWidget<T> = {\n data: data.asReadonly(),\n status: status.asReadonly(),\n reload: () => {\n const { start, end } = this.dateRange();\n status.set('loading');\n loader(this.toUtcDate(start), this.toUtcDate(end)).subscribe({\n next: (value) => {\n data.set(value);\n status.set('ready');\n },\n error: () => status.set('error'),\n });\n },\n };\n this.registeredWidgets.push(handle);\n return handle;\n }\n\n /** Reload every registered widget against the current period. */\n loadAll(): void {\n for (const w of this.registeredWidgets) w.reload();\n }\n\n /* ── Grants + export ────────────────────────────────────────── */\n\n /** Export grant (ADR-011) on this screen's own code. Grants are loaded\n * once by `processGrants()` in ngOnInit — safe to call from templates. */\n canExport(): boolean {\n return this.context?.isGranted(Permissions.Export) ?? false;\n }\n\n /** CSV download gated by the Export grant — silently no-ops without it. */\n protected exportCsv(\n filename: string,\n rows: object[],\n columns: { key: string; header: string }[],\n ): void {\n if (!this.canExport()) return;\n // `CsvColumn<T>['key']` is `keyof T & string`, which is `never` for the\n // bare `object` type — widen to `Record<string, unknown>` so the\n // generic infers a `string`-keyed column, matching `columns` as declared.\n CsvUtils.download(\n filename,\n CsvUtils.toCsv(rows as Record<string, unknown>[], columns),\n );\n }\n\n // AbstractComponent declares `abstract ngOnDestroy()`, so this must exist.\n // There is genuinely nothing to tear down here; removing it would push the\n // requirement onto every consumer component.\n // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method\n ngOnDestroy(): void {\n // NSwag observables complete after one emission — nothing to tear down.\n }\n}\n","import { Component } from '@angular/core';\nimport { AbstractScreenComponent } from './abstract-screen.component';\n\n@Component({\n template: ''\n})\nexport abstract class AbstractSubScreenComponent extends AbstractScreenComponent {\n protected readonly screenState = null;\n\n override ngOnInit(): void {\n super.ngOnInit();\n }\n\n override ngAfterViewInit(): void {\n super.ngAfterViewInit();\n }\n}\n","import {\n Component,\n inject,\n Injector,\n OnDestroy, OnInit,\n signal,\n} from '@angular/core';\nimport { Permissions } from '@elasticias/types';\nimport { AbstractScreenComponent } from './abstract-screen.component';\n\n/**\n * Signal-first base for SUB-screens — self-contained fragments embedded\n * inside a host screen (dashboard strips, side panels, …) rather than\n * routed on their own. The V2 counterpart to the legacy\n * {@link AbstractSubScreenComponent}.\n *\n * A sub-screen typically borrows ANOTHER screen's identity: its config\n * sets `SCREEN` to the code whose grants gate the data it shows (e.g. a\n * recent-orders strip on the sales dashboard uses `'SalesOrders'`), so\n * `canRead()` and `ScreenContext` permissions line up with the backend\n * seed without any cross-screen plumbing in the component.\n *\n * `ScreenConfig` surface (same fields as list screens, reused here):\n * - `SCREEN` — screen code whose grants apply to this fragment\n * - `SERVICE` — NSwag client resolved into `serviceInstance`\n * - `SEARCH_REFERENTIALS_KEYS` / `SEARCH_STATIC_LISTS` — ref-data the\n * fragment's columns/labels need; loaded on init, `refDataLoaded$`\n * fires when ready (reference columns resolve reactively, so data\n * fetches don't have to wait for it)\n *\n * No criteria caching, no routing, no toolbar — a sub-screen renders one\n * `ef-card` (or similar) and owns only its data + collapse state.\n */\n@Component({ template: '', standalone: true })\nexport abstract class AbstractSubScreenV2\n extends AbstractScreenComponent\n implements OnInit\n{\n protected readonly screenState = null;\n protected readonly injector = inject(Injector);\n\n /** NSwag client resolved from `ScreenConfig.SERVICE` (null-safe: a\n * sub-screen fed entirely by inputs may omit SERVICE). */\n protected serviceInstance: any;\n\n /**\n * Collapse state, bound `[(collapsed)]` on the sub-screen's `ef-card`.\n * Starts collapsed: sub-screens are secondary content on their host\n * screen, so they open on demand. Subclasses that must start open set\n * `this.collapsed.set(false)` in their constructor.\n */\n readonly collapsed = signal(true);\n\n toggleCollapsed(): void {\n this.collapsed.update((c) => !c);\n }\n\n /** Read grant on the config's `SCREEN` — gate the whole fragment on\n * this so an unauthorized user gets nothing (not an erroring card). */\n canRead(): boolean {\n return this.context?.isGranted(Permissions.Read) ?? false;\n }\n\n override ngOnInit(): void {\n super.ngOnInit();\n const cfg = this.getConfig();\n if (cfg?.SERVICE) {\n this.serviceInstance = this.injector.get(cfg.SERVICE as any);\n }\n\n const hasDynamicRefs = (cfg?.SEARCH_REFERENTIALS_KEYS?.length ?? 0) > 0;\n const hasStaticLists = (cfg?.SEARCH_STATIC_LISTS?.length ?? 0) > 0;\n if (hasDynamicRefs) this.initializeReferenceKeys(cfg.SEARCH_REFERENTIALS_KEYS);\n if (hasStaticLists) this.initializeStaticLists(cfg.SEARCH_STATIC_LISTS);\n // No refs declared → no load, and (matching AbstractSearchScreenV2)\n // no refDataLoaded$ emission — don't wait on it in that case.\n if (hasDynamicRefs || hasStaticLists) {\n this.loadReferenceData(cfg.REF_DATA_OPTIONS);\n }\n }\n\n // AbstractComponent declares `abstract ngOnDestroy()`, so this must exist.\n // There is genuinely nothing to tear down here; removing it would push the\n // requirement onto every consumer component.\n // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method\n ngOnDestroy(): void {\n // NSwag observables complete after one emission — nothing to tear\n // down; subclasses override when they hold live subscriptions.\n }\n}\n","import { SortDirectionEnum } from '../entities/search.entity';\nimport type { EfDatePresetKey } from '../entities/date-range.entity';\n\nexport interface DefaultSort {\n field: string;\n direction: SortDirectionEnum;\n}\n\nexport interface LoadOptions {\n bypassCache?: boolean;\n ttl?: number;\n forceRefresh?: boolean;\n useSql?: boolean;\n}\n\nexport abstract class ScreenConfig {\n SCREEN!: string;\n SERVICE!: unknown;\n\n SEARCH_REFERENTIALS_KEYS!: string[];\n DETAILS_REFERENTIALS_KEYS!: string[];\n\n SEARCH_STATIC_LISTS: string[] = [];\n DETAILS_STATIC_LISTS: string[] = [];\n\n INVALIDATE_KEYS_ON_SAVE?: string[];\n REFRESH_ON_SAVE?: boolean;\n REF_DATA_OPTIONS?: LoadOptions;\n DEFAULT_SORT?: DefaultSort;\n\n /**\n * Backend entity type for the standardized change-history box. When set,\n * AbstractDetailScreenV2 auto-loads the record's audit trail (via the\n * AUDIT_HISTORY_SERVICE token) into its `auditEntries` signal — the screen\n * only needs `<ef-change-history [entries]=\"auditEntries()\" />`. Leave unset\n * to opt out. Must match the backend IAuditable.AuditEntityType (e.g. 'Client').\n */\n AUDIT_ENTITY_TYPE?: string;\n\n /**\n * Report screens (AbstractReportScreenV2): starting period preset for the\n * screen's ef-datepicker-advanced. Unset → 'last_30_days'.\n */\n DEFAULT_PERIOD?: EfDatePresetKey;\n\n /**\n * Report screens: translatable static lists preloaded before the first\n * loadAll() — same mechanism as SEARCH_STATIC_LISTS on list screens.\n */\n REPORT_STATIC_LISTS?: string[];\n}\n","// Abstract base classes\nexport { AbstractEntity } from './lib/abstract/abstract.entity';\nexport { AbstractComponent } from './lib/abstract/abstract.component';\n\n// Screen abstract components\nexport { AbstractScreenComponent } from './lib/abstract/screen/abstract-screen.component';\nexport { AbstractDetailScreenComponent } from './lib/abstract/screen/abstract-detail-screen.component';\nexport { AbstractSearchScreenComponent } from './lib/abstract/screen/abstract-search-screen.component';\nexport type { ScreenDatatableColumn } from './lib/abstract/screen/abstract-search-screen.component';\nexport { AbstractSearchScreenV2 } from './lib/abstract/screen/abstract-search-screen-v2.component';\nexport type { AdvancedSelectFilter } from './lib/abstract/screen/abstract-search-screen-v2.component';\nexport { AbstractDetailScreenV2 } from './lib/abstract/screen/abstract-detail-screen-v2.component';\nexport { AbstractReportScreenV2 } from './lib/abstract/screen/abstract-report-screen-v2.component';\nexport type { ReportWidget, ReportWidgetStatus } from './lib/abstract/screen/abstract-report-screen-v2.component';\nexport { AbstractSubScreenComponent } from './lib/abstract/screen/abstract-sub-screen.component';\nexport { AbstractSubScreenV2 } from './lib/abstract/screen/abstract-sub-screen-v2.component';\n\n// Services\nexport { SCREEN_REF_DATA_SERVICE } from './lib/services/screen-reference-data.service';\nexport type { ScreenReferenceDataService } from './lib/services/screen-reference-data.service';\nexport { AUDIT_HISTORY_SERVICE } from './lib/services/audit-history.service';\nexport type { AuditHistoryService } from './lib/services/audit-history.service';\n\n// Config\nexport { ScreenStateEnum, StateUtilsEnum } from './lib/config/screen-state.enum';\nexport { ScreenConfig } from './lib/config/screen-config';\nexport type { LoadOptions, DefaultSort } from './lib/config/screen-config';\nexport { ScreenContext } from './lib/config/screen-context';\nexport type { ReferenceDataProvider } from './lib/config/screen-context';\n\n// Entities\nexport { SearchEntity, SortDirectionEnum, PaginationEnum } from './lib/entities/search.entity';\nexport { ViewModelEntity } from './lib/entities/view-model.entity';\nexport type { EfDateRange, EfDatePresetKey } from './lib/entities/date-range.entity';\nexport type { ActiveFilter } from './lib/entities/active-filter.entity';\nexport type { EfDetailToolbarAction } from './lib/entities/detail-toolbar-action.entity';\nexport type { EfSearchToolbarAction } from './lib/entities/search-toolbar-action.entity';\nexport type {\n EfDataCardColumn,\n EfDataCardColumnType,\n EfDataCardColumnMobileRole,\n EfDataCardColumnAlign,\n EfDataCardSort,\n EfDataCardSortDirection,\n EfReferenceColumnOpts,\n EfDataCardExportRequest,\n} from './lib/entities/data-card-column.entity';\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/screens",
3
- "version": "1.0.39",
3
+ "version": "1.0.40",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.0.0",
6
6
  "@angular/core": "^21.0.0",
@@ -61,6 +61,15 @@ declare class ScreenContext extends AbstractEntity {
61
61
  entity: unknown;
62
62
  grants: string[];
63
63
  duplicateMode: boolean;
64
+ /**
65
+ * Whether the screen may write the record it shows, for its current mode.
66
+ * Set by `AbstractDetailScreenV2` to its own `canWrite` signal, so shared
67
+ * components bound to `[context]` (ef-detail-toolbar's Save and its
68
+ * `requiresWrite` custom actions) follow the same rule without each
69
+ * screen passing it again. Undefined on screens that have no write mode
70
+ * (search, report), where those components keep their default behaviour.
71
+ */
72
+ canWrite?: Signal<boolean>;
64
73
  constructor(state: string, group?: unknown, entity?: unknown, refDataProvider?: ReferenceDataProvider, bundles?: Map<string, Map<string, Map<string, string>>>, grants?: string[], screenName?: string, language?: string);
65
74
  setReferenceDataProvider(provider: ReferenceDataProvider): void;
66
75
  get ref(): {
@@ -224,6 +233,12 @@ declare const SCREEN_REF_DATA_SERVICE: InjectionToken<ScreenReferenceDataService
224
233
  declare abstract class AbstractScreenComponent extends AbstractComponent implements OnInit, AfterViewInit, OnDestroy {
225
234
  context: ScreenContext;
226
235
  connectedUser: any;
236
+ /** V1 only: the NgForm a V1 detail template declares as `#entityForm`.
237
+ * V2 templates bind `[value]` / `(valueChangeEvent)` with no NgForm, so
238
+ * this stays undefined there and everything below that walks it
239
+ * (`disableAllControls`, `setFormErrors`, `isFormValid`) does nothing.
240
+ * V2 screens use `AbstractDetailScreenV2.readOnlyMode()` bound as
241
+ * `[efReadOnly]` on the form container, and `canWrite()` for saving. */
227
242
  entityForm: NgForm;
228
243
  serverErrors: _angular_core.WritableSignal<{
229
244
  [key: string]: string[];
@@ -241,6 +256,10 @@ declare abstract class AbstractScreenComponent extends AbstractComponent impleme
241
256
  get state(): string | null;
242
257
  screenStateKey: string;
243
258
  ngOnInit(): void;
259
+ /** The `isReadOnly()` branch below is the V1 read-only path. It never
260
+ * fires usefully on a V2 screen (see `entityForm`), and its predicate
261
+ * ignores the mode: Read+Create on an existing record counts as
262
+ * writable. V2 detail screens rely on `readOnlyMode()` instead. */
244
263
  ngAfterViewInit(): void;
245
264
  processGrants(): void;
246
265
  isFormValid(): boolean;
@@ -319,6 +338,8 @@ declare abstract class AbstractScreenComponent extends AbstractComponent impleme
319
338
  /** JSON gives back ISO strings; hand back real `Date`s or nothing. */
320
339
  private static reviveDateRange;
321
340
  clearServerErrors(): void;
341
+ /** V1 only: disables the controls of `entityForm`. A no-op on V2
342
+ * screens, which use `readOnlyMode()` + `[efReadOnly]`. */
322
343
  disableAllControls(): void;
323
344
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AbstractScreenComponent, never>;
324
345
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AbstractScreenComponent, "ng-component", never, { "context": { "alias": "context"; "required": false; }; }, {}, never, never, true, never>;
@@ -920,6 +941,14 @@ interface EfDetailToolbarAction {
920
941
  * show (subject to `visible`).
921
942
  */
922
943
  permission?: Permissions;
944
+ /**
945
+ * The action changes the record (approve, cancel, complete, ...).
946
+ * Hidden when the screen cannot write it in its current mode, read from
947
+ * the bound `ScreenContext.canWrite` (set by `AbstractDetailScreenV2`).
948
+ * Independent of `permission`: when both are set, both must pass. A
949
+ * context with no write state (no `canWrite`) leaves the action shown.
950
+ */
951
+ requiresWrite?: boolean;
923
952
  /** Click handler. */
924
953
  command?: () => void;
925
954
  }
@@ -998,6 +1027,29 @@ declare abstract class AbstractDetailScreenV2<TItem extends object = any> extend
998
1027
  * the `?mode=duplicate` query param.
999
1028
  */
1000
1029
  readonly duplicateMode: _angular_core.WritableSignal<boolean>;
1030
+ /**
1031
+ * Bumped every time `processGrants()` (re)reads the user's grants.
1032
+ * `context` is a plain object, not a signal, so without this a
1033
+ * `canWrite()` read before the grants arrive would memoize `false`
1034
+ * and the route subscription re-setting `editionState(false)` to the
1035
+ * same value would never invalidate it.
1036
+ */
1037
+ private readonly grantsVersion;
1038
+ /**
1039
+ * Whether the user may write the record on screen, for the mode it is
1040
+ * in: an existing record (edit mode, not duplicating) needs Edit; a new
1041
+ * record or a duplicate needs Create. Read is not enough for either,
1042
+ * which is how a Read-only user got a fully editable, savable form.
1043
+ *
1044
+ * Bind its negation on the form container to disable every ef-* control:
1045
+ * `<div class="form" [efReadOnly]="readOnlyMode()">`. ef-detail-toolbar
1046
+ * reads it through `context.canWrite` to hide Save, so screens pass
1047
+ * nothing for that. The backend still enforces the same grants; this is
1048
+ * the UI agreeing with it.
1049
+ */
1050
+ readonly canWrite: _angular_core.Signal<boolean>;
1051
+ /** `!canWrite()`, named for the `[efReadOnly]` binding it feeds. */
1052
+ readonly readOnlyMode: _angular_core.Signal<boolean>;
1001
1053
  /** True while service.get / create / update / delete is in flight. */
1002
1054
  readonly loading: _angular_core.WritableSignal<boolean>;
1003
1055
  /** Last load / save error message — empty string when none. */
@@ -1024,6 +1076,7 @@ declare abstract class AbstractDetailScreenV2<TItem extends object = any> extend
1024
1076
  */
1025
1077
  protected getCustomActions(): EfDetailToolbarAction[];
1026
1078
  ngOnInit(): void;
1079
+ processGrants(): void;
1027
1080
  /**
1028
1081
  * Merge a partial patch into the `entity` signal — the canonical
1029
1082
  * way for form inputs to write back. Spread-immutably so OnPush
@@ -1044,6 +1097,10 @@ declare abstract class AbstractDetailScreenV2<TItem extends object = any> extend
1044
1097
  * Persist the entity. Routes to `service.create()` when in new
1045
1098
  * or duplicate mode, `service.update(id, entity)` when editing.
1046
1099
  * Subclass `beforeSave()` can return `false` to cancel.
1100
+ *
1101
+ * A no-op when `canWrite()` is false, checked before `beforeSave()` so
1102
+ * a screen's validation never toasts at a user who could not save
1103
+ * anyway.
1047
1104
  */
1048
1105
  save(): void;
1049
1106
  /**
@@ -1068,7 +1125,9 @@ declare abstract class AbstractDetailScreenV2<TItem extends object = any> extend
1068
1125
  * via `service.create()` after the user hits Save.
1069
1126
  * Without the id, the duplicate route would have nothing to
1070
1127
  * fetch — `entity` would be empty and the clone-as-template
1071
- * flow would fall back to creating a blank record. */
1128
+ * flow would fall back to creating a blank record.
1129
+ * Needs Create: a duplicate is saved through `service.create()`, so
1130
+ * opening one without Create would only lead to a read-only form. */
1072
1131
  duplicate(): void;
1073
1132
  /**
1074
1133
  * Cancel handler for the default toolbar action: