@decaf-ts/for-angular 0.0.47 → 0.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/decaf-ts-for-angular.mjs +438 -248
- package/fesm2022/decaf-ts-for-angular.mjs.map +1 -1
- package/index.d.ts +74 -77
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decaf-ts-for-angular.mjs","sources":["../../../src/lib/engine/constants.ts","../../../src/lib/engine/ValidatorFactory.ts","../../../src/lib/for-angular-common.module.ts","../../../src/lib/utils/helpers.ts","../../../src/lib/services/NgxFormService.ts","../../../src/lib/utils/DecafFakerRepository.ts","../../../src/lib/utils/index.ts","../../../src/lib/engine/NgxRenderingEngine.ts","../../../src/lib/i18n/Loader.ts","../../../src/lib/services/NgxMediaService.ts","../../../src/lib/engine/NgxComponentDirective.ts","../../../src/lib/engine/NgxRenderableComponentDirective.ts","../../../src/lib/components/component-renderer/component-renderer.component.ts","../../../src/lib/components/component-renderer/component-renderer.component.html","../../../src/lib/engine/NgxFormFieldDirective.ts","../../../src/lib/engine/decorators.ts","../../../src/lib/components/model-renderer/model-renderer.component.ts","../../../src/lib/components/model-renderer/model-renderer.component.html","../../../src/lib/engine/NgxParentComponentDirective.ts","../../../src/lib/components/modal/modal.component.ts","../../../src/lib/components/modal/modal.component.html","../../../src/lib/components/crud-field/crud-field.component.ts","../../../src/lib/components/crud-field/crud-field.component.html","../../../src/lib/engine/NgxFormDirective.ts","../../../src/lib/components/card/card.component.ts","../../../src/lib/components/card/card.component.html","../../../src/lib/components/layout/layout.component.ts","../../../src/lib/components/layout/layout.component.html","../../../src/lib/components/crud-form/crud-form.component.ts","../../../src/lib/components/crud-form/crud-form.component.html","../../../src/lib/directives/NgxSvgDirective.ts","../../../src/lib/components/icon/icon.component.ts","../../../src/lib/components/icon/icon.component.html","../../../src/lib/components/empty-state/empty-state.component.ts","../../../src/lib/components/empty-state/empty-state.component.html","../../../src/lib/components/fieldset/fieldset.component.ts","../../../src/lib/components/fieldset/fieldset.component.html","../../../src/lib/components/searchbar/searchbar.component.ts","../../../src/lib/components/searchbar/searchbar.component.html","../../../src/lib/components/filter/filter.component.ts","../../../src/lib/components/filter/filter.component.html","../../../src/lib/components/pagination/pagination.component.ts","../../../src/lib/components/pagination/pagination.component.html","../../../src/lib/components/list/list.component.ts","../../../src/lib/components/list/list.component.html","../../../src/lib/components/list-item/list-item.component.ts","../../../src/lib/components/list-item/list-item.component.html","../../../src/lib/components/stepped-form/stepped-form.component.ts","../../../src/lib/components/stepped-form/stepped-form.component.html","../../../src/lib/components/file-upload/file-upload.component.ts","../../../src/lib/components/file-upload/file-upload.component.html","../../../src/lib/components/for-angular-components.module.ts","../../../src/lib/components/index.ts","../../../src/lib/engine/interfaces.ts","../../../src/lib/engine/DynamicModule.ts","../../../src/lib/engine/NgxEventHandler.ts","../../../src/lib/engine/NgxPageDirective.ts","../../../src/lib/engine/NgxModelPageDirective.ts","../../../src/lib/engine/index.ts","../../../src/lib/public-apis.ts","../../../src/lib/decaf-ts-for-angular.ts"],"sourcesContent":["import { VALIDATION_PARENT_KEY } from '@decaf-ts/decorator-validation';\nimport { ICrudFormOptions, IListEmptyOptions } from './interfaces';\n\nimport { ModalOptions } from '@ionic/angular/standalone';\n\n/**\n * @description Angular engine key constants.\n * @summary Contains key strings used by the Angular rendering engine for reflection,\n * dynamic component creation, and other engine operations. These constants provide\n * consistent naming for metadata keys, DOM attributes, and component identification\n * throughout the rendering system.\n * @typedef {Object} AngularEngineKeys\n * @property {string} REFLECT - Prefix for reflection metadata keys\n * @property {string} DYNAMIC - Key for dynamic component identification\n * @property {string} ANNOTATIONS - Key for component annotations\n * @property {string} ECMP - Key for embedded components\n * @property {string} NG_REFLECT - Prefix for Angular reflection attributes\n * @property {string} RENDERED - Prefix for rendered component markers\n * @property {string} MAPPER - Key for property mappers\n * @property {string} CHILDREN - Key for child components\n * @property {string} LISTABLE - Key for listable components\n * @property {string} RENDER - Key for renderable components\n * @property {string} RENDERED_ID - Template for rendered component IDs\n * @property {string} PARENT - Key for comparison decorators and validators\n * @property {string} VALIDATION_PARENT_KEY - Key for validation parent reference\n * @property {string} FLAVOUR - Identifier for the Angular engine flavor\n * @const AngularEngineKeys\n * @memberOf module:lib/engine/constants\n */\nexport const AngularEngineKeys = {\n REFLECT: `angular`,\n DYNAMIC: 'dynamic-component',\n ANNOTATIONS: '__annotations__',\n ECMP: 'ecmp',\n NG_REFLECT: 'ng-reflect-',\n RENDERED: 'rendered-as-',\n MAPPER: 'mapper',\n CHILDREN: 'children',\n LISTABLE: 'listable',\n RENDER: 'render',\n RENDERED_ID: 'rendered-as-{0}',\n PARENT: '_parent',\n VALIDATION_PARENT_KEY: VALIDATION_PARENT_KEY,\n FLAVOUR: 'angular',\n LOADED: 'engineLoaded',\n DARK_PALETTE_CLASS: 'dcf-palette-dark',\n} as const;\n\n/**\n * @description Form validation state constants.\n * @summary Contains constants representing the possible validation states of a form.\n * These are used to check and handle form validation throughout the application.\n * The VALID state indicates all form controls pass validation, while INVALID\n * indicates one or more validation errors exist.\n * @typedef {Object} FormConstants\n * @property {string} VALID - Constant representing a valid form state\n * @property {string} INVALID - Constant representing an invalid form state\n * @const FormConstants\n * @memberOf module:lib/engine/constants\n */\nexport const FormConstants = {\n VALID: 'VALID',\n INVALID: 'INVALID',\n} as const;\n\n/**\n * @description Event name constants.\n * @summary Contains constants for standardized event names used throughout the application.\n * These constants ensure consistent event naming across components and make it easier to\n * track and handle events. Each constant represents a specific application event type.\n * @typedef {Object} ComponentEventNames\n * @property {string} BACK_BUTTON_NAVIGATION - Event fired when back button navigation ends\n * @property {string} REFRESH - Event fired when a refresh action occurs\n * @property {string} CLICK - Event fired when a click action occurs\n * @property {string} SUBMIT - Event fired when a form submission occurs\n * @property {string} VALIDATION_ERROR - Event fired when a validation error occurs\n * @property {string} FIELDSET_ADD_GROUP - Event fired when adding a group to a fieldset\n * @property {string} FIELDSET_UPDATE_GROUP - Event fired when updating a fieldset group\n * @property {string} FIELDSET_REMOVE_GROUP - Event fired when removing a fieldset group\n * @const ComponentEventNames\n * @memberOf module:lib/engine/constants\n */\nexport const ComponentEventNames = {\n BACK_BUTTON_NAVIGATION: 'backButtonNavigationEndEvent',\n REFRESH: 'RefreshEvent',\n CLICK: 'ClickEvent',\n CHANGE: 'ChangeEvent',\n SUBMIT: 'SubmitEvent',\n VALIDATION_ERROR: 'validationErrorEvent',\n FIELDSET_ADD_GROUP: 'fieldsetAddGroupEvent',\n FIELDSET_UPDATE_GROUP: 'fieldsetUpdateGroupEvent',\n FIELDSET_REMOVE_GROUP: 'fieldsetRemoveGroupEvent',\n THEME_CHANGE: 'themeChangeEvent',\n // FIELDSET_GROUP_VALIDATION: 'fieldsetGroupValidationEvent'\n} as const;\n\n/**\n * @description Logger level constants.\n * @summary Defines the logging levels used in the application's logging system.\n * Lower numeric values represent more verbose logging, while higher values represent\n * more critical logs. These levels control which log messages are output based on\n * the configured logging threshold.\n * @enum {number}\n * @readonly\n * @property {number} ALL - Log everything (most verbose)\n * @property {number} DEBUG - Log debug information\n * @property {number} INFO - Log informational messages\n * @property {number} WARN - Log warnings\n * @property {number} ERROR - Log errors\n * @property {number} CRITICAL - Log critical errors (least verbose)\n * @memberOf module:lib/engine/constants\n */\nexport enum LoggerLevels {\n ALL = 0,\n DEBUG = 1,\n INFO = 2,\n WARN = 3,\n ERROR = 4,\n CRITICAL = 5,\n}\n\n/**\n * @description Route direction constants.\n * @summary Defines the possible navigation directions in the application.\n * Used for controlling navigation flow and animation directions during route transitions.\n * These constants help maintain consistent navigation behavior throughout the app.\n * @enum {string}\n * @readonly\n * @property {string} BACK - Navigate back to the previous page\n * @property {string} FORWARD - Navigate forward to the next page\n * @property {string} ROOT - Navigate to the root/home page\n * @memberOf module:lib/engine/constants\n */\nexport enum RouteDirections {\n BACK = 'back',\n FORWARD = 'forward',\n ROOT = 'root',\n}\n\n/**\n * @description Component tag name constants.\n * @summary Defines the custom HTML tag names for specialized components used in the application.\n * These tag names are registered with Angular and used for component rendering and identification.\n * Each constant represents the selector for a specific custom component type.\n * @enum {string}\n * @readonly\n * @property {string} LIST_ITEM - Tag name for list item component\n * @property {string} LIST_INFINITE - Tag name for infinite scrolling list component\n * @property {string} LIST_PAGINATED - Tag name for paginated list component\n * @property {string} CRUD_FIELD - Tag name for CRUD form field component\n * @property {string} LAYOUT_COMPONENT - Tag name for layout container component\n * @memberOf module:lib/engine/constants\n */\nexport enum ComponentsTagNames {\n LIST_ITEM = 'ngx-decaf-list-item',\n LIST_INFINITE = 'ngx-decaf-list-infinite',\n LIST_PAGINATED = 'ngx-decaf-list-paginated',\n CRUD_FIELD = 'ngx-decaf-crud-field',\n LAYOUT_COMPONENT = 'ngx-decaf-layout',\n}\n\n/**\n * @description Base component property name constants.\n * @summary Defines the standard property names used by base components throughout the application.\n * These constants ensure consistent property naming across components and facilitate\n * property access, validation, and data binding. Used primarily for component input\n * properties and change detection.\n * @enum {string}\n * @readonly\n * @property {string} MODEL - Property name for the component's data model\n * @property {string} LOCALE - Property name for localization settings\n * @property {string} LOCALE_ROOT - Property name for the locale root identifier\n * @property {string} PK - Property name for primary key\n * @property {string} ITEMS - Property name for collection items\n * @property {string} ROUTE - Property name for routing information\n * @property {string} OPERATIONS - Property name for available operations\n * @property {string} UID - Property name for unique identifier\n * @property {string} TRANSLATABLE - Property name for translation flag\n * @property {string} MAPPER - Property name for property mapper\n * @property {string} INITIALIZED - Property name for initialization state\n * @property {string} COMPONENT_NAME - Property name for component identifier\n * @property {string} PARENT_FORM - Property name for parent component reference\n * @property {string} FORM_GROUP_COMPONENT_PROPS - Property name for form group component properties\n * @memberOf module:lib/engine/constants\n */\nexport enum BaseComponentProps {\n MODEL = 'model',\n LOCALE = 'locale',\n LOCALE_ROOT = 'locale_root',\n PK = 'pk',\n ITEMS = 'items',\n ROUTE = 'route',\n OPERATIONS = 'operations',\n UID = 'uid',\n TRANSLATABLE = 'translatable',\n MAPPER = 'mapper',\n INITIALIZED = 'initialized',\n COMPONENT_NAME = 'componentName',\n PARENT_FORM = 'parentForm',\n FORM_GROUP_COMPONENT_PROPS = 'componentProps',\n}\n\n/**\n * @description List component type constants.\n * @summary Defines the available types for list components, determining their\n * pagination and scrolling behavior. Used to configure list rendering strategies.\n * @enum {string}\n * @readonly\n * @property {string} INFINITE - Infinite scroll list type\n * @property {string} PAGINATED - Paginated list type with page navigation\n * @memberOf module:lib/engine/constants\n */\nexport enum ListComponentsTypes {\n INFINITE = 'infinite',\n PAGINATED = 'paginated',\n}\n\n/**\n * @description CSS class name constants.\n * @summary Contains predefined CSS class names used for consistent styling\n * across components. These constants help maintain a unified visual language\n * and make it easier to apply standard styles.\n * @typedef {Object} CssClasses\n * @property {string} BUTTONS_CONTAINER - CSS class for button container elements\n * @const CssClasses\n * @memberOf module:lib/engine/constants\n */\nexport const CssClasses = {\n BUTTONS_CONTAINER: 'buttons-container',\n};\n\n/**\n * @description Default options for reactive CRUD forms.\n * @summary Provides default configuration for form buttons in CRUD operations.\n * Includes default text labels for submit and clear buttons, which can be\n * overridden by individual form implementations.\n * @type {ICrudFormOptions}\n * @property {Object} buttons - Configuration for form action buttons\n * @property {Object} buttons.submit - Submit button configuration\n * @property {string} buttons.submit.text - Default text for submit button\n * @property {Object} buttons.clear - Clear button configuration\n * @property {string} buttons.clear.text - Default text for clear button\n * @const DefaultFormReactiveOptions\n * @memberOf module:lib/engine/constants\n */\nexport const DefaultFormReactiveOptions: ICrudFormOptions = {\n buttons: {\n submit: {\n text: 'Submit',\n },\n clear: {\n text: 'Clear',\n },\n },\n};\n\n/**\n * @description Default options for empty list state display.\n * @summary Provides default configuration for displaying empty state in list components\n * when no data is available. Includes default text for title and subtitle, icon name,\n * button text and visibility settings. These defaults can be overridden by individual\n * list component implementations to customize the empty state presentation.\n * @type {IListEmptyOptions}\n * @property {string} title - Default translation key for empty list title\n * @property {string} subtitle - Default translation key for empty list subtitle\n * @property {boolean} showButton - Whether to show action button in empty state\n * @property {string} icon - Default Ionic icon name for empty state\n * @property {string} buttonText - Default translation key for button text\n * @property {string} link - Default navigation link (empty string)\n * @const DefaultListEmptyOptions\n * @memberOf module:lib/engine/constants\n */\nexport const DefaultListEmptyOptions = {\n title: 'empty.title',\n subtitle: 'empty.subtitle',\n showButton: false,\n icon: 'folder-open-outline',\n buttonText: 'locale.empty.button',\n link: '',\n} as IListEmptyOptions;\n\nexport const DefaultModalOptions = {\n component: '',\n showBackdrop: true,\n backdropDismiss: false,\n animated: true,\n canDismiss: true,\n showBackdropTapClose: true,\n focusTrap: true,\n} as ModalOptions;\n\nexport const ActionRoles = {\n cancel: 'cancel',\n confirm: 'confirm',\n submit: 'submit',\n clear: 'clear',\n back: 'back',\n} as const;\n\nexport const WindowColorSchemes = {\n light: 'light',\n dark: 'dark',\n undefined: 'undefined',\n} as const;\n\nexport const ElementSizes = {\n xsmall: 'xsmall',\n small: 'small',\n medium: 'medium',\n default: 'default',\n large: 'large',\n xLarge: 'xlarge',\n '2xLarge': '2xlarge',\n auto: 'auto',\n expand: 'expand',\n block: 'block',\n} as const;\n\nexport const ElementPositions = {\n left: 'left',\n center: 'center',\n right: 'right',\n top: 'top',\n bottom: 'bottom',\n} as const;\n\nexport const LayoutGridGaps = {\n small: 'small',\n medium: 'medium',\n large: 'large',\n collapse: 'collapse',\n none: '',\n} as const;\n\nexport const ListItemPositions = {\n uid: 'uid',\n title: 'title',\n description: 'description',\n info: 'info',\n subinfo: 'subinfo',\n} as const;\n","/**\n * @module module:lib/engine/ValidatorFactory\n * @description Factory for generating Angular ValidatorFn from Decaf validation metadata.\n * @summary ValidatorFactory maps validation keys defined by the Decaf validation system\n * into Angular ValidatorFn instances. It supports type-based resolution and comparison\n * validators and provides helpers to create proxies for nested control validation.\n *\n * @link {@link ValidatorFactory}\n */\nimport { AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn } from '@angular/forms';\nimport {\n ComparisonValidationKeys,\n DEFAULT_PATTERNS,\n PathProxy,\n PathProxyEngine,\n Primitives,\n Validation,\n ValidationKeys,\n Validator,\n} from '@decaf-ts/decorator-validation';\nimport { FieldProperties, HTML5InputTypes, parseValueByType } from '@decaf-ts/ui-decorators';\nimport { AngularEngineKeys } from './constants';\nimport { KeyValue } from './types';\nimport { NgxRenderingEngine } from './NgxRenderingEngine';\n\n\ntype ComparisonValidationKey = typeof ComparisonValidationKeys[keyof typeof ComparisonValidationKeys];\n\n/**\n *\n * Resolves the correct validator key and its associated properties based on the input key and type.\n *\n * When the validation key is TYPE, it's necessary to resolve the actual validator based on the\n * field's type (e.g., 'password', 'email', 'url') instead of using the generic getValidator(\"type\") logic.\n * This allows directly invoking specific validators like getValidator('password'), ensuring the correct\n * behavior for type-based validation.\n *\n * @param key - The validation key (e.g., 'type', 'required', etc.).\n * @param value - The value that needs be provided to the validator.\n * @param type - The field's declared type.\n * @returns An object containing the resolved validator key and its corresponding props.\n */\nconst resolveValidatorKeyProps = (key: string, value: unknown, type: string): {\n validatorKey: string;\n props: Record<string, unknown>;\n} => {\n const patternValidators: Record<string, unknown> = {\n [ValidationKeys.PASSWORD]: DEFAULT_PATTERNS.PASSWORD.CHAR8_ONE_OF_EACH,\n [ValidationKeys.EMAIL]: DEFAULT_PATTERNS.EMAIL,\n [ValidationKeys.URL]: DEFAULT_PATTERNS.URL,\n };\n const isTypeBased = key === ValidationKeys.TYPE && Object.keys(patternValidators).includes(type);\n const validatorKey = isTypeBased ? type : key;\n if (key === ValidationKeys.TYPE && HTML5InputTypes.CHECKBOX && value !== type )\n value = type;\n const props: Record<string, unknown> = {\n // [validatorKey]: (!isTypeBased && key === 'type') ? parseType(type) : value,\n [validatorKey]: (!isTypeBased && validatorKey === ValidationKeys.TYPE) ? NgxRenderingEngine.get().translate(value as string, false) : value,\n // Email, Password, and URL are validated using the \"pattern\" key\n ...(isTypeBased && { [ValidationKeys.PATTERN] : patternValidators[type] }),\n };\n\n return { validatorKey, props };\n};\n\n\nexport class ValidatorFactory {\n static spawn(fieldProps: FieldProperties, key: string): ValidatorFn {\n if (!Validation.keys().includes(key))\n throw new Error('Unsupported custom validation');\n\n const validatorFn: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {\n const { type, customTypes, options } = fieldProps;\n let fieldType = (customTypes || type) as string;\n if ((fieldType === HTML5InputTypes.CHECKBOX || fieldType === Array.name) && Array.isArray(options))\n fieldType = Primitives.STRING;\n\n const { validatorKey, props } = resolveValidatorKeyProps(key, fieldProps[key as keyof FieldProperties], fieldType);\n const validator = Validation.get(validatorKey) as Validator;\n\n // parseValueByType does not support undefined values\n const value = typeof control.value !== 'undefined'\n ? parseValueByType(fieldType, control.value, fieldProps)\n : undefined;\n\n // Create a proxy to enable access to parent and child values\n let proxy: PathProxy<unknown> = ValidatorFactory.createProxy({} as AbstractControl);\n if (Object.values(ComparisonValidationKeys).includes(key as ComparisonValidationKey)) {\n const parent: FormGroup = control instanceof FormGroup ? control : (control as KeyValue)[AngularEngineKeys.PARENT];\n proxy = ValidatorFactory.createProxy(parent) as PathProxy<unknown>;\n }\n\n let errs: string | undefined;\n try {\n\n errs = validator.hasErrors(value, props, proxy);\n } catch (e: unknown) {\n errs = `${key} validator failed to validate: ${e}`;\n console.error(errs);\n }\n return errs ? { [validatorKey]: true } : null;\n };\n\n Object.defineProperty(validatorFn, 'name', {\n value: `${key}Validator`,\n });\n\n return validatorFn;\n }\n\n /**\n * @summary Creates a proxy wrapper for an Angular AbstractControl to assist with custom validation logic.\n * @description Returns a structured proxy object that simulates a hierarchical tree of form values.\n * Enables Validators handling method to access parent and child properties using consistent dot-notation in Angular forms.\n *\n * @param {AbstractControl} control - The control to wrap in a proxy.\n * @returns {PathProxy<unknown>} A proxy object exposing form values and enabling recursive parent access.\n */\n static createProxy(control: AbstractControl): PathProxy<unknown> {\n return PathProxyEngine.create(control, {\n getValue(target: AbstractControl, prop: string): unknown {\n if (target instanceof FormControl)\n return target.value;\n\n if (target instanceof FormGroup) {\n const control = target.controls[prop];\n return control instanceof FormControl ? control.value : control;\n }\n\n // const value = target[prop];\n // if (value instanceof FormControl)\n // return value.value;\n //\n // if (value instanceof FormGroup) {\n // const control = value.controls[prop];\n // return control instanceof FormControl ? control.value : control;\n // }\n\n return (target as KeyValue)?.[prop];\n },\n getParent: function(target: AbstractControl) {\n return target?.['_parent'];\n },\n ignoreUndefined: true,\n ignoreNull: true,\n });\n }\n}\n","/**\n * @module lib/for-angular-common.module\n * @description Core Angular module and providers for Decaf's for-angular package.\n * @summary Provides the shared Angular module, injection tokens and helper functions used\n * by the for-angular integration. This module wires up common imports (forms, translation)\n * and exposes helper providers such as DB adapter registration and logger utilities.\n * @link {@link ForAngularCommonModule}\n */\nimport {\n NgModule,\n ModuleWithProviders,\n InjectionToken,\n Provider,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { TranslateModule, TranslatePipe } from '@ngx-translate/core';\nimport { Logger, Logging } from '@decaf-ts/logging';\nimport { I18nToken } from './engine/interfaces';\nimport { getOnWindow, getWindow } from './utils/helpers';\nimport {\n DecafRepository,\n FunctionLike,\n DecafRepositoryAdapter,\n KeyValue,\n} from './engine/types';\nimport { Model, Primitives } from '@decaf-ts/decorator-validation';\nimport { Repository } from '@decaf-ts/core';\nimport { Constructor, uses } from '@decaf-ts/decoration';\n\nexport const DB_ADAPTER_PROVIDER = 'DB_ADAPTER_PROVIDER';\n/**\n * @description Injection token for registering the database adapter provider.\n * @summary Used to inject the database adapter instance that implements DecafRepositoryAdapter.\n * This token allows the framework to locate and use the application's specific database implementation.\n * @const {InjectionToken<DecafRepositoryAdapter>}\n * @memberOf module:lib/for-angular-common.module\n */\nexport const DB_ADAPTER_PROVIDER_TOKEN =\n new InjectionToken<DecafRepositoryAdapter>('DB_ADAPTER_PROVIDER_TOKEN');\n/**\n * @description Injection token for the root path of locale translation files.\n * @summary Used to configure the base path where i18n translation files are located.\n * This allows the translation loader to locate JSON files for different languages.\n * @const {InjectionToken<string>}\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // Typical usage when providing the token\n * { provide: LOCALE_ROOT_TOKEN, useValue: './assets/i18n/' }\n */\nexport const LOCALE_ROOT_TOKEN = new InjectionToken<string>(\n 'LOCALE_ROOT_TOKEN'\n);\n\n/* Generic token for injecting on class constructors */\n/**\n * @description Generic injection token for providing arbitrary values to constructors.\n * @summary Used to inject classes, strings, or any other value into component or service constructors.\n * This is a flexible token that can be used to provide any type of dependency when more specific\n * tokens are not appropriate. The actual type and purpose of the injected value is determined by\n * the provider configuration.\n * @const {InjectionToken<unknown>}\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // Inject a string value\n * { provide: CPTKN, useValue: 'some-config-value' }\n *\n * // Inject a class\n * { provide: CPTKN, useClass: MyService }\n *\n * // Inject any arbitrary value\n * { provide: CPTKN, useValue: { key: 'value', data: [1, 2, 3] } }\n */\nexport const CPTKN = new InjectionToken<unknown>('CPTKN', {\n providedIn: 'root',\n factory: () => '',\n});\n\n/**\n * @description Injection token for i18n resource configuration.\n * @summary Used to provide configuration for internationalization resources, including\n * translation file locations and supported languages. This token configures how the\n * application loads and manages translation resources.\n * @const {InjectionToken<I18nToken>}\n * @memberOf module:lib/for-angular-common.module\n */\nexport const I18N_CONFIG_TOKEN = new InjectionToken<I18nToken>(\n 'I18N_CONFIG_TOKEN'\n);\n\n/**\n * @description Provides an array of component types for dynamic rendering.\n * @summary Helper function to package component constructors for registration with the\n * rendering engine. This function accepts component classes and returns them as an array\n * suitable for use with the CPTKN injection token.\n * @param {...Constructor[]} components - Component constructor classes to register\n * @return {Constructor} Array of component constructors\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // Register multiple custom components\n * providers: [\n * { provide: CPTKN, useValue: provideDynamicComponents(MyComponent, AnotherComponent) }\n * ]\n */\nexport function provideDynamicComponents(\n ...components: Constructor<unknown>[]\n): Constructor<unknown>[] {\n return components;\n}\n\n/**\n * @description Retrieves the repository instance for a given model.\n * @summary Creates or retrieves a DecafRepository instance for the specified model. This function\n * resolves the model by name or class, locates the registered database adapter, and returns\n * a fully initialized repository instance for performing CRUD operations.\n * @param {Model | string} model - The model class or model name string\n * @return {DecafRepository<Model>} Repository instance for the model\n * @throws {InternalError} If model is not found or not registered with @model decorator\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // Get repository by model class\n * const userRepo = getModelAndRepository(User);\n *\n * // Get repository by model name\n * const productRepo = getModelAndRepository('Product');\n *\n * // Use repository for queries\n * const users = await userRepo.findAll();\n */\nexport function getModelAndRepository(\n model: Model | string\n): {repository: DecafRepository<Model>, model: Model} | undefined {\n try {\n const modelName = (\n typeof model === Primitives.STRING\n ? model\n : (model as Model).constructor.name\n ) as string;\n const constructor = Model.get(\n (modelName.charAt(0).toUpperCase() + modelName.slice(1)) as string\n );\n if (!constructor)\n return undefined;\n const dbAdapterFlavour = getOnWindow(DB_ADAPTER_PROVIDER) || undefined;\n if (dbAdapterFlavour) uses(dbAdapterFlavour as string)(constructor);\n const repository = Repository.forModel(constructor);\n model = new constructor() as Model;\n if(!repository.pk)\n return undefined;\n return {repository, model};\n } catch (error: unknown) {\n getLogger(getModelAndRepository).warn((error as Error)?.message || (error as string));\n return undefined;\n }\n}\n\n/**\n * @description Provides a database adapter for dependency injection.\n * @summary Creates an Angular provider that registers a database adapter instance. This function\n * instantiates the adapter class, registers its flavour globally, and returns a provider object\n * for use in Angular's dependency injection system.\n * @template DbAdapter - The database adapter class type extending {flavour: string}\n * @param {Constructor<DbAdapter>} adapterClass - Database adapter constructor class\n * @param {KeyValue} [options={}] - Configuration options passed to adapter constructor\n * @param {string} [flavour] - Optional flavour override; uses adapter.flavour if not provided\n * @return {Provider} Angular provider object for DB_ADAPTER_PROVIDER_TOKEN\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // Register a SQLite adapter\n * providers: [\n * provideDbAdapter(SqliteAdapter, { database: 'myapp.db' }, 'sqlite')\n * ]\n *\n * // Register with default flavour from adapter\n * providers: [\n * provideDbAdapter(PostgresAdapter, { host: 'localhost', port: 5432 })\n * ]\n */\nexport function provideDbAdapter<DbAdapter extends { flavour: string }>(\n adapterClass: Constructor<DbAdapter>,\n options: KeyValue = {},\n flavour?: string\n): Provider {\n const adapter = new adapterClass(options);\n if (flavour) flavour = adapter.flavour;\n // Log and expose adapter flavour globally\n getLogger(provideDbAdapter).info(\n `Using ${adapter.constructor.name} ${flavour} as Db Provider`\n );\n getWindow()[DB_ADAPTER_PROVIDER] = flavour;\n return {\n provide: DB_ADAPTER_PROVIDER_TOKEN,\n useValue: adapter,\n };\n}\n\n/**\n * @const {Logger}\n * @private\n * @description Base logger instance for the for-angular module.\n * @memberOf module:lib/for-angular-common.module\n */\nconst log = Logging.for('for-angular');\n\n/**\n * @description Retrieves a logger instance for the given context.\n * @summary Creates or retrieves a namespaced logger instance using the Decaf logging system.\n * The logger is automatically namespaced under \"for-angular\" and can be further scoped\n * to a specific instance, function, or string identifier.\n * @param {string | FunctionLike | unknown} instance - The instance, function, or string to scope the logger to\n * @return {Logger} Logger instance for the specified context\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // Get logger for a class\n * const logger = getLogger(MyComponent);\n * logger.info('Component initialized');\n *\n * // Get logger with string identifier\n * const serviceLogger = getLogger('UserService');\n * serviceLogger.error('Operation failed', error);\n */\nexport function getLogger(instance: string | FunctionLike | unknown): Logger {\n return log.for(instance as string | FunctionLike);\n}\n\nconst CommonModules = [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n TranslateModule,\n TranslatePipe,\n];\n\n/**\n * @description Main Angular module for the Decaf framework.\n * @summary The ForAngularCommonModule provides the core functionality for integrating Decaf with Angular applications.\n * It imports and exports common Angular and Ionic components and modules needed for Decaf applications,\n * including form handling, translation support, and Ionic UI components. This module can be imported\n * directly or via the forRoot() method for proper initialization in the application's root module.\n * @class ForAngularCommonModule\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // In your app module:\n * @NgModule({\n * imports: [\n * ForAngularCommonModule.forRoot(),\n * // other imports\n * ],\n * // ...\n * })\n * export class AppModule {}\n */\n@NgModule({\n imports: CommonModules,\n declarations: [],\n exports: CommonModules,\n schemas: [],\n providers: [],\n})\nexport class ForAngularCommonModule {\n /**\n * @description Creates a module with providers for root module import.\n * @summary This static method provides the proper way to import the ForAngularCommonModule in the application's\n * root module. It returns a ModuleWithProviders object that includes the ForAngularCommonModule itself.\n * Using forRoot() ensures that the module and its providers are properly initialized and only\n * instantiated once in the application.\n * @return {ModuleWithProviders<ForAngularCommonModule>} The module with its providers\n * @memberOf ForAngularCommonModule\n * @static\n * @example\n * // Import in root module\n * @NgModule({\n * imports: [ForAngularCommonModule.forRoot()],\n * // ...\n * })\n * export class AppModule {}\n */\n static forRoot(): ModuleWithProviders<ForAngularCommonModule> {\n return {\n ngModule: ForAngularCommonModule,\n };\n }\n}\n","/**\n * @module module:lib/helpers/utils\n * @description General helper utilities used across the library.\n * @summary Exposes small, reusable utility functions for window/document access, date handling,\n * string manipulation, simple mapping helpers and environment helpers used by UI components\n * and services. This module's functions include `getWindow`, `getWindowDocument`, `formatDate`,\n * `isValidDate`, `itemMapper`, `dataMapper`, and event helpers like `windowEventEmitter`.\n *\n * Do not document individual exports here — functions are documented inline.\n * @link {@link getWindow}\n */\n\nimport { isDevMode } from '@angular/core';\nimport { InjectableRegistryImp, InjectablesRegistry } from '@decaf-ts/injectable-decorators';\nimport { Primitives } from '@decaf-ts/decorator-validation';\nimport { KeyValue, StringOrBoolean, } from '../engine/types';\nimport { FunctionLike } from '../engine/types';\nimport { getLogger } from '../for-angular-common.module';\n\nlet injectableRegistry: InjectablesRegistry;\n\n/**\n * @description Retrieves the singleton instance of the injectables registry\n * @summary This function implements the singleton pattern for the InjectablesRegistry.\n * It returns the existing registry instance if one exists, or creates a new instance\n * if none exists. The registry is used to store and retrieve injectable dependencies\n * throughout the application.\n *\n * @return {InjectablesRegistry} The singleton injectables registry instance\n *\n * @function getInjectablesRegistry\n * @memberOf module:for-angular\n */\nexport function getInjectablesRegistry(): InjectablesRegistry {\n if (!injectableRegistry)\n injectableRegistry = new InjectableRegistryImp();\n return injectableRegistry;\n}\n\n/**\n * @description Determines if the application is running in development mode\n * @summary This function checks whether the application is currently running in a development\n * environment. It uses Angular's isDevMode() function and also checks the window context\n * and hostname against the provided context parameter. This is useful for enabling\n * development-specific features or logging.\n *\n * @param {string} [context='localhost'] - The context string to check against the current environment\n * @return {boolean} True if the application is running in development mode, false otherwise\n *\n * @function isDevelopmentMode\n * @memberOf module:for-angular\n */\nexport function isDevelopmentMode(context: string = 'localhost'): boolean {\n if (!context)\n return isDevMode();\n const win = getWindow();\n return (\n isDevMode() ||\n win?.['env']?.['CONTEXT'].toLowerCase() !== context.toLowerCase() ||\n win?.['location']?.hostname?.includes(context)\n );\n}\n\n/**\n * @description Dispatches a custom event to the document window\n * @summary This function creates and dispatches a custom event to the browser window.\n * It's useful for cross-component communication or for triggering application-wide events.\n * The function allows specifying the event name, detail data, and additional event properties.\n *\n * @param {string} name - The name of the custom event to dispatch\n * @param {unknown} detail - The data to include in the event's detail property\n * @param {object} [props] - Optional additional properties for the custom event\n * @return {void}\n *\n * @function windowEventEmitter\n * @memberOf module:for-angular\n */\nexport function windowEventEmitter(\n name: string,\n detail: unknown,\n props?: object\n): void {\n const data = Object.assign(\n {\n bubbles: true,\n composed: true,\n cancelable: false,\n detail: detail,\n },\n props || {}\n );\n (getWindow() as Window).dispatchEvent(new CustomEvent(name, data));\n}\n/**\n * @description Retrieves a property from the window's document object\n * @summary This function provides a safe way to access properties on the window's document object.\n * It uses the getWindowDocument function to get a reference to the document, then accesses\n * the specified property. This is useful for browser environment interactions that need\n * to access document properties.\n *\n * @param {string} key - The name of the property to retrieve from the document object\n * @return {any} The value of the specified property, or undefined if the document or property doesn't exist\n *\n * @function getOnWindowDocument\n * @memberOf module:for-angular\n */\nexport function getOnWindowDocument(key: string): Document | undefined {\n const doc = getWindowDocument() as Document;\n return doc instanceof Document ?\n (doc as KeyValue)?.[key] || undefined : undefined;\n}\n\n/**\n * @description Retrieves the document object from the window\n * @summary This function provides a safe way to access the document object from the window.\n * It uses the getOnWindow function to retrieve the 'document' property from the window object.\n * This is useful for browser environment interactions that need access to the document.\n *\n * @return {Document | undefined} The window's document object, or undefined if it doesn't exist\n *\n * @function getWindowDocument\n * @memberOf module:for-angular\n */\nexport function getWindowDocument(): Document | undefined {\n return getOnWindow('document') as Document;\n}\n\n/**\n * @description Retrieves a property from the window object\n * @summary This function provides a safe way to access properties on the window object.\n * It uses the getWindow function to get a reference to the window, then accesses\n * the specified property. This is useful for browser environment interactions that need\n * to access window properties or APIs.\n *\n * @param {string} key - The name of the property to retrieve from the window object\n * @return {unknown | undefined} The value of the specified property, or undefined if the window or property doesn't exist\n *\n * @function getOnWindow\n * @memberOf module:for-angular\n */\nexport function getOnWindow(key: string): unknown | undefined {\n return getWindow()?.[key];\n}\n\n/**\n * @description Sets a property on the window object\n * @summary This function provides a way to set properties on the window object.\n * It uses the getWindow function to get a reference to the window, then sets\n * the specified property to the provided value. This is useful for storing\n * global data or functions that need to be accessible across the application.\n *\n * @param {string} key - The name of the property to set on the window object\n * @param {any} value - The value to assign to the property\n * @return {void}\n *\n * @function setOnWindow\n * @memberOf module:for-angular\n */\nexport function setOnWindow(key: string, value: unknown): void {\n getWindow()[key] = value;\n}\n\n/**\n * @description Retrieves the global window object\n * @summary This function provides a safe way to access the global window object.\n * It uses globalThis to ensure compatibility across different JavaScript environments.\n * This is the core function used by other window-related utility functions to\n * access the window object.\n *\n * @return {Window} The global window object\n *\n * @function getWindow\n * @memberOf module:for-angular\n */\nexport function getWindow(): Window & KeyValue {\n return (globalThis as KeyValue)?.['window'] as Window & KeyValue;\n}\n\n/**\n * @description Retrieves the width of the browser window\n * @summary This function provides a convenient way to get the current width of the browser window.\n * It uses the getOnWindow function to access the 'innerWidth' property of the window object.\n * This is useful for responsive design implementations and viewport-based calculations.\n *\n * @return {number | undefined} The current width of the browser window in pixels\n *\n * @function getWindowWidth\n * @memberOf module:for-angular\n */\nexport function getWindowWidth(): number {\n return getOnWindow('innerWidth') as number || 0;\n}\n\n/**\n * @description Checks if a value is not undefined\n * @summary This utility function determines whether a given value is not undefined.\n * It's a simple wrapper that makes code more readable when checking for defined values.\n * The function is particularly useful for checking StringOrBoolean properties that might be undefined.\n *\n * @param {StringOrBoolean | undefined} prop - The property to check\n * @return {boolean} True if the property is not undefined, false otherwise\n *\n * @function isNotUndefined\n * @memberOf module:for-angular\n */\nexport function isNotUndefined(prop: StringOrBoolean | undefined): boolean {\n return (prop !== undefined) as boolean;\n}\n\n/**\n * @description Generates a locale string from a class name or instance\n * @summary This utility function converts a class name or instance into a locale string\n * that can be used for internationalization purposes. It handles different input types\n * (string, function, or object) and applies formatting rules to generate a consistent\n * locale identifier. For short names (less than 3 parts), it reverses the dot-separated\n * string. For longer names, it uses the last part as a prefix and joins the rest with\n * underscores.\n *\n * @param {string|FunctionLike|object} instance - The input to generate the locale from (class name, constructor, or instance)\n * @param {string} [suffix] - Optional string to append to the instance name before processing\n * @return {string} A formatted locale string derived from the input\n *\n * @function getLocaleFromClassName\n * @memberOf module:for-angular\n */\nexport function getLocaleFromClassName(\n instance: string | FunctionLike | KeyValue,\n suffix?: string\n): string {\n if (typeof instance !== Primitives.STRING)\n instance = (instance as FunctionLike).name || (instance as object)?.constructor?.name;\n\n let name: string | string[] = instance as string;\n\n if (suffix)\n name = `${instance}${suffix.charAt(0).toUpperCase() + suffix.slice(1)}`;\n\n name = name.replace(/_|-/g, '').replace(/(?:^\\w|[A-Z]|\\b\\w)/g, (word: string, index: number) => {\n if (index > 1) word = '.' + word;\n return word.toLowerCase();\n }).split('.');\n\n if (name.length < 3)\n return name.reverse().join('.');\n\n const preffix = name[name.length - 1];\n name.pop();\n name = name.join('_');\n return `${preffix}.${name}`;\n}\n\n\n\n/**\n * @description Retrieves the current locale language\n * @summary This utility function gets the current locale language based on the user's browser settings.\n * It provides a consistent way to access the user's language preference throughout the application.\n * The function returns the browser's navigator.language value, defaulting to 'en' if not available.\n *\n * @return {string} The current locale language (e.g., 'en', 'fr')\n *\n * @function getLocaleLanguage\n * @memberOf module:for-angular\n */\nexport function getLocaleLanguage(): string {\n const win = getWindow();\n return (win as Window).navigator.language || \"en\";\n // return win?.[WINDOW_KEYS.LANGUAGE_SELECTED] || (win.navigator.language || '').split('-')[0] || \"en\";\n}\n\n\n\n/**\n * @description Generates a random string or number of specified length\n * @summary This utility function creates a random string of a specified length.\n * It can generate either alphanumeric strings (including uppercase and lowercase letters)\n * or numeric-only strings. This is useful for creating random IDs, temporary passwords,\n * or other random identifiers throughout the application.\n *\n * @param {number} [length=8] - The length of the random value to generate\n * @param {boolean} [onlyNumbers=false] - Whether to generate only numeric characters\n * @return {string} A randomly generated string of the specified length and character set\n *\n * @function generateRandomValue\n * @memberOf module:for-angular\n */\nexport function generateRandomValue(length: number = 8, onlyNumbers: boolean = false): string {\n const chars = onlyNumbers\n ? '0123456789'\n : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++)\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n\n return result;\n}\n\n\n/**\n * @description Converts a string representation of a boolean or a boolean value to a boolean type.\n * @summary This utility function handles conversion of string-based boolean values ('true', 'false')\n * to actual boolean types. It performs case-insensitive string comparison and returns the\n * corresponding boolean value. This is particularly useful when parsing configuration values,\n * URL parameters, or form inputs that may come as strings but need to be used as booleans.\n *\n * @param {'true' | 'false' | boolean} prop - The value to convert. Can be the string 'true', 'false', or a boolean\n * @returns {boolean} The boolean representation of the input value. Returns true if the input is the string 'true' or boolean true, false otherwise\n *\n * @function stringToBoolean\n * @memberOf module:lib/helpers/utils\n */\nexport function stringToBoolean(prop: 'true' | 'false' | boolean): boolean {\n if (typeof prop === 'string')\n prop = prop.toLowerCase() === 'true' ? true : false;\n return prop;\n}\n\n\n/**\n * @description Checks if a value is a valid Date object.\n * @summary This validation function determines whether a given value represents a valid date.\n * It handles multiple input types including Date objects, timestamp numbers, and date strings.\n * For string inputs, it supports ISO 8601 format (YYYY-MM-DD) with or without time components.\n * The function performs comprehensive validation including regex pattern matching and Date\n * object creation to ensure the date is not only parseable but also represents a real date.\n *\n * @param {string | Date | number} date - The value to check. Can be a Date object, a timestamp number, or a date string\n * @returns {boolean} Returns true if the value is a valid Date object (not NaN), otherwise false\n *\n * @function isValidDate\n * @memberOf module:lib/helpers/utils\n */\nexport function isValidDate(date: string | Date | number): boolean {\n try {\n return (date instanceof Date && !isNaN(date as unknown as number)) || (() => {\n const testRegex = new RegExp(/^\\d{4}-\\d{2}-\\d{2}$/).test(date as string)\n if (typeof date !== Primitives.STRING || !(date as string)?.includes('T') && !testRegex)\n return false;\n\n date = (date as string).split('T')[0];\n if (!new RegExp(/^\\d{4}-\\d{2}-\\d{2}$/).test(date))\n return false;\n\n return !!(new Date(date));\n })();\n } catch(error: unknown) {\n getLogger(isValidDate).error(error as Error | string);\n return false;\n }\n}\n\n/**\n * @description Formats a date into a localized string representation.\n * @summary This function converts a date value into a formatted string according to a specified\n * or system locale. It accepts multiple input formats (Date objects, timestamps, or date strings)\n * and returns a consistently formatted date string in DD/MM/YYYY format. If the input date is\n * invalid, the function returns the original input as a string. The function automatically\n * uses the system locale if none is provided and handles string format conversions by replacing\n * forward slashes with hyphens for proper Date parsing.\n *\n * @param {string | Date | number} date - The date to format. Can be a Date object, a timestamp number, or a date string\n * @param {string} [locale] - The locale to use for formatting. If not provided, the system's locale will be used\n * @returns {Date | string} A formatted date string in the format DD/MM/YYYY according to the specified locale,\n * or the original input as a string if the date is invalid\n *\n * @function formatDate\n * @memberOf module:lib/helpers/utils\n */\nexport function formatDate(date: string | Date | number, locale?: string | undefined): Date | string {\n\n if (!locale)\n locale = getLocaleLanguage();\n\n if (typeof date === 'string' || typeof date === 'number')\n date = new Date(typeof date === 'string' ? date.replace(/\\//g, '-') : date);\n\n if (!isValidDate(date))\n return `${date}` as string;\n const r = date.toLocaleString(locale, {\n year: \"numeric\",\n day: \"2-digit\",\n month: '2-digit'\n });\n\n\n return r;\n}\n\n/**\n * @description Attempts to parse a date string, Date object, or number into a valid Date object.\n * @summary This function provides robust date parsing functionality that handles the specific\n * format \"DD/MM/YYYY HH:MM:SS:MS\". It first validates the input date, and if already valid,\n * returns it as-is. For string inputs, it parses the date and time components separately,\n * extracts numeric values, and constructs a new Date object. The function includes validation\n * to ensure the resulting Date object is valid and logs a warning if parsing fails.\n * Returns null for invalid or unsupported date formats.\n *\n * @param {string | Date | number} date - The date to parse. Can be a Date object, a timestamp number,\n * or a date string in the format \"DD/MM/YYYY HH:MM:SS:MS\"\n * @returns {Date | null} A valid Date object if parsing is successful, or null if the date is invalid\n * or doesn't match the expected format\n *\n * @function parseToValidDate\n * @memberOf module:lib/helpers/utils\n */\nexport function parseToValidDate(date: string | Date | number): Date | null {\n if (isValidDate(date))\n return date as Date;\n\n if (!`${date}`.includes('/'))\n return null;\n\n const [dateString, timeString] = (date as string).split(' ');\n const [day, month, year] = dateString.split('/').map(Number);\n const [hours, minutes, seconds, milliseconds] = timeString.split(':').map(Number);\n date = new Date(year, month - 1, day, hours, minutes, seconds, milliseconds);\n\n if (!isValidDate(date)) {\n console.warn('parseToValidDate - Invalid date format', date);\n return null;\n }\n\n return date;\n}\n\n\n/**\n * @description Maps an item object using a provided mapper object and optional additional properties.\n * @summary This function transforms a source object into a new object based on mapping rules defined\n * in the mapper parameter. It supports dot notation for nested property access (e.g., 'user.name.first')\n * and handles various data types including strings and complex objects. For date values, it automatically\n * formats them using the formatDate function. The function also allows merging additional properties\n * into the result. When a mapped value is null or undefined, it uses the original mapper value as\n * a fallback.\n *\n * @param {KeyValue} item - The source object to be mapped\n * @param {KeyValue} mapper - An object that defines the mapping rules. Keys represent the new property names,\n * and values represent the path to the corresponding values in the source object\n * @param {KeyValue} [props] - Optional additional properties to be included in the mapped object\n * @returns {KeyValue} A new object with properties mapped according to the mapper object and including any additional properties\n *\n * @function itemMapper\n * @memberOf module:lib/helpers/utils\n */\nexport function itemMapper(item: KeyValue, mapper: KeyValue, props?: KeyValue): KeyValue {\n return Object.entries(mapper).reduce((accum: KeyValue, [key, value]) => {\n const arrayValue = (value as string).split('.');\n if (!value) {\n accum[key] = value;\n } else {\n if (arrayValue.length === 1) {\n accum[key] = item?.[value as string] || (value !== key ? value : \"\");\n } else {\n let val;\n\n for (const _value of arrayValue)\n val = !val\n ? item[_value]\n : (typeof val === 'string' ? JSON.parse(val) : val)[_value];\n\n if (isValidDate(new Date(val))) val = `${formatDate(val)}`;\n\n accum[key] = val === null || val === undefined ? value : val;\n }\n }\n return Object.assign({}, props || {}, accum);\n }, {});\n}\n\n/**\n * @description Maps an array of data objects using a provided mapper object.\n * @summary This function transforms an array of objects by applying mapping rules to each item\n * using the itemMapper function. It processes each element in the data array and creates\n * new mapped objects based on the mapper configuration. The function includes validation\n * to ensure meaningful data: if a mapped item contains only null/undefined values, it\n * preserves the original item instead. This prevents data loss during transformation.\n * Returns an empty array if the input data is null, undefined, or empty.\n *\n * @template T - The type of the resulting mapped items\n * @param {T[]} data - The array of data objects to be mapped\n * @param {KeyValue} mapper - An object that defines the mapping rules\n * @param {KeyValue} [props] - Additional properties to be included in the mapped items\n * @returns {T[]} The array of mapped items. If an item in the original array does not have any non-null values after mapping,\n * the original item is returned instead\n *\n * @function dataMapper\n * @memberOf module:lib/helpers/utils\n */\nexport function dataMapper<T>(data: T[], mapper: KeyValue, props?: KeyValue): T[] {\n if (!data || !data.length) return [];\n return data.reduce((accum: T[], curr) => {\n const item = itemMapper(curr as KeyValue, mapper, props) as T;\n const hasValues =\n [...new Set(Object.values(item as T[]))].filter((value) => value).length >\n 0;\n accum.push(hasValues ? item : curr);\n return accum;\n }, []);\n}\n\n/**\n * @description Removes focus from the currently active DOM element\n * @summary This utility function blurs the currently focused element in the document,\n * effectively removing focus traps that might prevent proper navigation or keyboard\n * interaction. It safely accesses the document's activeElement and calls blur() if\n * an element is currently focused. This is useful for accessibility and user experience\n * improvements, particularly when closing modals or dialogs.\n *\n * @return {void}\n *\n * @function removeFocusTrap\n * @memberOf module:for-angular\n */\nexport function removeFocusTrap(): void {\n const doc = getWindowDocument();\n if (doc?.activeElement)\n (doc.activeElement as HTMLElement)?.blur();\n}\n\n/**\n * @description Cleans and normalizes whitespace in a string value\n * @summary This utility function trims leading and trailing whitespace from a string\n * and replaces multiple consecutive whitespace characters with a single space.\n * Optionally converts the result to lowercase for consistent text processing.\n * This is useful for normalizing user input, search terms, or data sanitization.\n *\n * @param {string} value - The string value to clean and normalize\n * @param {boolean} [lowercase=false] - Whether to convert the result to lowercase\n * @return {string} The cleaned and normalized string\n *\n * @function cleanSpaces\n * @memberOf module:for-angular\n */\nexport function cleanSpaces(value: string = \"\", lowercase: boolean = false): string {\n value = `${value}`.trim().replace(/\\s+/g, ' ');\n return lowercase ? value.toLowerCase() : value;\n}\n\n\n/**\n * @description Determines if the user's system is currently in dark mode\n * @summary This function checks the user's color scheme preference using the CSS media query\n * '(prefers-color-scheme: dark)'. It returns a boolean indicating whether the system is\n * currently set to dark mode. This is useful for implementing theme-aware functionality\n * and adjusting UI elements based on the user's preferred color scheme.\n *\n * @return {Promise<boolean>} True if the system is in dark mode, false otherwise\n *\n * @function isDarkMode\n * @memberOf module:for-angular\n */\nexport async function isDarkMode(): Promise<boolean> {\n const {matches} = getWindow().matchMedia('(prefers-color-scheme: dark)');\n return matches;\n}\n\n/**\n * @description Filters out strings containing or not containing a specific substring from an array or space-separated string.\n * @summary This function removes or retains strings based on whether they include the specified substring.\n * If the input is a single string, it is split into an array using spaces as delimiters before filtering.\n *\n * @param {string | string[]} original - The input string or array of strings to filter.\n * @param {string} value - The substring to filter by.\n * @param {boolean} [contain=true] - Determines the filtering behavior. If true, retains strings containing the substring; otherwise, removes them.\n * @returns {string} A string that contains or excludes the specified substring based on the `contain` parameter.\n *\n * @function filterString\n * @memberOf module:lib/helpers/utils\n */\nexport function filterString(original: string | string[], value: string, contain: boolean = true): string {\n if (typeof original === Primitives.STRING)\n original = (original as string).split(' ');\n return ((original as string[]).filter(str =>\n contain ?\n str.includes(value) : !str.includes(value)\n ) || []).join(' ');\n}\n","/**\n * @module lib/engine/NgxFormService\n * @description Utilities to create and manage Angular forms in Decaf components.\n * @summary The NgxFormService exposes helpers to build FormGroup/FormArray instances\n * from component metadata or UI model definitions, register forms in a registry,\n * validate and extract form data, and create controls with appropriate validators.\n */\nimport { escapeHtml, FieldProperties, HTML5CheckTypes, HTML5InputTypes, IPagedComponentProperties, parseToNumber, UIModelMetadata } from '@decaf-ts/ui-decorators';\nimport { FieldUpdateMode, FormParent, FormParentGroup, KeyValue } from '../engine/types';\nimport { IComponentConfig, IFormComponentProperties } from '../engine/interfaces';\nimport { AbstractControl, FormArray, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';\nimport { isValidDate, ModelKeys, parseDate, Primitives, Validation } from '@decaf-ts/decorator-validation';\nimport { ValidatorFactory } from '../engine/ValidatorFactory';\nimport { cleanSpaces } from '../utils/helpers';\nimport { OperationKeys } from '@decaf-ts/db-decorators';\nimport { BaseComponentProps } from '../engine/constants';\n\n\n/**\n * @description Service for managing Angular forms and form controls.\n * @summary The NgxFormService provides utility methods for creating, managing, and validating Angular forms and form controls. It includes functionality for registering forms, adding controls, validating fields, and handling form data.\n *\n * @class\n * @param {WeakMap<AbstractControl, FieldProperties>} controls - A WeakMap to store control properties.\n * @param {Map<string, FormGroup>} formRegistry - A Map to store registered forms.\n *\n * @example\n * // Creating a form from components\n * const components = [\n * { inputs: { name: 'username', type: 'text', required: true } },\n * { inputs: { name: 'password', type: 'password', minLength: 8 } }\n * ];\n * const form = NgxFormService.createFormFromComponents('loginForm', components, true);\n *\n * // Validating fields\n * NgxFormService.validateFields(form);\n *\n * // Getting form data\n * const formData = NgxFormService.getFormData(form);\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant AF as Angular Forms\n * C->>NFS: createFormFromComponents()\n * NFS->>AF: new FormGroup()\n * NFS->>NFS: addFormControl()\n * NFS->>AF: addControl()\n * NFS-->>C: Return FormGroup\n * C->>NFS: validateFields()\n * NFS->>AF: markAsTouched(), markAsDirty(), updateValueAndValidity()\n * C->>NFS: getFormData()\n * NFS->>AF: Get control values\n * NFS-->>C: Return form data\n */\nexport class NgxFormService {\n /**\n * @description WeakMap that stores control properties for form controls.\n * @summary A WeakMap that associates AbstractControl instances with their corresponding FieldProperties.\n * This allows the service to track metadata for form controls without creating memory leaks.\n * @type {WeakMap<AbstractControl, FieldProperties>}\n * @private\n * @static\n */\n private static controls: WeakMap<AbstractControl, FieldProperties> = new WeakMap<AbstractControl, FieldProperties>();\n\n /**\n * @description Registry of form groups indexed by their unique identifiers.\n * @summary A Map that stores FormGroup instances with their unique string identifiers.\n * This allows global access to registered forms throughout the application.\n * @type {Map<string, FormGroup>}\n * @private\n * @static\n */\n private static formRegistry: Map<string, FormParent> = new Map<string, FormParent>();\n\n /**\n * @description Creates a new form group or form array with the specified identifier.\n * @summary Generates a FormGroup or FormArray based on the provided parameters. If formArray is true,\n * creates a FormArray; otherwise creates a FormGroup. The form can optionally be registered in the\n * global form registry for later access throughout the application. If a form with the given id\n * already exists in the registry, it returns the existing form.\n * @param {string} id - Unique identifier for the form\n * @param {boolean} [formArray=false] - Whether to create a FormArray instead of a FormGroup\n * @param {boolean} [registry=true] - Whether to register the form in the global registry\n * @return {FormGroup | FormArray} The created or existing form instance\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant FR as Form Registry\n * participant AF as Angular Forms\n * C->>NFS: createForm(id, formArray, registry)\n * NFS->>FR: Check if form exists\n * alt Form exists\n * FR-->>NFS: Return existing form\n * else Form doesn't exist\n * alt formArray is true\n * NFS->>AF: new FormArray([])\n * else\n * NFS->>AF: new FormGroup({})\n * end\n * alt registry is true\n * NFS->>FR: addRegistry(id, form)\n * end\n * end\n * NFS-->>C: Return FormGroup | FormArray\n * @static\n */\n static createForm(id: string, formArray = false, registry: boolean = true): FormGroup | FormArray {\n const form = this.formRegistry.get(id) ?? (formArray ? new FormArray([]) : new FormGroup({}));\n if (!this.formRegistry.has(id) && registry)\n this.addRegistry(id, form as FormArray | FormGroup);\n return form as FormArray | FormGroup;\n }\n\n\n /**\n * @description Adds a form to the registry.\n * @summary Registers a FormGroup or FormArray with a unique identifier for global access throughout\n * the application. This allows forms to be retrieved and managed centrally. Throws an error if\n * the identifier is already in use to prevent conflicts.\n * @param {string} formId - The unique identifier for the form\n * @param {FormParent} formGroup - The FormGroup or FormArray to be registered\n * @return {void}\n * @throws {Error} If a FormGroup with the given id is already registered\n * @static\n */\n static addRegistry(formId: string, formGroup: FormParent): void {\n if (this.formRegistry.has(formId))\n throw new Error(`A FormGroup with id '${formId}' is already registered.`);\n this.formRegistry.set(formId, formGroup);\n }\n\n /**\n * @description Retrieves a form from the registry by its identifier.\n * @summary Gets a FormGroup or FormArray from the registry using its unique identifier.\n * Returns undefined if the form is not found in the registry. This method provides\n * safe access to registered forms without throwing errors.\n * @param {string} [id] - The unique identifier of the form to retrieve\n * @return {FormParent | undefined} The FormGroup or FormArray if found, undefined otherwise\n * @static\n */\n static getOnRegistry(id?: string): FormParent | undefined {\n return this.formRegistry.get(id as string);\n }\n\n /**\n * @description Removes a form from the registry.\n * @summary Deletes a FormGroup or FormArray from the registry using its unique identifier.\n * This cleans up the registry and allows the identifier to be reused. The form itself\n * is not destroyed, only removed from the central registry.\n * @param {string} formId - The unique identifier of the form to be removed\n * @return {void}\n * @static\n */\n static removeRegistry(formId: string): void {\n this.formRegistry.delete(formId);\n }\n\n /**\n * @description Resolves the parent group and control name from a path.\n * @summary Traverses the form group structure to find the parent group and control name for a given path.\n * Handles complex nested structures including arrays and sub-groups. Creates missing intermediate\n * groups as needed and properly configures FormArray controls for multiple value scenarios.\n * @param {FormGroup} formGroup - The root FormGroup to traverse\n * @param {string} path - The dot-separated path to the control (e.g., 'user.address.street')\n * @param {IFormComponentProperties} componentProps - Properties defining the component configuration\n * @param {KeyValue} parentProps - Properties from the parent component for context\n * @return {FormParentGroup} A tuple containing the parent FormGroup and the control name\n * @private\n * @mermaid\n * sequenceDiagram\n * participant NFS as NgxFormService\n * participant FG as FormGroup\n * participant FA as FormArray\n * NFS->>NFS: Split path into parts\n * loop For each path part\n * alt Control doesn't exist\n * alt isMultiple and part is childOf\n * NFS->>FA: new FormArray([new FormGroup({})])\n * else\n * NFS->>FG: new FormGroup({})\n * end\n * NFS->>FG: addControl(part, newControl)\n * end\n * NFS->>NFS: Navigate to next level\n * end\n * NFS-->>NFS: Return [parentGroup, controlName]\n * @static\n */\n private static resolveParentGroup(\n formGroup: FormGroup,\n path: string,\n componentProps: IFormComponentProperties,\n parentProps: Partial<IFormComponentProperties>\n ): FormParentGroup {\n const isMultiple = parentProps?.multiple || parentProps?.type === Array.name || false;\n const parts = path.split('.');\n const controlName = parts.pop() as string;\n\n const {childOf} = componentProps\n let currentGroup = formGroup;\n function setArrayComponentProps(formGroupArray: KeyValue) {\n const props = formGroupArray?.[BaseComponentProps.FORM_GROUP_COMPONENT_PROPS] || {};\n if(!props[ModelKeys.MODEL][controlName])\n props[ModelKeys.MODEL] = Object.assign({}, props[ModelKeys.MODEL], {[controlName]: {...componentProps}});\n }\n\n for (const part of parts) {\n if (!currentGroup.get(part)) {\n const partFormGroup = (isMultiple && (part === childOf|| childOf?.endsWith(`${part}`))) ? new FormArray([new FormGroup({})]) : new FormGroup({});\n const pk = componentProps?.pk || parentProps?.pk || '';\n (partFormGroup as KeyValue)[BaseComponentProps.FORM_GROUP_COMPONENT_PROPS] = {\n childOf: childOf || '',\n isMultiple: isMultiple,\n name: part,\n pk,\n [ModelKeys.MODEL]: {},\n } as Partial<FieldProperties> & {model: KeyValue};\n\n if(currentGroup instanceof FormArray) {\n (currentGroup as FormArray).push(partFormGroup);\n } else {\n for(const control of Object.values(partFormGroup.controls)) {\n if(control instanceof FormControl)\n this.register(control as AbstractControl, componentProps);\n }\n\n if(partFormGroup instanceof AbstractControl)\n this.register(partFormGroup as AbstractControl, componentProps);\n currentGroup.addControl(part, partFormGroup);\n }\n }\n if(childOf && currentGroup instanceof FormArray)\n setArrayComponentProps(currentGroup);\n currentGroup = currentGroup.get(part) as FormGroup;\n }\n return [currentGroup, controlName];\n }\n\n /**\n * @description Retrieves component properties from a FormGroup or FormArray.\n * @summary Extracts component properties stored in the form group metadata. If a FormGroup is provided\n * and groupArrayName is specified, it will look for the FormArray within the form structure.\n * @param {FormGroup | FormArray} formGroup - The form group or form array to extract properties from\n * @param {string} [key] - Optional key to retrieve a specific property\n * @param {string} [groupArrayName] - Optional name of the group array if formGroup is not a FormArray\n * @return {Partial<FieldProperties>} The component properties or a specific property if key is provided\n * @static\n */\n static getComponentPropsFromGroupArray(formGroup: FormGroup | FormArray, key?: string, groupArrayName?: string | undefined): Partial<FieldProperties> {\n if(!(formGroup instanceof FormArray) && typeof groupArrayName === Primitives.STRING)\n formGroup = formGroup.root.get(groupArrayName as string) as FormArray || {};\n const props = (formGroup as KeyValue)?.[BaseComponentProps.FORM_GROUP_COMPONENT_PROPS] || {};\n return (!key ? props : props?.[key]) || {};\n }\n\n /**\n * @description Adds a new group to a parent FormArray.\n * @summary Creates and adds a new FormGroup to the specified parent FormArray based on the\n * component properties stored in the parent's metadata. This is used for dynamic form arrays\n * where new groups need to be added at runtime. Clones the control at the specified index\n * to maintain the same structure and validators.\n * @param {FormParent} parentForm - The FormArray or FormGroup containing the parent FormArray\n * @param {number} [index] - The index position to clone from; defaults to last index if length > 0, otherwise 0\n * @return {FormArray} The parent FormArray after adding the new group\n * @static\n */\n static addGroupToParent(parentForm: FormParent, index?: number): FormArray {\n if(parentForm instanceof FormGroup)\n parentForm = parentForm.parent as FormArray;\n index = index || (parentForm.length === 0 ? 0 : parentForm.length - 1);\n parentForm.push(this.cloneFormControl(parentForm.at(index)));\n return parentForm;\n }\n\n /**\n * @description Retrieves a FormGroup from a parent FormArray at the specified index.\n * @summary Gets a FormGroup from the specified parent FormArray. If the group doesn't exist\n * at the given index, it will create a new one using addGroupToParent.\n * @param {FormParent} formGroup - The root form group containing the parent FormArray\n * @param {string} parentName - The name of the parent FormArray to retrieve the group from\n * @param {number} [index=1] - The index of the group to retrieve\n * @return {FormGroup} The FormGroup at the specified index\n * @static\n */\n static getGroupFromParent(formGroup: FormParent, parentName: string, index: number = 1): FormGroup {\n const childGroup = ((formGroup.get(parentName) || formGroup) as FormArray).at(index);\n if(childGroup instanceof FormGroup)\n return childGroup;\n return this.addGroupToParent(formGroup, index).at(index) as FormGroup;\n }\n\n /**\n * @description Clones a form control with its validators.\n * @summary Creates a deep copy of a FormControl, FormGroup, or FormArray, preserving\n * validators but resetting values and state. This is useful for creating new instances\n * of form controls with the same validation rules, particularly in dynamic FormArrays\n * where new groups need to be added with identical structure.\n * @param {AbstractControl} control - The control to clone (FormControl, FormGroup, or FormArray)\n * @return {AbstractControl} A new instance of the control with the same validators\n * @throws {Error} If the control type is not supported\n * @static\n */\n static cloneFormControl(control: AbstractControl): AbstractControl {\n const syncValidators = (control.validator ? [control.validator] : []).filter(fn => {\n // if(lastIndex > 0)\n // if(fn !== Validators.required)\n // return fn;\n return fn;\n });\n const asyncValidators = control.asyncValidator ?? null;\n const validators = {\n validators: syncValidators,\n asyncValidators\n }\n if (control instanceof FormControl) {\n control = new FormControl(\"\", validators);\n // control.markAsPristine();\n // control.markAsUntouched();\n // control.setErrors(null);\n // control.updateValueAndValidity();\n return control;\n }\n\n if (control instanceof FormGroup) {\n const groupControls: Record<string, AbstractControl> = {};\n for (const key in control.controls) {\n groupControls[key] = this.cloneFormControl(control.controls[key]);\n }\n return new FormGroup(groupControls, validators);\n }\n\n if (control instanceof FormArray) {\n const arrayControls = control.controls.map(child => this.cloneFormControl(child));\n return new FormArray(arrayControls, validators);\n }\n\n throw new Error('Unsupported control type');\n }\n\n /**\n * @description Checks if a value is unique within a FormArray group.\n * @summary Validates that the primary key value in a FormGroup is unique among all groups\n * in the parent FormArray. The uniqueness check behavior differs based on the operation type.\n * For both CREATE and UPDATE operations, it checks that no other group in the array has the same\n * primary key value.\n * @param {FormGroup} formGroup - The FormGroup to check for uniqueness\n * @param {OperationKeys} [operation=OperationKeys.CREATE] - The type of operation being performed\n * @param {number} [index] - The index of the current group within the FormArray\n * @return {boolean} True if the value is unique, false otherwise\n * @static\n */\n static isUniqueOnGroup(formGroup: FormGroup, operation: OperationKeys = OperationKeys.CREATE, index?: number): boolean {\n const formArray = formGroup.parent as FormArray;\n if(index === undefined || index === null)\n index = formArray.length - 1;\n const pk = this.getComponentPropsFromGroupArray(formArray, BaseComponentProps.PK as string) as string;\n const controlName = Object.keys(formGroup.controls)[0];\n\n if(controlName !== pk || !pk)\n return true;\n const controlValue = cleanSpaces(`${formGroup.get(pk)?.value}`, true);\n if(operation === OperationKeys.CREATE) {\n return !formArray.controls.some((group, i) => {\n const value = cleanSpaces(`${group.get(pk)?.value}`, true);\n return i !== index && value === controlValue;\n });\n }\n\n return !formArray.controls.some((group, i) => {\n const value = cleanSpaces(`${group.get(pk)?.value}`, true);\n return i !== index && value === controlValue;\n });\n }\n\n /**\n * @description Enables all controls within a FormGroup or FormArray.\n * @summary Recursively enables all form controls within the provided FormGroup or FormArray.\n * This is useful for making all controls interactive after they have been disabled.\n * @param {FormArray | FormGroup} formGroup - The FormGroup or FormArray to enable all controls for\n * @return {void}\n * @static\n */\n static enableAllGroupControls(formGroup: FormArray | FormGroup): void {\n Object.keys(formGroup.controls).forEach(key => {\n const control = formGroup.get(key);\n if (control instanceof FormArray) {\n control.controls.forEach(child => {\n if (child instanceof FormGroup) {\n child.enable({ emitEvent: false });\n child.updateValueAndValidity({ emitEvent: true });\n }\n });\n }\n });\n }\n\n /**\n * @description Adds a form control to a form group based on component properties.\n * @summary Creates and configures a FormControl within the specified FormGroup using the provided\n * component properties. Handles nested paths, multiple controls (FormArrays), and control registration.\n * This method supports complex form structures with nested groups and arrays. It also manages\n * page-based forms and FormArray indexing.\n * @param {FormParent} formGroup - The form group or form array to add the control to\n * @param {IFormComponentProperties} componentProps - The component properties defining the control configuration\n * @param {Partial<IFormComponentProperties>} [parentProps={}] - Properties from the parent component for context\n * @param {number} [index=0] - The index for multiple controls in FormArrays\n * @return {FormParent} The updated form parent (FormGroup or FormArray)\n * @private\n * @static\n */\n private static addFormControl(formGroup: FormParent, componentProps: IFormComponentProperties, parentProps: Partial<IFormComponentProperties> = {}, index: number = 0): FormParent {\n\n const isMultiple = parentProps?.['multiple'] || parentProps?.['type'] === 'Array' || false;\n const { name, childOf } = componentProps;\n if(isMultiple)\n componentProps['pk'] = componentProps['pk'] || parentProps?.['pk'] || '';\n const fullPath = childOf ? isMultiple ? `${childOf}.${index}.${name}` : `${childOf}.${name}` : name;\n const [parentGroup, controlName] = this.resolveParentGroup(formGroup as FormGroup, fullPath, componentProps, parentProps);\n\n if (!parentGroup.get(controlName)) {\n const control = NgxFormService.fromProps(\n componentProps,\n componentProps.updateMode || 'change',\n );\n NgxFormService.register(control, componentProps);\n if (parentGroup instanceof FormGroup) {\n parentGroup.addControl(controlName, control);\n }\n if(parentGroup instanceof FormArray) {\n const root = parentGroup.controls[(componentProps as KeyValue)?.['page'] - 1] as FormGroup;\n if(root) {\n root.addControl(controlName, control);\n } else {\n parentGroup.push({[controlName]: control});\n }\n }\n }\n let rootGroup = parentGroup;\n if(rootGroup instanceof FormArray)\n rootGroup = (parentGroup as FormArray).controls[(componentProps as KeyValue)?.['page'] - 1] as FormParent;\n // if(childOf?.includes(\".\"))\n // rootGroup = (rootGroup as FormGroup)?.parent as FormArray\n\n // componentProps['formGroup'] = root as FormGroup;\n componentProps['formGroup'] = rootGroup as FormGroup;\n componentProps['formControl'] = parentGroup.get(controlName) as FormControl;\n // componentProps['multiple'] = isMultiple;\n\n return parentGroup as FormParent;\n }\n\n /**\n * @description Retrieves a control from a registered form.\n * @summary Finds and returns an AbstractControl from a registered form using the form id and optional path.\n * This method provides centralized access to form controls across the application by leveraging\n * the form registry system.\n * @param {string} formId - The unique identifier of the form in the registry\n * @param {string} [path] - The optional dot-separated path to a specific control within the form\n * @return {AbstractControl} The requested AbstractControl (FormGroup, FormArray, or FormControl)\n * @throws {Error} If the form is not found in the registry or the control is not found in the form\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant FR as Form Registry\n * C->>NFS: getControlFromForm(formId, path?)\n * NFS->>FR: Get form by formId\n * alt Form not found\n * FR-->>NFS: null\n * NFS-->>C: Throw Error\n * else Form found\n * FR-->>NFS: Return form\n * alt path provided\n * NFS->>NFS: form.get(path)\n * alt Control not found\n * NFS-->>C: Throw Error\n * else\n * NFS-->>C: Return control\n * end\n * else\n * NFS-->>C: Return form\n * end\n * end\n * @static\n */\n static getControlFromForm(formId: string, path?: string): AbstractControl {\n const form = this.formRegistry.get(formId);\n if (!form)\n throw new Error(`Form with id '${formId}' not found in the registry.`);\n\n if (!path)\n return form;\n\n const control = form.get(path);\n if (!control)\n throw new Error(`Control with path '${path}' not found in form '${formId}'.`);\n return control;\n }\n\n\n /**\n * @description Creates a form from UI model metadata children.\n * @summary Generates a FormGroup from an array of UIModelMetadata objects, extracting component\n * properties and creating appropriate form controls. This method is specifically designed to work\n * with the UI decorator system and provides automatic form generation from metadata.\n * @param {string} id - Unique identifier for the form\n * @param {boolean} [registry=false] - Whether to register the created form in the global registry\n * @param {UIModelMetadata[]} [children] - Array of UI model metadata objects to create controls from\n * @return {FormGroup} The created FormGroup with controls for each child metadata\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant AF as Angular Forms\n * C->>NFS: createFormFromChildren(id, registry, children)\n * NFS->>AF: new FormGroup({})\n * loop For each child metadata\n * NFS->>NFS: addFormControl(form, child.props)\n * NFS->>AF: Create and add FormControl\n * end\n * alt registry is true\n * NFS->>NFS: addRegistry(id, form)\n * end\n * NFS-->>C: Return FormGroup\n * @static\n */\n static createFormFromChildren(id: string, registry: boolean = false, children?: UIModelMetadata[],): FormGroup {\n const form = new FormGroup({});\n if(children?.length)\n children.forEach(child => {\n this.addFormControl(form, child.props as IFormComponentProperties);\n });\n if (registry)\n this.addRegistry(id, form);\n return form;\n }\n\n /**\n * @description Creates a form from component configurations.\n * @summary Generates a FormGroup based on an array of component configurations and optionally registers it.\n * This method processes component input configurations to create appropriate form controls with\n * validation and initial values.\n * @param {string} id - The unique identifier for the form\n * @param {IComponentConfig[]} components - An array of component configurations defining the form structure\n * @param {boolean} [registry=false] - Whether to register the created form in the global registry\n * @return {FormGroup} The created FormGroup with controls for each component configuration\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant AF as Angular Forms\n * C->>NFS: createFormFromComponents(id, components, registry)\n * NFS->>AF: new FormGroup({})\n * loop For each component config\n * NFS->>NFS: addFormControl(form, component.inputs)\n * NFS->>AF: Create and add FormControl\n * end\n * alt registry is true\n * NFS->>NFS: addRegistry(id, form)\n * end\n * NFS-->>C: Return FormGroup\n * @static\n */\n static createFormFromComponents(id: string, components: IComponentConfig[], registry: boolean = false): FormGroup {\n const form = new FormGroup({});\n components.forEach(component => {\n this.addFormControl(form, component.inputs);\n });\n\n if (registry)\n this.addRegistry(id, form);\n\n return form;\n }\n\n /**\n * @description Adds a control to a form based on component properties.\n * @summary Creates and adds a form control to a form (existing or new) based on the provided component properties.\n * Handles multi-page forms by managing FormArray structures and proper indexing. This method supports\n * complex form scenarios including nested controls and page-based form organization. It automatically\n * creates FormArrays for forms with multiple pages and manages page indexing.\n * @param {string} id - The unique identifier of the form\n * @param {ComponentProperties} props - The properties of the component to create the control from\n * @param {props} [parentProps] - Optional parent properties for context and configuration\n * @return {FormParent} The form or created control (FormGroup or FormArray)\n * @throws {Error} If page property is required but not provided or is invalid\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant F as Form\n * C->>NFS: addControlFromProps(id, props, parentProps?)\n * NFS->>NFS: createForm(id, formArray, true)\n * alt Multi-page form (parentProps.pages > 0)\n * NFS->>NFS: Calculate page index\n * alt Group doesn't exist at index\n * NFS->>F: Create new FormGroup at index\n * end\n * NFS->>NFS: Set form to page FormGroup\n * end\n * alt props has path\n * NFS->>NFS: addFormControl(form, props, parentProps)\n * end\n * NFS-->>C: Return form/control\n * @static\n */\n static addControlFromProps(id: string, props: IFormComponentProperties, parentProps?: IFormComponentProperties): FormParent {\n\n const componentPages = (typeof props?.pages === Primitives.NUMBER ?\n props?.pages : (props?.pages as IPagedComponentProperties[])?.length) as number;\n const parentPages = (typeof parentProps?.pages === Primitives.NUMBER ?\n parentProps?.pages : (parentProps?.pages as IPagedComponentProperties[])?.length) as number;\n\n const isFormArray = (componentPages && componentPages >= 1 || props.multiple === true);\n let form = this.createForm(id, isFormArray, true);\n\n if(parentPages && parentPages > 0) {\n const childOf = props.childOf || \"\";\n const parentChildOf = parentProps?.childOf || \"\";\n const index = props.page || parentProps?.page;\n // dont check page in nested childs with same childOf\n if((!(typeof index === 'number') || index === 0) && (childOf.length && childOf !== parentChildOf))\n throw Error(`Property 'page' is required and greather than 0 on ${props.name}`);\n // if(index > formLength) {\n // if((form as KeyValue)?.['lastIndex'] && index === (form as KeyValue)['lastIndex']['page']) {\n // index = (form as KeyValue)['lastIndex']['index'];\n // } else {\n // (form as KeyValue)['lastIndex'] = {\n // page: index,\n // index: formLength + 1\n // };\n // index = formLength + 1;\n\n // }\n // }\n let group = (form as FormArray).controls[(index as number) - 1];\n if(!group) {\n group = new FormGroup({});\n (form as FormArray).insert(index as number, group);\n }\n form = group as FormGroup;\n }\n if(props.path)\n form = this.addFormControl(form, props, parentProps);\n return form;\n }\n\n /**\n * @description Retrieves form data from a FormGroup.\n * @summary Extracts and processes the data from a FormGroup, handling different input types and nested form groups.\n * Performs type conversion for various HTML5 input types, validates nested controls, and manages\n * multiple control scenarios. Automatically enables all group controls after data extraction.\n * @param {FormGroup} formGroup - The FormGroup to extract data from\n * @return {Record<string, unknown>} An object containing the processed form data with proper type conversions\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant FG as FormGroup\n * participant FC as FormControl\n * C->>NFS: getFormData(formGroup)\n * loop For each control in formGroup\n * alt Control is not FormControl\n * NFS->>NFS: Recursive getFormData(control)\n * alt parentProps.multiple and !isValid\n * NFS->>NFS: reset(control)\n * end\n * else Control is FormControl\n * NFS->>FC: Get control value\n * NFS->>NFS: Apply type conversion based on props.type\n * alt HTML5CheckTypes\n * NFS->>NFS: Keep boolean value\n * else NUMBER type\n * NFS->>NFS: parseToNumber(value)\n * else DATE/DATETIME types\n * NFS->>NFS: new Date(value)\n * else Other types\n * NFS->>NFS: escapeHtml(value)\n * end\n * end\n * end\n * NFS->>NFS: enableAllGroupControls(formGroup)\n * NFS-->>C: Return processed data object\n * @static\n */\n static getFormData(formGroup: FormGroup): Record<string, unknown> {\n const data: Record<string, unknown> = {};\n for (const key in formGroup.controls) {\n const control = formGroup.controls[key];\n const parentProps = NgxFormService.getPropsFromControl(formGroup as FormGroup | FormArray);\n if (!(control instanceof FormControl)) {\n if(control.disabled)\n continue;\n const value = NgxFormService.getFormData(control as FormGroup);\n const isValid = control.valid;\n if(parentProps.multiple) {\n if(isValid) {\n data[key] = value;\n } else {\n this.reset(control as FormControl);\n }\n continue;\n }\n data[key] = value;\n continue;\n }\n\n const props = NgxFormService.getPropsFromControl(control as FormControl | FormArray);\n let value = control.value;\n if (!HTML5CheckTypes.includes(props['type'])) {\n switch (props['type']) {\n case HTML5InputTypes.NUMBER:\n value = parseToNumber(value);\n break;\n case HTML5InputTypes.DATE:\n case HTML5InputTypes.DATETIME_LOCAL:\n value = new Date(value);\n break;\n default:\n value = escapeHtml(value);\n }\n } else {\n if(props['type'] === HTML5InputTypes.CHECKBOX && Array.isArray(value))\n value = control.value;\n }\n data[key] = value;\n }\n NgxFormService.enableAllGroupControls(formGroup as FormGroup);\n return data;\n }\n\n /**\n * @description Validates fields in a form control or form group.\n * @summary Recursively validates all fields in a form control or form group, marking them as touched and dirty.\n * Performs comprehensive validation including uniqueness checks for primary keys in FormArray scenarios.\n * This method ensures all validation rules are applied and form state is properly updated.\n * @param {AbstractControl} control - The control or form group to validate\n * @param {string} [pk] - Optional primary key field name for uniqueness validation\n * @param {string} [path] - The path to the control within the form for error reporting\n * @return {boolean} True if all fields are valid, false otherwise\n * @throws {Error} If no control is found at the specified path or if the control type is unknown\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant FC as FormControl\n * participant FG as FormGroup\n * participant FA as FormArray\n * C->>NFS: validateFields(control, pk?, path?)\n * alt Control is FormControl\n * NFS->>FC: markAsTouched()\n * NFS->>FC: markAsDirty()\n * NFS->>FC: updateValueAndValidity()\n * alt Is in FormArray group\n * NFS->>NFS: Check uniqueness in group\n * alt Not unique\n * NFS->>FC: setErrors({notUnique: true})\n * end\n * end\n * NFS-->>C: Return control.valid\n * else Control is FormGroup\n * loop For each child control\n * NFS->>NFS: Recursive validateFields(child)\n * end\n * NFS-->>C: Return allValid\n * else Control is FormArray\n * loop For each array control\n * NFS->>NFS: Recursive validateFields(child)\n * end\n * NFS-->>C: Return allValid\n * else Unknown control type\n * NFS-->>C: Throw Error\n * end\n * @static\n */\n static validateFields(control: AbstractControl, pk?: string, path?: string): boolean {\n control = path ? control.get(path) as AbstractControl : control;\n if (!control)\n throw new Error(`No control found at path: ${path || 'root'}.`);\n\n const isAllowed = [FormArray, FormGroup, FormControl].some(type => control instanceof type);\n if (!isAllowed)\n throw new Error(`Unknown control type at: ${path || 'root'}`);\n\n control.markAsTouched();\n control.markAsDirty();\n control.updateValueAndValidity({emitEvent: true });\n\n if (control instanceof FormGroup) {\n Object.values(control.controls).forEach(childControl => {\n this.validateFields(childControl);\n });\n }\n\n if (control instanceof FormArray) {\n const totalGroups = control.length;\n const hasValid = control.controls.some(control => control.valid);\n if(totalGroups > 1 && hasValid) {\n for (let i = control.length - 1; i >= 0; i--) {\n const childControl = control.at(i);\n // disable no valid groups on array\n if (!childControl.valid) {\n (childControl.parent as FormGroup).setErrors(null);\n (childControl.parent as FormGroup).updateValueAndValidity({ emitEvent: true });\n childControl.disable();\n } else {\n this.validateFields(childControl);\n }\n }\n } else {\n Object.values(control.controls).forEach(childControl => {\n this.validateFields(childControl);\n });\n }\n }\n\n // function getControlName(control: AbstractControl): string | null {\n // const group = control.parent as FormGroup;\n // if (!group)\n // return null;\n // return Object.keys(group.controls).find(name => control === group.get(name)) || null;\n // }\n\n return control?.disabled ? true : control.valid;\n }\n\n /**\n * @description Generates validators from component properties.\n * @summary Creates an array of ValidatorFn based on the supported validation keys in the component properties.\n * Maps each validation property to its corresponding Angular validator function using the ValidatorFactory.\n * Only processes properties that are recognized as validation keys by the Validation utility.\n * @param {KeyValue} props - The component properties containing validation rules\n * @return {ValidatorFn[]} An array of validator functions\n * @private\n * @static\n */\n private static validatorsFromProps(props: KeyValue): ValidatorFn[] {\n const supportedValidationKeys = Validation.keys();\n return Object.keys(props)\n .filter((k: string) => supportedValidationKeys.includes(k))\n .map((k: string) => {\n return ValidatorFactory.spawn(props as FieldProperties, k);\n });\n }\n\n /**\n * @description Creates a FormControl from component properties.\n * @summary Generates a FormControl with validators and initial configuration based on the provided\n * component properties. Handles different input types, sets initial values, and configures\n * validation rules and update modes.\n * @param {FieldProperties} props - The component properties defining the control configuration\n * @param {FieldUpdateMode} [updateMode='change'] - The update mode for the control ('change', 'blur', 'submit')\n * @return {FormControl} The created FormControl with proper configuration and validators\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant VF as ValidatorFactory\n * participant AF as Angular Forms\n * C->>NFS: fromProps(props, updateMode?)\n * NFS->>NFS: validatorsFromProps(props)\n * NFS->>VF: Create validators from props\n * VF-->>NFS: Return validator array\n * NFS->>NFS: Compose validators\n * alt props.value exists and not checkbox\n * alt props.type is DATE\n * NFS->>NFS: Validate date format\n * end\n * NFS->>NFS: Set initial value\n * end\n * NFS->>AF: new FormControl(config)\n * AF-->>NFS: Return FormControl\n * NFS-->>C: Return configured FormControl\n * @static\n */\n static fromProps(props: FieldProperties, updateMode: FieldUpdateMode = 'change'): FormControl {\n const validators = this.validatorsFromProps(props);\n const composed = validators.length ? Validators.compose(validators) : null;\n return new FormControl(\n {\n value:\n props.value\n ? props.type === HTML5InputTypes.CHECKBOX ?\n Array.isArray(props.value) ? props.value : undefined\n : props.type === HTML5InputTypes.DATE\n ? !isValidDate(parseDate(props.format as string, props.value as string))\n ? undefined : props.value :\n (props.value as unknown) : undefined,\n disabled: props.disabled,\n },\n {\n validators: composed,\n updateOn: updateMode,\n },\n );\n }\n\n /**\n * @description Retrieves properties from a FormControl, FormArray, or FormGroup.\n * @summary Gets the FieldProperties associated with a form control from the internal WeakMap.\n * This method provides access to the original component properties that were used to create\n * the control, enabling validation, rendering, and behavior configuration.\n * @param {FormControl | FormArray | FormGroup} control - The form control to get properties for\n * @return {FieldProperties} The properties associated with the control, or empty object if not found\n * @static\n */\n static getPropsFromControl(control: FormControl | FormArray | FormGroup): FieldProperties {\n return this.controls.get(control) || {} as FieldProperties;\n }\n\n /**\n * @description Finds a parent element with a specific tag in the DOM tree.\n * @summary Traverses up the DOM tree to find the nearest parent element with the specified tag name.\n * This is useful for finding container elements or specific parent components in the DOM hierarchy.\n * The search is case-insensitive for tag name matching.\n * @param {HTMLElement} el - The starting element to traverse from\n * @param {string} tag - The tag name to search for (case-insensitive)\n * @return {HTMLElement} The found parent element with the specified tag\n * @throws {Error} If no parent with the specified tag is found in the DOM tree\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant DOM as DOM Tree\n * C->>NFS: getParentEl(element, tagName)\n * loop Traverse up DOM tree\n * NFS->>DOM: Get parentElement\n * DOM-->>NFS: Return parent or null\n * alt Parent exists and tag matches\n * NFS-->>C: Return parent element\n * else Parent is null\n * NFS-->>C: Throw Error\n * end\n * end\n * @static\n */\n static getParentEl(el: HTMLElement, tag: string): HTMLElement {\n let parent: HTMLElement | null;\n while ((parent = el.parentElement) !== null) {\n if (parent.tagName.toLowerCase() === tag.toLowerCase()) {\n return parent;\n }\n el = parent;\n }\n throw new Error(\n `No parent with the tag ${tag} was found for provided element`,\n );\n }\n\n /**\n * @description Registers a control with its properties in the internal WeakMap.\n * @summary Associates a form control with its component properties for later retrieval.\n * This enables the service to maintain metadata about controls without creating memory leaks,\n * as WeakMap automatically cleans up references when controls are garbage collected.\n * @param {AbstractControl} control - The control to register (FormControl, FormGroup, or FormArray)\n * @param {FieldProperties} props - The properties to associate with the control\n * @return {void}\n * @static\n */\n static register(control: AbstractControl, props: FieldProperties): void {\n this.controls.set(control, props);\n }\n\n /**\n * @description Unregisters a control from the internal WeakMap.\n * @summary Removes a control and its associated properties from the internal WeakMap.\n * This cleans up the metadata tracking for the control and frees up memory. Returns\n * true if the control was found and removed, false if it was not in the registry.\n * @param {AbstractControl} control - The control to unregister (FormControl, FormGroup, or FormArray)\n * @return {boolean} True if the control was successfully unregistered, false otherwise\n * @static\n */\n static unregister(control: AbstractControl): boolean {\n return this.controls.delete(control);\n }\n\n /**\n * @description Resets a form group or form control.\n * @summary Recursively resets all controls in a form group or a single form control, clearing values,\n * errors, and marking them as pristine and untouched. For FormControls, it sets the value to empty\n * string (except for checkbox types) and clears validation errors. For FormGroups, it recursively\n * resets all child controls.\n * @param {FormGroup | FormControl} formGroup - The form group or form control to reset\n * @return {void}\n * @static\n */\n static reset(formGroup: FormGroup | FormControl): void {\n if(formGroup instanceof FormControl) {\n const control = formGroup as FormControl;\n const { type } = NgxFormService.getPropsFromControl(control);\n if (!HTML5CheckTypes.includes(type))\n control.setValue(\"\");\n control.markAsPristine();\n control.markAsUntouched();\n control.setErrors(null);\n control.updateValueAndValidity();\n } else {\n for (const key in formGroup.controls) {\n const control = formGroup.controls[key];\n NgxFormService.reset(control as FormControl);\n continue;\n }\n }\n }\n}\n","import { faker } from '@faker-js/faker';\nimport { parseToNumber } from '@decaf-ts/ui-decorators';\nimport { Model, Primitives } from '@decaf-ts/decorator-validation';\nimport { InternalError } from '@decaf-ts/db-decorators';\nimport { Metadata, uses } from '@decaf-ts/decoration';\nimport { Repository } from '@decaf-ts/core';\nimport { DB_ADAPTER_PROVIDER } from '../for-angular-common.module';\nimport { DecafRepository, KeyValue, FunctionLike } from '../engine/types';\nimport { formatDate, getOnWindow } from './helpers';\n\nexport class DecafFakerRepository<T extends Model> {\n protected data: T[] = [];\n\n protected _repository: DecafRepository<Model> | undefined = undefined;\n\n constructor(\n protected model: string | Model,\n protected limit: number = 36\n ) {}\n\n protected get repository(): DecafRepository<Model> {\n if (!this._repository) {\n const modelName =\n typeof this.model === 'string'\n ? this.model\n : (this.model as Model).constructor.name;\n const constructor = Model.get(modelName);\n if (!constructor)\n throw new InternalError(\n `Cannot find model ${modelName}. was it registered with @model?`\n );\n try {\n this.model = new constructor();\n const dbAdapterFlavour = getOnWindow(DB_ADAPTER_PROVIDER) || undefined;\n if (dbAdapterFlavour) uses(dbAdapterFlavour as string)(constructor);\n this._repository = Repository.forModel(constructor);\n } catch (error: unknown) {\n throw new InternalError((error as Error)?.message || (error as string));\n }\n }\n return this._repository;\n }\n\n public async initialize(): Promise<void> {\n if (!this._repository)\n this._repository = this.repository;\n }\n\n async generateData<T extends Model>(\n pkValues?: KeyValue,\n pk?: string,\n pkType?: string\n ): Promise<T[]> {\n const limit = pkValues\n ? Object.values(pkValues || {}).length - 1\n : this.limit;\n if (!pk)\n pk = this._repository?.pk as string;\n if (!pkType)\n pkType = Metadata.type(this.repository.class, pk).name.toLowerCase();\n\n const props = Object.keys(this.model as KeyValue).filter((k) => {\n if (pkType === Primitives.STRING)\n return !['updatedBy', 'createdAt', 'createdBy', 'updatedAt'].includes(\n k\n );\n return ![pk, 'updatedBy', 'createdAt', 'createdBy', 'updatedAt'].includes(\n k\n );\n });\n const dataProps: Record<string, FunctionLike> = {};\n for (const prop of props) {\n const type = Metadata.type(this.repository.class, prop).name.toLowerCase();\n switch ((type?.name || '').toLowerCase()) {\n case 'string':\n dataProps[prop] = () =>\n `${faker.lorem.word()} ${pk === prop ? ' - ' + faker.number.int({ min: 1, max: 200 }) : ''}`;\n break;\n case 'step':\n dataProps[prop] = () => faker.lorem.word();\n break;\n case 'email':\n dataProps[prop] = () => faker.internet.email();\n break;\n case 'number':\n dataProps[prop] = () => faker.number.int({ min: 1, max: 5 });\n break;\n case 'boolean':\n dataProps[prop] = () => faker.datatype.boolean();\n break;\n case 'date':\n dataProps[prop] = () => faker.date.past();\n break;\n case 'url':\n dataProps[prop] = () => faker.internet.url();\n break;\n case 'array':\n dataProps[prop] = () =>\n faker.lorem.words({ min: 2, max: 5 }).split(' ');\n break;\n }\n }\n\n const data = getFakerData<T>(\n limit,\n dataProps,\n typeof this.model === 'string' ? this.model : this.model?.constructor.name\n );\n\n if (!pkValues) return data;\n\n const values = Object.values(pkValues as KeyValue);\n const iterated: (string | number)[] = [];\n\n function getPkValue(item: KeyValue): T {\n if (values.length > 0) {\n const randomIndex = Math.floor(Math.random() * values.length);\n const selected = values.splice(randomIndex, 1)[0];\n const value =\n pkType === Primitives.STRING\n ? selected\n : pkType === Primitives.NUMBER\n ? parseToNumber(selected)\n : pkType === Array.name\n ? [selected]\n : selected;\n item[pk as string] = value;\n }\n if (!iterated.includes(item[pk as string])) {\n iterated.push(item[pk as string]);\n return item as T;\n }\n return undefined as unknown as T;\n }\n const uids = new Set();\n return data\n .map((d) => getPkValue(d))\n .filter((item: KeyValue) => {\n if (!item || uids.has(item[pk]) || !item[pk] || item[pk] === undefined)\n return false;\n uids.add(item[pk]);\n return true;\n })\n .filter(Boolean) as T[];\n }\n}\n\nexport function getFakerData<T extends Model>(\n limit = 100,\n data: Record<string, FunctionLike>,\n model?: string\n): T[] {\n let index = 1;\n return Array.from({ length: limit }, () => {\n const item: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n const val = value();\n item[key] = val?.constructor === Date ? formatDate(val) : val;\n }\n // if ((item as any)?.['code'])\n // (item as any).code = `${index}`;\n // item.id = index;\n // item.createdAt = faker.date.past({ refDate: '2025-01-01' });\n index = index + 1;\n return (!model ? item : Model.build(item, model)) as T;\n });\n}\n","/**\n * @module utils\n * @description Utility functions for Angular Decaf applications\n * @summary The utils module provides a collection of utility functions and types\n * that assist with common tasks in Decaf Angular applications. It includes functions\n * for array manipulation, date formatting, logging, string operations, and various\n * utility functions for working with Angular components and services. These helpers\n * simplify common operations and promote code reuse across the application.\n * Key exports include logging utilities, string manipulation functions, and component\n * utility functions.\n */\nexport * from './helpers';\nexport * from './DecafFakerRepository';\n","/**\n * @module lib/engine/NgxRenderingEngine\n * @description Angular rendering engine for Decaf model-driven UIs.\n * @summary Implements NgxRenderingEngine which converts model decorator metadata\n * into Angular components, manages component registration, and orchestrates\n * dynamic component creation and input mapping.\n * @link {@link NgxRenderingEngine}\n */\nimport { FieldDefinition, HTML5InputTypes, RenderingEngine } from '@decaf-ts/ui-decorators';\nimport { AngularFieldDefinition, KeyValue } from './types';\nimport { AngularDynamicOutput, IFormComponentProperties } from './interfaces';\nimport { AngularEngineKeys } from './constants';\nimport { Model, ModelKeys, Primitives } from '@decaf-ts/decorator-validation';\nimport { Constructor } from '@decaf-ts/decoration';\nimport { InternalError, OperationKeys } from '@decaf-ts/db-decorators';\nimport {\n ComponentMirror,\n ComponentRef,\n createEnvironmentInjector,\n EnvironmentInjector,\n Injector,\n reflectComponentType,\n runInInjectionContext,\n TemplateRef,\n Type,\n ViewContainerRef,\n createComponent,\n} from '@angular/core';\nimport { NgxFormService } from '../services/NgxFormService';\nimport { isDevelopmentMode } from '../utils';\nimport { FormParent } from './types';\nimport { getLogger } from '../for-angular-common.module';\n\n/**\n * @description Angular implementation of the RenderingEngine for Decaf components.\n * @summary This class extends the base RenderingEngine to provide Angular-specific rendering capabilities.\n * It handles the conversion of field definitions to Angular components, manages component registration,\n * and provides utilities for component creation and input handling. The engine converts model decorator\n * metadata into dynamically created Angular components with proper input binding and lifecycle management.\n * @template AngularFieldDefinition - Type for Angular-specific field definitions\n * @template AngularDynamicOutput - Type for Angular-specific component output\n * @class NgxRenderingEngine\n * @extends {RenderingEngine<AngularFieldDefinition, AngularDynamicOutput>}\n * @example\n * ```typescript\n * const engine = NgxRenderingEngine.get();\n * engine.initialize();\n * const output = engine.render(myModel, {}, viewContainerRef, injector, templateRef);\n * ```\n * @mermaid\n * sequenceDiagram\n * participant Client\n * participant Engine as NgxRenderingEngine\n * participant Components as RegisteredComponents\n *\n * Client->>Engine: get()\n * Client->>Engine: initialize()\n * Client->>Engine: render(model, props, vcr, injector, tpl)\n * Engine->>Engine: toFieldDefinition(model, props)\n * Engine->>Engine: fromFieldDefinition(fieldDef, vcr, injector, tpl)\n * Engine->>Components: components(fieldDef.tag)\n * Components-->>Engine: component constructor\n * Engine->>Engine: createComponent(component, inputs, metadata, vcr, injector, template)\n * Engine-->>Client: return AngularDynamicOutput\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\nexport class NgxRenderingEngine extends RenderingEngine<\n AngularFieldDefinition,\n AngularDynamicOutput\n> {\n private static _injector?: Injector;\n\n /**\n * @description Registry of components available for dynamic rendering.\n * @summary Static registry that stores all registered components indexed by their selector name.\n * Each component entry contains a constructor reference that can be used to instantiate\n * the component during the rendering process. This registry is shared across all instances\n * of the rendering engine and is populated through the registerComponent method.\n * @private\n * @static\n * @type {Record<string, { constructor: Constructor<unknown> }>}\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n private static _components: Record<\n string,\n { constructor: Constructor<unknown> }\n >;\n\n /**\n * @description Currently active model being rendered by the engine.\n * @summary Stores a reference to the model instance that is currently being processed\n * by the rendering engine. This property is set during the render method execution\n * and is used throughout the rendering lifecycle to access model data and metadata.\n * The definite assignment assertion (!) is used because this property is always\n * initialized before use within the render method.\n * @private\n * @type {Model}\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n private _model!: Model;\n\n /**\n * @description Current operation context for component visibility control.\n * @summary Static property that stores the current operation being performed,\n * which is used to determine component visibility through the 'hidden' property.\n * Components can specify operations where they should be hidden, and this property\n * provides the context for those visibility checks. The value is typically extracted\n * from the global properties during the rendering process.\n * @private\n * @static\n * @type {string | undefined}\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n private static _operation: string | undefined = undefined;\n\n /**\n * @description Reference to the currently active component instance.\n * @summary Static property that maintains a reference to the most recently created\n * component instance. This is used internally for component lifecycle management\n * and can be cleared through the destroy method. The reference allows access to\n * the active component instance for operations that need to interact with the\n * currently rendered component.\n * @private\n * @static\n * @type {Type<unknown> | undefined}\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n private static _instance: Type<unknown> | undefined;\n\n // private static _projectable: boolean = true\n\n /**\n * @description Parent component properties for child component inheritance.\n * @summary Static property that stores parent component properties that should be\n * inherited by child components. This is particularly used for passing page configuration\n * down to child components in multi-page forms. The property is cleared after rendering\n * to prevent property leakage between unrelated component trees.\n * @private\n * @static\n * @type {KeyValue | undefined}\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n private static _parentProps: KeyValue | undefined = undefined;\n\n /**\n * @description Constructs a new NgxRenderingEngine instance.\n * @summary Initializes a new instance of the Angular rendering engine by calling the parent\n * constructor with the 'angular' engine type identifier. This constructor sets up the base\n * rendering engine functionality with Angular-specific configurations and prepares the\n * instance for component registration and rendering operations.\n * @constructor\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n constructor() {\n super(AngularEngineKeys.FLAVOUR);\n }\n\n /**\n * @description Converts a field definition to an Angular component output.\n * @summary This private method takes a field definition and creates the corresponding Angular component.\n * It handles component instantiation, input property mapping, child component rendering, and visibility\n * control. The method validates input properties against the component's metadata and processes\n * child components recursively.\n * @param {FieldDefinition<AngularFieldDefinition>} fieldDef - The field definition to convert\n * @param {ViewContainerRef} vcr - The view container reference for component creation\n * @param {Injector} injector - The Angular injector for dependency injection\n * @param {TemplateRef<any>} tpl - The template reference for content projection\n * @param {string} registryFormId - Form identifier for the component renderer\n * @param {boolean} createComponent - Whether to create the component instance\n * @param {FormParent} [formGroup] - Optional form group for form components\n * @return {AngularDynamicOutput} The Angular component output with component reference and inputs\n * @mermaid\n * sequenceDiagram\n * participant Method as fromFieldDefinition\n * participant Components as NgxRenderingEngine.components\n * participant Angular as Angular Core\n * participant Process as processChild\n *\n * Method->>Components: components(fieldDef.tag)\n * Components-->>Method: component constructor\n * Method->>Angular: reflectComponentType(component)\n * Angular-->>Method: componentMetadata\n * Method->>Method: Validate input properties\n * Method->>Method: Create result object\n * alt Has children\n * Method->>Process: Process children recursively\n * Process->>Method: Return processed children\n * Method->>Angular: Create embedded view\n * Method->>Method: Create component instance\n * end\n * Method-->>Caller: return AngularDynamicOutput\n * @private\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n private fromFieldDefinition(\n fieldDef: FieldDefinition<AngularFieldDefinition>,\n vcr: ViewContainerRef,\n injector: Injector,\n tpl: TemplateRef<unknown>,\n registryFormId: string = Date.now().toString(36).toUpperCase(),\n createComponent: boolean = true,\n formGroup?: FormParent\n ): AngularDynamicOutput {\n const cmp =\n (fieldDef as KeyValue)?.['component'] ||\n NgxRenderingEngine.components(fieldDef.tag);\n const component = cmp.constructor as unknown as Type<unknown>;\n\n const componentMetadata = reflectComponentType(component);\n if (!componentMetadata) {\n throw new InternalError(\n `Metadata for component ${fieldDef.tag} not found.`\n );\n }\n\n const { inputs: possibleInputs } = componentMetadata;\n const inputs = { ...fieldDef.props };\n\n const unmappedKeys = Object.keys(inputs).filter((input) => {\n const isMapped = possibleInputs.find(\n ({ propName }) => propName === input\n );\n if (!isMapped) delete inputs[input];\n return !isMapped;\n });\n\n if (unmappedKeys.length > 0 && isDevelopmentMode())\n getLogger(this.fromFieldDefinition).warn(\n `Unmapped input properties for component ${fieldDef.tag}: ${unmappedKeys.join(', ')}`\n );\n\n const operation = NgxRenderingEngine._operation;\n\n const hiddenOn = inputs?.hidden || [];\n if ((hiddenOn as string[]).includes(operation as string))\n return { inputs, injector };\n\n // const customTypes = (inputs as KeyValue)?.['customTypes'] || [];\n // const hasFormRoot = Object.values(possibleInputs).some(({propName}) => propName === AngularEngineKeys.PARENT_FORM);\n // if (hasFormRoot && !inputs?.[AngularEngineKeys.PARENT_FORM] && formGroup)\n // inputs[AngularEngineKeys.PARENT_FORM] = formGroup;\n if(operation !== OperationKeys.CREATE && (hiddenOn as string[]).includes(OperationKeys.CREATE)) {\n fieldDef.props = {...fieldDef.props, ... {readonly: true, type: HTML5InputTypes.TEXT} };\n }\n\n const result: AngularDynamicOutput = {\n component,\n inputs,\n injector,\n };\n\n if (fieldDef.rendererId)\n (result.inputs as Record<string, unknown>)['rendererId'] =\n fieldDef.rendererId;\n // process children\n // generating DOM\n // const projectable = NgxRenderingEngine._projectable;\n // const template = !projectable ? [] : vcr.createEmbeddedView(tpl, injector).rootNodes;\n // const template = [];\n const hasChildren = Object.values(possibleInputs).some(\n ({ propName }) => propName === AngularEngineKeys.CHILDREN\n );\n const hasModel = Object.values(possibleInputs).some(\n ({ propName }) => propName === ModelKeys.MODEL\n );\n const componentInputs = Object.assign(\n inputs,\n hasModel ? { model: this._model } : {},\n hasChildren ? { children: fieldDef?.['children'] || [] } : {}\n );\n if (createComponent) {\n vcr.clear();\n const componentInstance = NgxRenderingEngine.createComponent(\n component,\n componentInputs,\n injector,\n componentMetadata,\n vcr,\n []\n );\n result.component = NgxRenderingEngine._instance =\n componentInstance as Type<unknown>;\n }\n if (fieldDef.children?.length) {\n if (!NgxRenderingEngine._parentProps && inputs?.['pages']) {\n NgxRenderingEngine._parentProps = { pages: inputs?.['pages'] };\n // NgxRenderingEngine._projectable = false;\n }\n\n result.children = fieldDef.children.map((child) => {\n const readonly = operation === OperationKeys.UPDATE && ((child?.props?.hidden || []) as string[]).includes(OperationKeys.CREATE);\n // const hiddenOn = (child?.props?.hidden || []) as string[];\n // // moved to ui decorators\n // if (child?.children?.length) {\n // child.children = child.children.filter(c => {\n // const hiddenOn = c?.props?.hidden || [];\n // if (!(hiddenOn as string[]).includes(operation as string))\n // return c\n // })\n // }\n // if (!hiddenOn?.length || !(hiddenOn as CrudOperations[]).includes(operation as CrudOperations))\n if(!readonly) {\n NgxFormService.addControlFromProps(registryFormId, child.props, {\n ...inputs,\n ...(NgxRenderingEngine._parentProps || {}),\n });\n } else {\n child.props = {...child.props, ... {readonly: true} };\n }\n return this.fromFieldDefinition(\n child,\n vcr,\n injector,\n tpl,\n registryFormId,\n false,\n formGroup\n );\n });\n }\n return result;\n }\n\n /**\n * @description Creates an Angular component instance with inputs and template projection.\n * @summary This static utility method creates an Angular component instance with the specified\n * inputs and template. It uses Angular's component creation API to instantiate the component\n * and then sets the input properties using the provided metadata.\n * @param {Type<unknown>} component - The component type to create\n * @param {KeyValue} [inputs={}] - The input properties to set on the component\n * @param {ComponentMirror<unknown>} metadata - The component metadata for input validation\n * @param {ViewContainerRef} vcr - The view container reference for component creation\n * @param {Injector} injector - The Angular injector for dependency injection\n * @param {Node[]} [template=[]] - The template nodes to project into the component\n * @return {ComponentRef<unknown>} The created component reference\n * @static\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n static createComponent<C>(\n component: Type<unknown>,\n inputs: KeyValue = {},\n injector?: Injector,\n metadata?: ComponentMirror<unknown>,\n vcr?: ViewContainerRef,\n template?: Node[]\n ): C {\n if (vcr && metadata && injector)\n return NgxRenderingEngine.createViewComponent(\n component,\n inputs,\n metadata,\n vcr,\n injector,\n template || []\n );\n return NgxRenderingEngine.createHostComponent(component, inputs, injector);\n }\n\n static createViewComponent<C>(\n component: Type<unknown>,\n inputs: KeyValue = {},\n metadata: ComponentMirror<unknown>,\n vcr: ViewContainerRef,\n injector: Injector,\n template: Node[] = []\n ): C {\n const cmp = vcr.createComponent(component as Type<unknown>, {\n environmentInjector: injector as EnvironmentInjector,\n projectableNodes: [template],\n });\n this.setInputs(cmp, inputs, metadata);\n return cmp.instance as C;\n }\n\n static createHostComponent<C>(\n component: Type<C | unknown> | string,\n props: KeyValue = {},\n injector?: Injector\n ): C {\n if (!injector)\n injector =\n NgxRenderingEngine._injector ||\n Injector.create({ providers: [], parent: Injector.NULL });\n const envInjector: EnvironmentInjector = createEnvironmentInjector(\n [],\n injector as EnvironmentInjector\n );\n\n let cmp: ComponentRef<unknown> = {} as ComponentRef<C>;\n\n runInInjectionContext(envInjector, () => {\n const host = document.createElement('div');\n component =\n typeof component === Primitives.STRING\n ? (NgxRenderingEngine.components(\n component as string\n ) as Type<unknown>)\n : component;\n if (!host) throw new Error('Cant create host element for component');\n\n cmp = createComponent(component as Type<unknown>, {\n environmentInjector: envInjector,\n hostElement: host,\n });\n\n const metadata = reflectComponentType(component as Type<unknown>);\n if (!metadata)\n throw new InternalError(\n `Metadata for component ${component} not found.`\n );\n\n const { inputs: possibleInputs } = metadata;\n const inputs = { ...props };\n\n const unmappedKeys = Object.keys(inputs).filter((input) => {\n const isMapped = possibleInputs.find(\n ({ propName }) => propName === input\n );\n if (!isMapped) delete inputs[input];\n return !isMapped;\n });\n\n if (unmappedKeys.length > 0 && isDevelopmentMode())\n getLogger(this.createHostComponent).warn(\n `Unmapped input properties for component ${component}: ${unmappedKeys.join(', ')}`\n );\n\n if (metadata)\n this.setInputs(\n cmp as ComponentRef<unknown>,\n inputs,\n metadata as ComponentMirror<unknown>\n );\n document.body.querySelector('ion-app')?.appendChild(host);\n });\n\n return cmp.instance as C;\n }\n\n /**\n * @description Extracts decorator metadata from a model.\n * @summary This method provides access to the field definition generated from a model's\n * decorators. It's a convenience wrapper around the toFieldDefinition method that\n * converts a model to a field definition based on its decorators and the provided\n * global properties.\n * @param {Model} model - The model to extract decorators from\n * @param {Record<string, unknown>} globalProps - Global properties to include in the field definition\n * @return {FieldDefinition<AngularFieldDefinition>} The field definition generated from the model\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n getDecorators(\n model: Model,\n globalProps: Record<string, unknown>\n ): FieldDefinition<AngularFieldDefinition> {\n return this.toFieldDefinition(model, globalProps);\n }\n\n /**\n * @description Destroys the current engine instance and cleans up resources.\n * @summary This static method clears the current instance reference and parent props,\n * effectively destroying the singleton instance of the rendering engine. Optionally\n * removes the form registry for the specified form ID. This can be used to reset the\n * engine state or to prepare for a new instance creation.\n * @param {string} [formId] - Optional form ID to remove from registry\n * @return {Promise<void>} A promise that resolves when the instance is destroyed\n * @static\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n static async destroy(formId?: string): Promise<void> {\n if (formId) NgxFormService.removeRegistry(formId);\n NgxRenderingEngine._instance = undefined;\n NgxRenderingEngine._parentProps = undefined;\n }\n\n /**\n * @description Renders a model into an Angular component output.\n * @summary This method takes a model and converts it to an Angular component output.\n * It first stores a reference to the model, then converts it to a field definition\n * using the base RenderingEngine's toFieldDefinition method, and finally converts\n * that field definition to an Angular component output using fromFieldDefinition.\n * @template M - Type extending Model\n * @param {M} model - The model to render\n * @param {Record<string, unknown>} globalProps - Global properties to pass to the component\n * @param {ViewContainerRef} vcr - The view container reference for component creation\n * @param {Injector} injector - The Angular injector for dependency injection\n * @param {TemplateRef<any>} tpl - The template reference for content projection\n * @return {AngularDynamicOutput} The Angular component output with component reference and inputs\n * @mermaid\n * sequenceDiagram\n * participant Client as Client Code\n * participant Render as render method\n * participant ToField as toFieldDefinition\n * participant FromField as fromFieldDefinition\n *\n * Client->>Render: render(model, globalProps, vcr, injector, tpl)\n * Render->>Render: Store model reference\n * Render->>ToField: toFieldDefinition(model, globalProps)\n * ToField-->>Render: fieldDef\n * Render->>FromField: fromFieldDefinition(fieldDef, vcr, injector, tpl)\n * FromField-->>Render: AngularDynamicOutput\n * Render-->>Client: return AngularDynamicOutput\n * @override\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n override render<M extends Model>(\n model: M,\n globalProps: Record<string, unknown>,\n vcr: ViewContainerRef,\n injector: Injector,\n tpl: TemplateRef<unknown>\n ): AngularDynamicOutput {\n let result: AngularDynamicOutput;\n if (!NgxRenderingEngine._injector) NgxRenderingEngine._injector = injector;\n try {\n this._model = model;\n const formId = Date.now().toString(36).toUpperCase();\n const fieldDef = this.toFieldDefinition(model, globalProps);\n const props = fieldDef.props as Partial<IFormComponentProperties>;\n if (!NgxRenderingEngine._operation)\n NgxRenderingEngine._operation = props?.operation || undefined;\n const isArray =\n (props?.pages && (props?.pages as number) >= 1) ||\n props?.multiple === true;\n const formGroup = NgxFormService.createForm(formId, isArray);\n result = this.fromFieldDefinition(\n fieldDef,\n vcr,\n injector,\n tpl,\n formId,\n true,\n formGroup\n );\n if (result.component)\n (result.component as KeyValue)['formGroup'] = formGroup;\n NgxRenderingEngine.destroy(formId);\n } catch (e: unknown) {\n throw new InternalError(\n `Failed to render Model ${model.constructor.name}: ${e}`\n );\n }\n\n return result;\n }\n\n /**\n * @description Initializes the rendering engine.\n * @summary This method initializes the rendering engine. It checks if the engine is already initialized\n * and sets the initialized flag to true. This method is called before the engine is used\n * to ensure it's properly set up for rendering operations.\n * @return {Promise<void>} A promise that resolves when initialization is complete\n * @override\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n override async initialize(): Promise<void> {\n if (!this.initialized) this.initialized = true;\n }\n\n /**\n * @description Registers a component with the rendering engine.\n * @summary This static method registers a component constructor with the rendering engine\n * under a specific name. It initializes the components registry if needed and throws\n * an error if a component is already registered under the same name to prevent\n * accidental overrides.\n * @param {string} name - The name to register the component under\n * @param {Constructor<unknown>} constructor - The component constructor\n * @return {void}\n * @static\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n static registerComponent(\n name: string,\n constructor: Constructor<unknown>\n ): void {\n if (!this._components) this._components = {};\n if (name in this._components)\n throw new InternalError(`Component already registered under ${name}`);\n this._components[name] = {\n constructor: constructor,\n };\n }\n\n /**\n * @description Retrieves registered components from the rendering engine.\n * @summary This static method retrieves either all registered components or a specific component\n * by its selector. When called without a selector, it returns an array of all registered\n * components. When called with a selector, it returns the specific component if found,\n * or throws an error if the component is not registered.\n * @param {string} [selector] - Optional selector to retrieve a specific component\n * @return {Object|Array} Either a specific component or an array of all components\n * @static\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n static components(selector?: string): object | string[] {\n if (!selector) return Object.values(this._components);\n if (!(selector in this._components))\n throw new InternalError(`No Component registered under ${selector}`);\n return this._components[selector];\n }\n\n /**\n * @description Sets input properties on a component instance.\n * @summary This static utility method sets input properties on a component instance\n * based on the provided inputs object and component metadata. It handles both simple\n * values and nested objects, recursively processing object properties. The method\n * validates each input against the component's metadata to ensure only valid inputs\n * are set.\n * @param {ComponentRef<unknown>} component - The component reference to set inputs on\n * @param {KeyValue} inputs - The input properties to set\n * @param {ComponentMirror<unknown>} metadata - The component metadata for input validation\n * @return {void}\n * @mermaid\n * sequenceDiagram\n * participant Caller\n * participant SetInputs as setInputs\n * participant Parse as parseInputValue\n * participant Component as ComponentRef\n *\n * Caller->>SetInputs: setInputs(component, inputs, metadata)\n * SetInputs->>SetInputs: Iterate through inputs\n * loop For each input\n * SetInputs->>SetInputs: Check if input exists in metadata\n * alt Input is 'props'\n * SetInputs->>Parse: parseInputValue(component, value)\n * Parse->>Parse: Recursively process nested objects\n * Parse->>Component: setInput(key, value)\n * else Input is valid\n * SetInputs->>Component: setInput(key, value)\n * end\n * end\n * @static\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n static setInputs(\n component: ComponentRef<unknown>,\n inputs: KeyValue,\n metadata: ComponentMirror<unknown>\n ): void {\n function parseInputValue(\n component: ComponentRef<unknown>,\n input: KeyValue\n ) {\n Object.keys(input).forEach((key) => {\n const value = input[key];\n if (typeof value === 'object' && !!value)\n return parseInputValue(component, value);\n component.setInput(key, value);\n });\n }\n\n Object.entries(inputs).forEach(([key, value]) => {\n const prop = metadata.inputs.find(\n (item: { propName: string }) => item.propName === key\n );\n if (prop) {\n if (key === 'props') {\n component.setInput(key, value);\n parseInputValue(component, value);\n }\n\n // if (key === 'locale' && !value)\n // value = getLocaleFromClassName(this._componentName);\n component.setInput(key, value);\n }\n });\n }\n}\n","/**\n * @module module:lib/i18n/Loader\n * @description Internationalization loader and helpers for the for-angular package.\n * @summary Provides an implementation of TranslateLoader (I18nLoader) and helper factories\n * to load translation resources. Also exposes locale utilities used by components to resolve\n * localized keys.\n *\n * @link {@link I18nLoader}\n */\nimport { inject } from '@angular/core';\nimport { HttpClient, provideHttpClient } from '@angular/common/http';\nimport { provideTranslateParser, provideTranslateService, RootTranslateServiceConfig, TranslateLoader, TranslateParser, TranslationObject } from '@ngx-translate/core';\nimport { Primitives, sf } from '@decaf-ts/decorator-validation';\nimport { forkJoin, Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport {I18nResourceConfig} from '../engine/interfaces';\nimport { FunctionLike, I18nResourceConfigType, KeyValue } from '../engine/types';\nimport { cleanSpaces, getLocaleFromClassName } from '../utils';\nimport en from './data/en.json';\nimport { I18N_CONFIG_TOKEN } from '../for-angular-common.module';\n\nconst libLanguage: Record<string, TranslationObject> = {en};\n\n/**\n * @description Retrieves the locale context for a given class, object, or string.\n * @summary Resolves the locale context by extracting the class name or using the provided suffix.\n *\n * @param {FunctionLike | object | string} clazz - The class, object, or string to derive the locale context from.\n * @param {string} [suffix] - An optional suffix to append to the locale context.\n * @returns {string} - The resolved locale context string.\n */\nexport function getLocaleContext(clazz: FunctionLike | object | string, suffix?: string): string {\n return getLocaleFromClassName(clazz, suffix);\n}\n\n\n/**\n * @description Generates a localized string by combining locale and phrase\n * @summary This utility function creates a properly formatted locale string by combining\n * a locale identifier with a phrase. It handles edge cases such as empty phrases,\n * missing locales, and phrases that already include the locale prefix. This function\n * is useful for ensuring consistent formatting of localized strings throughout the application.\n *\n * @param {string} locale - The locale identifier (e.g., 'en', 'fr')\n * @param {string | undefined} phrase - The phrase to localize\n * @return {string} The formatted locale string, or empty string if phrase is undefined\n *\n * @function generateLocaleFromString\n * @memberOf module:for-angular\n */\nexport function getLocaleContextByKey(\n locale: string,\n phrase: string | undefined\n): string {\n if (!phrase)\n return locale;\n if (!locale || phrase.includes(`${locale}.`))\n return phrase;\n const parts = phrase.split(' ');\n return `${locale}.${cleanSpaces(parts.join('.'), true)}`;\n}\n\n/**\n * @description Factory function for creating an instance of I18nLoader.\n * @summary Configures and returns an I18nLoader instance with the specified HTTP client and translation resources.\n *\n * @param {HttpClient} http - The HTTP client used to fetch translation resources.\n * @returns {TranslateLoader} - An instance of I18nLoader configured with the provided HTTP client and resources.\n */\nexport function I18nLoaderFactory(http: HttpClient): TranslateLoader {\n const { resources, versionedSuffix } = inject(I18N_CONFIG_TOKEN, { optional: true }) ?? provideI18nLoader().useValue;\n return new I18nLoader(http, resources?.length ? resources : [{ prefix: './app/assets/i18n/', suffix: '.json' }], versionedSuffix);\n}\n\n/**\n * @description Provides the I18nLoader configuration.\n * @summary Configures the translation resources and versioned suffix for the I18nLoader.\n *\n * @param {I18nResourceConfigType} [resources=[]] - The translation resources to be used by the loader.\n * @param {boolean} [versionedSuffix=false] - Whether to append a versioned suffix to resource URLs.\n * @returns {object} - The configuration object for the I18nLoader.\n */\nexport function provideI18nLoader(resources: I18nResourceConfigType = [], versionedSuffix: boolean = false) {\n if (!Array.isArray(resources)) {\n resources = [resources];\n }\n return {\n provide: I18N_CONFIG_TOKEN,\n useValue: { resources: [...resources], versionedSuffix },\n };\n}\n\n/**\n * @description Custom implementation of TranslateLoader for loading translations.\n * @summary Fetches and merges translation resources, supporting versioned suffixes and recursive merging.\n */\nexport class I18nLoader implements TranslateLoader {\n /**\n * @param {HttpClient} http - The HTTP client used to fetch translation resources.\n * @param {I18nResourceConfig[]} [resources=[]] - The translation resources to be loaded.\n * @param {boolean} [versionedSuffix=false] - Whether to append a versioned suffix to resource URLs.\n */\n constructor(private http: HttpClient, private resources: I18nResourceConfig[] = [], private versionedSuffix: boolean = false) {}\n\n /**\n * @description Appends a versioned suffix to the resource URL if enabled.\n * @summary Generates a versioned suffix based on the current date.\n *\n * @param {string} suffix - The original suffix of the resource URL.\n * @returns {string} - The modified suffix with a version string appended.\n */\n private getSuffix(suffix: string): string {\n if (!this.versionedSuffix) {\n return suffix;\n }\n const today = new Date();\n return `${suffix}?version=${today.getFullYear()}${today.getMonth()}${today.getDay()}`;\n }\n\n /**\n * @description Fetches and merges translations for the specified language.\n * @summary Loads translation resources, merges them recursively, and includes library keys.\n *\n * @param {string} lang - The language code for the translations to load.\n * @returns {Observable<TranslationObject>} - An observable that emits the merged translation object.\n */\n getTranslation(lang: string): Observable<TranslationObject> {\n const libKeys: KeyValue = libLanguage[lang] || libLanguage['en'] || {};\n const httpRequests$ = forkJoin(\n this.resources.map(config =>\n this.http.get<TranslationObject>(`${config.prefix}${lang}${this.getSuffix(config.suffix || '.json')}`)\n )\n );\n\n /**\n * @description Recursively merges two translation objects.\n * @summary Combines the properties of the source object into the target object.\n *\n * @param {KeyValue} target - The target object to merge into.\n * @param {KeyValue} source - The source object to merge from.\n * @returns {KeyValue} - The merged object.\n */\n function recursiveMerge(target: KeyValue, source: KeyValue): KeyValue {\n for (const key of Object.keys(source)) {\n if (source[key] instanceof Object) {\n if (!target[key]) Object.assign(target, { [key]: {} });\n recursiveMerge(target[key], source[key]);\n } else {\n Object.assign(target, { [key]: source[key] });\n }\n }\n return target;\n }\n\n return httpRequests$.pipe(\n map(res => {\n const merged = {\n ...libKeys,\n ...res.reduce((acc: KeyValue, current: KeyValue) => {\n for (const key in current) {\n let value = current[key] || {};\n if (libKeys[key]) {\n value = { ...libKeys[key], ...recursiveMerge(libKeys[key] as KeyValue, current[key] as KeyValue) };\n }\n acc[key] = value;\n }\n return acc;\n }, {}),\n };\n return merged;\n })\n );\n }\n}\n\n/**\n * @description Custom implementation of TranslateParser for interpolation.\n * @summary Extends TranslateParser to support string formatting with parameters.\n */\nexport class I18nParser extends TranslateParser {\n /**\n * @description Interpolates a translation string with parameters.\n * @summary Replaces placeholders in the translation string with parameter values.\n *\n * @param {string} value - The translation string to interpolate.\n * @param {object | string} [params={}] - The parameters to replace placeholders with.\n * @returns {string} - The interpolated translation string.\n */\n interpolate(value: string, params: object | string = {}): string {\n if (typeof params === Primitives.STRING) {\n params = { '0': params };\n }\n return sf(value, ...Object.values(params));\n }\n}\n\n/**\n * @description Provides the internationalization (i18n) configuration for the application.\n * @summary Configures the translation service with a fallback language, default language, custom parser, and loader.\n *\n * @param {RootTranslateServiceConfig} [config={fallbackLang: 'en', lang: 'en'}] - The configuration for the translation service, including fallback and default languages.\n * @param {I18nResourceConfigType} [resources=[]] - The translation resources to be used by the loader.\n * @param {boolean} [versionedSuffix=false] - Whether to append a versioned suffix to resource URLs.\n * @returns {Array} - An array of providers for the translation service and loader.\n */\nexport function provideI18n(\n config: RootTranslateServiceConfig = { fallbackLang: 'en', lang: 'en' },\n resources: I18nResourceConfigType = [],\n versionedSuffix: boolean = false\n) {\n return [\n provideHttpClient(),\n provideTranslateService({\n fallbackLang: config.fallbackLang,\n lang: config.lang,\n parser: provideTranslateParser(I18nParser),\n loader: {\n provide: TranslateLoader,\n useFactory: I18nLoaderFactory,\n deps: [HttpClient],\n },\n }),\n provideI18nLoader(resources, versionedSuffix),\n ];\n}\n","/**\n * @module NgxMediaService\n * @description Provides utilities for managing media-related features such as color scheme detection,\n * window resize observation, and SVG injection.\n * @summary\n * This module exposes the `NgxMediaService` class, which includes methods for observing the\n * application's color scheme, handling window resize events, and dynamically injecting SVG content\n * into the DOM. It leverages Angular's dependency injection system and RxJS for reactive programming.\n *\n * Key exports:\n * - {@link NgxMediaService}: The main service class providing media-related utilities.\n */\n\nimport { ElementRef, Injectable, NgZone, inject } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { fromEvent, Subject, Observable, BehaviorSubject, merge, of, timer } from 'rxjs';\nimport { distinctUntilChanged, map, shareReplay, takeUntil, tap, switchMap } from 'rxjs/operators';\nimport { IWindowResizeEvent } from '../engine/interfaces';\nimport { WindowColorScheme } from '../engine/types';\nimport { getWindow, getWindowDocument } from '../utils/helpers';\nimport { AngularEngineKeys, WindowColorSchemes } from '../engine/constants';\n\n\n\n\n/**\n * @description Service for managing media-related features in an Angular application.\n * @summary\n * The `NgxMediaService` provides utilities for observing and managing media-related features\n * such as color scheme detection, window resize events, and dynamic SVG injection. It leverages\n * Angular's dependency injection system and RxJS for reactive programming.\n *\n * @class NgxMediaService\n * @example\n * // Inject the service into a component\n * constructor(private mediaService: NgxMediaService) {}\n *\n * // Observe the current color scheme\n * this.mediaService.colorScheme$.subscribe(scheme => {\n * console.log('Current color scheme:', scheme);\n * });\n *\n * // Observe window resize events\n * this.mediaService.resize$.subscribe(dimensions => {\n * console.log('Window dimensions:', dimensions);\n * });\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class NgxMediaService {\n\n /**\n * @description Subject used to signal the destruction of the service.\n * @summary\n * This subject is used to complete observables and clean up resources when the service is destroyed.\n * It is utilized with the `takeUntil` operator to manage subscriptions.\n */\n private readonly destroy$ = new Subject<void>();\n\n /**\n * @description BehaviorSubject to track the window's dimensions.\n * @summary\n * This subject holds the current dimensions of the window (width and height) and emits updates\n * whenever the window is resized. It is used to provide the `resize$` observable.\n */\n private resizeSubject = new BehaviorSubject<IWindowResizeEvent>({\n width: this._window.innerWidth,\n height: this._window.innerHeight\n });\n\n /**\n * @description Angular's NgZone service for running code outside Angular's zone.\n * @summary\n * This service is used to optimize performance by running certain operations outside\n * Angular's zone and bringing updates back into the zone when necessary.\n */\n private readonly angularZone: NgZone = inject(NgZone);\n\n /**\n * @description Angular's HttpClient service for making HTTP requests.\n * @summary\n * This service is used to fetch resources such as SVG files for injection into the DOM.\n */\n // private http = inject(HttpClient);\n\n /**\n * @description Tracks the current color scheme of the application.\n * @summary\n * This property holds the current color scheme (light, dark, or undefined) and is updated\n * whenever the color scheme changes.\n */\n private currentSchema: WindowColorScheme = WindowColorSchemes.undefined;\n\n /**\n * @description Observable that emits the current color scheme of the application.\n * @summary\n * This observable emits the current color scheme (light or dark) and updates whenever\n * the system's color scheme preference changes or the `DARK_PALETTE_CLASS` is toggled.\n */\n readonly colorScheme$: Observable<WindowColorScheme> = this.colorSchemeObserver();\n\n /**\n * @description Observable that emits the current dimensions of the window.\n * @summary\n * This observable emits the current dimensions of the window (width and height) and updates\n * whenever the window is resized.\n */\n readonly resize$: Observable<IWindowResizeEvent> = this.resizeSubject.asObservable();\n\n /**\n * @description Retrieves the global `window` object.\n * @summary\n * This getter provides access to the global `window` object, ensuring it is properly typed.\n *\n * @return {Window} The global `window` object.\n */\n private get _window(): Window {\n return getWindow() as Window;\n }\n\n /**\n * @description Retrieves the global `document` object.\n * @summary\n * This getter provides access to the global `document` object, ensuring it is properly typed.\n *\n * @return {Document} The global `document` object.\n */\n private get _document(): Document {\n return getWindowDocument() as Document;\n }\n\n /**\n * @description Observes window resize events and emits the updated dimensions.\n * @summary\n * This method listens for window resize events and emits the new dimensions\n * (width and height) through the `resize$` observable. The resize events are\n * processed outside Angular's zone to improve performance, and updates are\n * brought back into the Angular zone to ensure change detection.\n *\n * @return {Observable<IWindowResizeEvent>} An observable that emits the window dimensions on resize.\n * @function windowResizeObserver\n * @example\n * mediaService.windowResizeObserver().subscribe(dimensions => {\n * console.log('Window dimensions:', dimensions);\n * });\n */\n windowResizeObserver(): Observable<IWindowResizeEvent> {\n const win = this._window;\n this.angularZone.runOutsideAngular(() => {\n fromEvent(win, 'resize')\n .pipe(\n distinctUntilChanged(),\n takeUntil(this.destroy$),\n shareReplay(1)\n )\n .subscribe(() => {\n const dimensions: IWindowResizeEvent = {\n width: win.innerWidth,\n height: win.innerHeight\n };\n // update within the zone to reflect in Angular\n this.angularZone.run(() => this.resizeSubject.next(dimensions));\n });\n });\n\n return this.resize$;\n }\n\n /**\n * @description Observes the color scheme of the application.\n * @summary\n * This method observes changes in the system's color scheme preference (light or dark)\n * and the presence of the `DARK_PALETTE_CLASS` on the document's root element.\n * Optionally, it can toggle the dark mode class on a specific component.\n *\n * @param {ElementRef | HTMLElement} [component] - Optional component to toggle the dark mode class on.\n * @return {Observable<WindowColorScheme>} An observable that emits the current color scheme (`dark` or `light`).\n * @function colorSchemeObserver\n * @example\n * // Observe the color scheme globally\n * mediaService.colorSchemeObserver().subscribe(scheme => {\n * console.log('Current color scheme:', scheme);\n * });\n *\n * // Observe and toggle dark mode on a specific component\n * const component = document.querySelector('.my-component');\n * mediaService.colorSchemeObserver(component).subscribe();\n */\n colorSchemeObserver(component?: ElementRef | HTMLElement): Observable<WindowColorScheme> {\n const win = this._window;\n const doc = this._document;\n const documentElement = doc.documentElement;\n const mediaFn = win.matchMedia(`(prefers-color-scheme: ${WindowColorSchemes.dark})`);\n\n if(component) {\n this.colorScheme$.subscribe((schema: WindowColorScheme) => {\n this.toggleClass(\n component,\n AngularEngineKeys.DARK_PALETTE_CLASS,\n schema === WindowColorSchemes.dark ? true : false\n );\n });\n }\n\n return merge(\n of(mediaFn.matches ? WindowColorSchemes.dark: WindowColorSchemes.light),\n // observe media query changes\n new Observable<WindowColorScheme>(observer => {\n this.angularZone.runOutsideAngular(() => {\n const mediaQuery = mediaFn;\n const subscription = fromEvent<MediaQueryListEvent>(mediaQuery, 'change')\n .pipe(map(event => (event.matches ? WindowColorSchemes.dark: WindowColorSchemes.light)))\n .subscribe(value => {\n this.angularZone.run(() => observer.next(value));\n });\n return () => subscription.unsubscribe();\n });\n }),\n // observe ngx-dcf-palettedark class changes\n new Observable<WindowColorScheme>(observer => {\n this.angularZone.runOutsideAngular(() => {\n const observerConfig = { attributes: true, attributeFilter: ['class'] };\n const mutationObserver = new MutationObserver(() => {\n const theme = documentElement.classList.contains(AngularEngineKeys.DARK_PALETTE_CLASS) ?\n WindowColorSchemes.dark: WindowColorSchemes.light;\n this.angularZone.run(() => observer.next(theme));\n });\n mutationObserver.observe(documentElement, observerConfig);\n // this.angularZone.run(() => observer.next(theme));\n\n // this.angularZone.run(() => observer.next(theme));\n return () => mutationObserver.disconnect();\n });\n })\n ).pipe(\n distinctUntilChanged(),\n tap(scheme => {\n const shouldAdd = scheme === WindowColorSchemes.dark;\n if (shouldAdd) {\n // always add when the emitted scheme is dark\n this.toggleClass(documentElement, AngularEngineKeys.DARK_PALETTE_CLASS, true);\n } else {\n // remove the class only if the previously stored schema was dark\n if (this.currentSchema === WindowColorSchemes.dark) {\n this.toggleClass(documentElement, AngularEngineKeys.DARK_PALETTE_CLASS, false);\n }\n }\n // store the latest schema value\n this.currentSchema = scheme;\n }),\n takeUntil(this.destroy$),\n shareReplay(1)\n );\n }\n\n /**\n * @description Observes the scroll state of the active page.\n * @summary\n * This method observes the scroll position of the active page's content and emits a boolean\n * indicating whether the scroll position exceeds the specified offset. It waits for a delay\n * before starting the observation to allow page transitions to complete.\n *\n * @param {number} offset - The scroll offset to compare against.\n * @param {number} [awaitDelay=500] - The delay in milliseconds before starting the observation.\n * @return {Observable<boolean>} An observable that emits `true` if the scroll position exceeds the offset, otherwise `false`.\n * @function observePageScroll\n * @example\n * mediaService.observePageScroll(100).subscribe(isScrolled => {\n * console.log('Page scrolled past 100px:', isScrolled);\n * });\n */\n observePageScroll(offset: number, awaitDelay: number = 500): Observable<boolean> {\n // await delay for page change to complete\n return timer(awaitDelay)\n .pipe(\n switchMap(\n () => new Observable<boolean>(observer => {\n const activeContent = this._document.querySelector('ion-router-outlet .ion-page:not(.ion-page-hidden) ion-content') as HTMLIonContentElement;\n if (!(activeContent && typeof (activeContent as HTMLIonContentElement).getScrollElement === 'function'))\n return this.angularZone.run(() => observer.next(false));\n\n (activeContent as HTMLIonContentElement).getScrollElement().then((element: HTMLElement) => {\n const emitScrollState = () => {\n const scrollTop = element.scrollTop || 0;\n this.angularZone.run(() => observer.next(scrollTop > offset));\n };\n element.addEventListener('scroll', emitScrollState);\n emitScrollState();\n return () => element.removeEventListener('scroll', emitScrollState);\n });\n\n })\n ),\n distinctUntilChanged(),\n takeUntil(this.destroy$),\n shareReplay(1)\n );\n }\n\n /**\n * @description Loads an SVG file and injects it into a target element.\n * @summary\n * This method fetches an SVG file from the specified path and injects its content\n * into the provided target element. The operation is performed outside Angular's\n * zone to improve performance, and the DOM update is brought back into the Angular\n * zone to ensure change detection.\n *\n * @param {string} path - The path to the SVG file.\n * @param {HTMLElement} target - The target element to inject the SVG content into.\n * @return {void}\n * @function loadSvgObserver\n * @example\n * const targetElement = document.getElementById('svg-container');\n * mediaService.loadSvgObserver('/assets/icons/icon.svg', targetElement);\n */\n loadSvgObserver(http: HttpClient, path: string, target: HTMLElement): void {\n this.angularZone.runOutsideAngular(() => {\n const svg$ = http.get(path, { responseType: 'text' }).pipe(\n takeUntil(this.destroy$),\n shareReplay(1)\n );\n svg$.subscribe(svg => {\n this.angularZone.run(() => {\n target.innerHTML = svg;\n });\n });\n });\n }\n\n /**\n * @description Determines if the current theme is dark mode.\n * @summary\n * Observes the `colorScheme$` observable and checks if the `DARK_PALETTE_CLASS` is present\n * on the document's root element or if the emitted color scheme is `dark`.\n *\n * @return {Observable<boolean>} An observable that emits `true` if dark mode is active, otherwise `false`.\n * @function isDarkMode\n * @example\n * mediaService.isDarkMode().subscribe(isDark => {\n * console.log('Dark mode active:', isDark);\n * });\n */\n isDarkMode(): Observable<boolean> {\n const documentElement = this._document.documentElement;\n return this.colorScheme$.pipe(\n map(scheme => documentElement.classList.contains(AngularEngineKeys.DARK_PALETTE_CLASS) || scheme === WindowColorSchemes.dark),\n distinctUntilChanged(),\n shareReplay(1),\n takeUntil(this.destroy$)\n );\n }\n\n /**\n * @description Toggles dark mode for a specific component.\n * @summary\n * Subscribes to the `colorScheme$` observable and adds or removes the `DARK_PALETTE_CLASS`\n * on the provided component based on the emitted color scheme.\n *\n * @param {ElementRef | HTMLElement} component - The target component to toggle dark mode on.\n * @return {void}\n * @function setDarkMode\n * @example\n * const component = document.querySelector('.my-component');\n * mediaService.setDarkMode(component);\n */\n setDarkMode(component: ElementRef | HTMLElement): void {\n this.colorScheme$.subscribe((scheme) => {\n this.toggleClass(\n component,\n AngularEngineKeys.DARK_PALETTE_CLASS,\n scheme === WindowColorSchemes.dark ? true : false\n );\n });\n }\n\n /**\n * @description Add or remove a CSS class on one or multiple elements.\n * @summary\n * Accepts an ElementRef, HTMLElement, or array of mixed elements and will add\n * or remove the provided `className` depending on the `add` flag. Operates\n * defensively: resolves ElementRef.nativeElement when needed and ignores\n * falsy entries.\n *\n * @param {(ElementRef | HTMLElement | unknown[])} component - Single element,\n * ElementRef, or array of elements to update.\n * @param {string} className - CSS class name to add or remove.\n * @param {boolean} [add=true] - Whether to add (true) or remove (false) the class.\n * @return {void}\n * @function toggleClass\n * @example\n * // Add a class to a single element\n * mediaService.toggleClass(element, 'active', true);\n *\n * // Remove a class from multiple elements\n * mediaService.toggleClass([element1, element2], 'hidden', false);\n */\n toggleClass(component: ElementRef | HTMLElement | unknown[], className: string, add: boolean = true): void {\n const components = Array.isArray(component) ? component : [component];\n components.forEach(element => {\n if ((element as ElementRef)?.nativeElement)\n element = (element as ElementRef).nativeElement;\n if(element instanceof HTMLElement) {\n switch (add) {\n case true:\n (element as HTMLElement).classList.add(className);\n break;\n case false:\n (element as HTMLElement).classList.remove(className);\n break;\n }\n }\n });\n }\n\n /**\n * @description Clean up internal subscriptions and observers used by the service.\n * @summary\n * Triggers completion of the internal `destroy$` subject so that any\n * Observables created with `takeUntil(this.destroy$)` will complete and\n * resources are released.\n *\n * @return {void}\n * @function destroy\n */\n destroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n}\n","/**\n * @module lib/engine/NgxComponentDirective\n * @description Base decaf component abstraction providing shared inputs and utilities.\n * @summary NgxComponentDirective is the abstract foundation for Decaf components and provides common\n * inputs (model, mapper, pk, props), logging, repository resolution, and event dispatch helpers.\n * It centralizes shared behavior for child components and simplifies integration with the rendering engine.\n * @link {@link NgxComponentDirective}\n */\nimport { Directive, ElementRef, EventEmitter, Inject, inject, Input, Output, SimpleChanges, ViewChild, OnChanges, ChangeDetectorRef, Renderer2, OnDestroy } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { Location } from '@angular/common';\nimport { TranslateService } from '@ngx-translate/core';\nimport { firstValueFrom } from 'rxjs';\nimport { Model, ModelConstructor, Primitives } from '@decaf-ts/decorator-validation';\nimport { CrudOperations, InternalError, OperationKeys } from '@decaf-ts/db-decorators';\nimport { DecafRepository, FunctionLike, KeyValue } from './types';\nimport { IBaseCustomEvent, ICrudFormEvent } from './interfaces';\nimport { NgxEventHandler } from './NgxEventHandler';\nimport { getLocaleContext } from '../i18n/Loader';\nimport { NgxRenderingEngine } from './NgxRenderingEngine';\nimport { getModelAndRepository, CPTKN } from '../for-angular-common.module';\nimport { AngularEngineKeys, BaseComponentProps } from './constants';\nimport { generateRandomValue, getWindow, setOnWindow } from '../utils';\nimport { EventIds } from '@decaf-ts/core';\nimport { NgxMediaService } from '../services/NgxMediaService';\nimport { DecafComponent, UIFunctionLike, UIKeys } from '@decaf-ts/ui-decorators';\n\ntry {\n const win = getWindow();\n if (!win?.[AngularEngineKeys.LOADED])\n new NgxRenderingEngine();\n setOnWindow(AngularEngineKeys.LOADED, true);\n} catch (e: unknown) {\n throw new Error(`Failed to load rendering engine: ${e}`);\n}\n\n/**\n * @description Base directive for Decaf components in Angular applications.\n * @summary Abstract base class that provides common functionality for all Decaf components.\n * This directive establishes a foundation for component development by offering shared inputs\n * (model, mapper, pk, props), logging infrastructure, repository access, event handling, and\n * internationalization support. It implements OnChanges to respond to input property changes\n * and includes utilities for navigation, localization, and dynamic property binding. All Decaf\n * components should extend this directive to inherit its foundational capabilities.\n * @class NgxComponentDirective\n * @extends {LoggedClass}\n * @implements {OnChanges}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n@Directive({host: {'[attr.id]': 'uid'}})\nexport abstract class NgxComponentDirective extends DecafComponent implements OnChanges, OnDestroy {\n\n\n /**\n * @description Reference to the component's native DOM element.\n * @summary Provides direct access to the native DOM element of the component through Angular's\n * ViewChild decorator. This reference can be used to manipulate the DOM element directly,\n * apply custom styles, or access native element properties and methods. The element is\n * identified by the 'component' template reference variable.\n * @type {ElementRef}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @ViewChild('component', { read: ElementRef, static: true })\n component!: ElementRef;\n\n /**\n * @description Flag to enable or disable dark mode support for the component.\n * @summary When enabled, the component will automatically detect the system's dark mode\n * preference using the media service and apply appropriate styling classes. This flag\n * controls whether the component should respond to dark mode changes and apply the\n * dark palette class to its DOM element. By default, dark mode support is disabled.\n * @protected\n * @type {boolean}\n * @default false\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n protected override enableDarkMode: boolean = true;\n\n /**\n * @description Flag to enable or disable dark mode support for the component.\n * @summary When enabled, the component will automatically detect the system's dark mode\n * preference using the media service and apply appropriate styling classes. This flag\n * controls whether the component should respond to dark mode changes and apply the\n * dark palette class to its DOM element. By default, dark mode support is disabled.\n * @protected\n * @type {boolean}\n * @default false\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n protected override isDarkMode: boolean = false;\n\n\n /**\n * @description Name identifier for the component instance.\n * @summary Provides a string identifier that can be used to name or label the component\n * instance. This name can be used for debugging purposes, logging, or to identify specific\n * component instances within a larger application structure. It serves as a human-readable\n * identifier that helps distinguish between multiple instances of the same component type.\n * @type {string}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override name!: string;\n\n /**\n * @description Parent component identifier for hierarchical component relationships.\n * @summary Specifies the identifier of the parent component in a hierarchical component structure.\n * This property establishes a parent-child relationship between components, allowing for\n * proper nesting and organization of components within a layout. It can be used to track\n * component dependencies and establish component hierarchies for rendering and event propagation.\n * @type {string | undefined}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override childOf!: string | undefined;\n\n /**\n * @description Unique identifier for the component instance.\n * @summary A unique identifier automatically generated for each component instance.\n * This UID is used for DOM element identification, component tracking, and debugging purposes.\n * By default, it generates a random 16-character value, but it can be explicitly set via input.\n * @type {string | number}\n * @default generateRandomValue(16)\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override uid?: string | number;\n\n\n /**\n * @description Data model or model name for component operations.\n * @summary The data model that this component will use for CRUD operations. This can be provided\n * as a Model instance, a model constructor, or a string representing the model's registered name.\n * When set, this property provides the component with access to the model's schema, validation rules,\n * and metadata needed for rendering and data operations.\n * @type {Model | string | undefined}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override model!: Model | string | undefined;\n\n\n /**\n * @description Primary key value of the current model instance.\n * @summary Specifies the primary key value for the current model record being displayed or\n * manipulated by the component. This identifier is used for CRUD operations that target\n * specific records, such as read, update, and delete operations. The value corresponds to\n * the field designated as the primary key in the model definition.\n * @type {EventIds}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override modelId?: EventIds;\n\n\n /**\n * @description Primary key field name for the data model.\n * @summary Specifies which field in the model should be used as the primary key.\n * This is typically used for identifying unique records in operations like update and delete.\n * If not explicitly set, it defaults to the repository's configured primary key or 'id'.\n * @type {string}\n * @default 'id'\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override pk!: string;\n\n /**\n * @description Field mapping configuration object or function.\n * @summary Defines how fields from the data model should be mapped to properties used by the component.\n * This allows for flexible data binding between the model and the component's display logic. Can be\n * provided as a static object mapping or as a function for dynamic mapping transformations.\n * @type {Record<string, string> | FunctionLike | Record<string, FunctionLike>}\n * @default {}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n mapper: Record<string, string> | FunctionLike | Record<string, FunctionLike> = {};\n\n /**\n * @description Available CRUD operations for this component instance.\n * @summary Defines which CRUD operations (Create, Read, Update, Delete) are available\n * for this component. This affects which operations can be performed on the data and\n * which operation buttons are displayed in the UI. By default, only READ operations are enabled.\n * @type {CrudOperations[]}\n * @default [OperationKeys.READ]\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n operations: CrudOperations[] = [OperationKeys.READ];\n\n\n /**\n * @description The CRUD operation type to be performed on the model.\n * @summary Specifies which operation (Create, Read, Update, Delete) this component instance\n * should perform. This determines the UI behavior, form configuration, and available actions.\n * The operation affects form validation, field availability, and the specific repository\n * method called during data submission.\n *\n * @type {OperationKeys.CREATE | OperationKeys.READ | OperationKeys.UPDATE | OperationKeys.DELETE}\n * @default OperationKeys.READ\n * @memberOf ModelPage\n */\n @Input()\n operation: OperationKeys | undefined = OperationKeys.READ;\n\n /**\n * @description Row position in a grid-based layout system.\n * @summary Specifies the row position of this component when rendered within a grid-based layout.\n * This property is used for positioning components in multi-row, multi-column layouts and helps\n * establish the component's vertical placement within the grid structure.\n * @type {number}\n * @default 1\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n row: number = 1;\n\n /**\n * @description Column position in a grid-based layout system.\n * @summary Specifies the column position of this component when rendered within a grid-based layout.\n * This property is used for positioning components in multi-row, multi-column layouts and helps\n * establish the component's horizontal placement within the grid structure.\n * @type {number}\n * @default 1\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n col: number = 1;\n\n /**\n * @description Additional CSS class names for component styling.\n * @summary Allows custom CSS classes to be added to the component's root element.\n * These classes are appended to any automatically generated classes based on other\n * component properties. Multiple classes can be provided as a space-separated string.\n * This provides a way to customize the component's appearance beyond the built-in styling options.\n * @type {string}\n * @default \"\"\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n className: string = '';\n\n\n /**\n * @description Angular change detection service for manual change detection control.\n * @summary Injected service that provides manual control over change detection cycles.\n * This is essential for ensuring that programmatic DOM changes (like setting accordion\n * attributes) are properly reflected in the component's state and trigger appropriate\n * view updates when modifications occur outside the normal Angular change detection flow.\n * @protected\n * @type {ChangeDetectorRef}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);\n\n\n /**\n * @description Media service instance for responsive design and media query management.\n * @summary Provides access to media query functionality for detecting and responding to\n * different screen sizes and device capabilities. This service enables components to adapt\n * their behavior and presentation based on viewport dimensions, orientation, and other\n * media features. It manages media query listeners and provides utilities for responsive\n * component rendering. The service is instantiated per component and should be destroyed\n * via ngOnDestroy to prevent memory leaks.\n * @protected\n * @type {NgxMediaService}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected mediaService: NgxMediaService = inject(NgxMediaService);\n\n\n /**\n * @description Angular Renderer2 service for platform-agnostic DOM manipulation.\n * @summary Injected service that provides a safe, platform-agnostic way to manipulate DOM elements.\n * This service ensures proper handling of DOM operations across different platforms and environments,\n * including server-side rendering and web workers, without direct DOM access.\n * @protected\n * @type {Renderer2}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected renderer: Renderer2 = inject(Renderer2);\n\n /**\n * @description Translation service for application internationalization.\n * @summary Injected service that provides translation capabilities for UI text.\n * Used to translate button labels, validation messages, and other text content based\n * on the current locale setting, enabling multilingual support throughout the application.\n * @protected\n * @type {TranslateService}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected translateService: TranslateService = inject(TranslateService);\n\n /**\n * @description Event emitter for custom component events.\n * @summary Emits custom events that occur within child components or the component itself.\n * This allows parent components to listen for and respond to user interactions or\n * state changes. Events are passed up the component hierarchy to enable coordinated\n * behavior across the application.\n * @type {EventEmitter<IBaseCustomEvent>}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Output()\n listenEvent: EventEmitter<IBaseCustomEvent> = new EventEmitter<IBaseCustomEvent>();\n\n /**\n * @description Angular Router instance for programmatic navigation.\n * @summary Injected Router service used for programmatic navigation between routes\n * in the application. This service enables navigation to different views and operations,\n * handles route parameters, and manages the browser's navigation history.\n * @protected\n * @type {Router}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected router: Router = inject(Router);\n\n\n /**\n * @description Current locale identifier for component internationalization.\n * @summary Specifies the locale code (e.g., 'en-US', 'pt-BR') used for translating UI text\n * and formatting data according to regional conventions. This property can be set to override\n * the default application locale for this specific component instance, enabling per-component\n * localization when needed.\n * @type {string | undefined}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override locale?: string;\n\n\n /**\n * @description Configuration for list item rendering behavior.\n * @summary Defines how list items should be rendered in the component.\n * This property holds a configuration object that specifies the tag name\n * and other properties needed to render list items correctly. The tag property\n * identifies which component should be used to render each item in a list.\n * Additional properties can be included to customize the rendering behavior.\n * @type {Record<string, FieldDefinition>}\n * @default {tag: \"\"}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override item: Record<string, unknown> = { tag: '' };\n\n\n /**\n * @description Dynamic properties configuration for runtime customization.\n * @summary Contains key-value pairs of dynamic properties that can be applied to the component\n * at runtime. This flexible configuration object allows for dynamic property assignment without\n * requiring explicit input bindings for every possible configuration option. Properties from\n * this object are parsed and applied to the component instance through the parseProps method,\n * enabling customizable component behavior based on external configuration.\n * @type {Record<string, unknown>}\n * @default {}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override props: Record<string, unknown> = {};\n\n\n /**\n * @description Base route path for component navigation.\n * @summary Defines the base route path used for navigation actions related to this component.\n * This is often used as a prefix for constructing navigation URLs when transitioning between\n * different operations or views. The route helps establish the component's position in the\n * application's routing hierarchy.\n * @type {string}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override route?: string = \"\";\n\n /**\n * @description Controls whether borders are displayed around the component.\n * @summary Boolean flag that determines if the component should be visually outlined with borders.\n * When true, borders are shown to visually separate the component from surrounding content.\n *\n * @type {boolean}\n * @default false\n */\n @Input()\n override borders: boolean = false;\n\n\n /**\n * @description Angular Location service.\n * @summary Injected service that provides direct access to the browser's URL and history.\n * Unlike the Router, Location allows for low-level manipulation of the browser's history stack\n * and URL path, such as programmatically navigating back or forward, or updating the URL without\n * triggering a route change. This is useful for scenarios where you need to interact with the\n * browser history or URL outside of Angular's routing system, such as closing modals, handling\n * popstate events, or supporting custom navigation logic.\n *\n * @private\n * @type {Location}\n */\n protected override location: Location = inject(Location);\n\n /**\n * @description Flag indicating if the component is rendered as a child of a modal dialog.\n * @summary Determines whether this component instance is being displayed within a modal\n * context. This flag affects component behavior such as navigation patterns, event handling,\n * and lifecycle management. When true, the component may use different navigation strategies\n * (e.g., closing the modal instead of browser navigation) and adjust its layout to fit modal\n * constraints. This is typically set by parent modal containers when instantiating child components.\n * @protected\n * @type {boolean}\n * @default false\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n isModalChild: boolean = false;\n\n @Input()\n protected override handlers: Record<string, UIFunctionLike> = {};\n\n @Input()\n protected override events: Record<string, UIFunctionLike> = {};\n\n /**\n * @description Constructor for NgxComponentDirective.\n * @summary Initializes the directive by setting up the component name, locale root,\n * and logger. Calls the parent LoggedClass constructor and configures localization\n * context. The component name and locale root can be optionally injected via the\n * CPTKN token, otherwise defaults are used.\n * @param {string} [componentName] - Optional component name for identification and logging\n * @param {string} [localeRoot] - Optional locale root key for internationalization\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n // eslint-disable-next-line @angular-eslint/prefer-inject\n constructor(@Inject(CPTKN) componentName?: string, @Inject(CPTKN) localeRoot?: string) {\n\t\tsuper();\n this.componentName = componentName || \"NgxComponentDirective\";\n this.localeRoot = localeRoot;\n if (!this.localeRoot && this.componentName)\n this.localeRoot = this.componentName;\n if (this.localeRoot)\n this.getLocale(this.localeRoot);\n this.uid = `${this.componentName}-${generateRandomValue(8)}`;\n\t}\n\n /**\n * @description Cleanup lifecycle hook invoked when the directive is destroyed.\n * @summary Ensures any resources allocated by the directive's media service are\n * released (DOM listeners, timers, subscriptions, etc.). Implementations should\n * keep `mediaService.destroy()` idempotent; calling it here prevents leaks when\n * components are torn down.\n * @returns {void}\n */\n ngOnDestroy(): Promise<void> | void {\n this.mediaService.destroy();\n }\n\n /**\n * @description Getter for the current locale context identifier.\n * @summary Returns the current locale identifier by calling the getLocale method.\n * This property provides convenient access to the component's active locale setting.\n * @returns {string} The current locale identifier\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n get localeContext(): string{\n\t\treturn this.getLocale();\n\t}\n\n /**\n * @description Getter for the data repository instance.\n * @summary Lazily initializes and returns the DecafRepository instance for the current model.\n * This getter ensures the repository is created only when needed and reused for subsequent\n * access. It also automatically sets the primary key field if not explicitly configured.\n * @protected\n * @returns {DecafRepository<Model>} The repository instance for the current model\n * @throws {InternalError} If repository initialization fails\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected get repository(): DecafRepository<Model> | undefined {\n try {\n if (!this._repository) {\n this._repository = getModelAndRepository(this.model as Model)?.repository;\n if (this.model && !this.pk)\n this.pk =\n (this._repository as unknown as DecafRepository<Model>).pk || 'id';\n }\n } catch (error: unknown) {\n throw new InternalError((error as Error)?.message || (error as string));\n }\n return this._repository as DecafRepository<Model>;\n }\n\n /**\n * @description Angular lifecycle hook for handling input property changes.\n * @summary Responds to changes in component input properties, specifically monitoring changes\n * to the model, locale root, and component name properties. When the model changes, it triggers\n * model initialization and locale context updates. When locale-related properties change,\n * it updates the component's locale setting accordingly.\n * @param {SimpleChanges} changes - Object containing the changed properties with their previous and current values\n * @return {void}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n async ngOnChanges(changes: SimpleChanges): Promise<void> {\n if (changes[BaseComponentProps.MODEL]) {\n const { currentValue } = changes[BaseComponentProps.MODEL];\n if (currentValue)\n this.getModel(currentValue);\n this.locale = this.localeContext;\n if (!this.initialized)\n this.initialized = true;\n }\n if (changes[UIKeys.EVENTS]) {\n const { currentValue, previousValue } = changes[UIKeys.EVENTS];\n if (currentValue && typeof currentValue !== previousValue) {\n if(!this._repository)\n this._repository = this.repository;\n for(const key in currentValue) {\n const event = currentValue[key]();\n if (event && typeof event === 'function') {\n const clazz = new event();\n this.events[key] = clazz[key].bind(this);\n if (event[key] instanceof Promise) {\n await clazz[key].bind(this)();\n } else {\n clazz[key].bind(this)();\n }\n }\n }\n }\n }\n if (changes[BaseComponentProps.LOCALE_ROOT] || changes[BaseComponentProps.COMPONENT_NAME])\n this.locale = this.localeContext;\n\n if(this.enableDarkMode)\n this.checkDarkMode();\n }\n\n /**\n * @description Translates text phrases using the translation service.\n * @summary Provides a promise-based wrapper around the translation service to translate\n * UI text based on the current locale. Supports both single phrases and arrays of phrases,\n * and accepts optional parameters for template interpolation. When a string parameter is\n * provided, it's automatically converted to an object format for the translation service.\n * @protected\n * @param {string | string[]} phrase - The translation key or array of keys to translate\n * @param {object | string} [params] - Optional parameters for interpolation in translated text\n * @return {Promise<string>} A promise that resolves to the translated text\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected async translate(phrase: string | string[], params?: object | string): Promise<string> {\n if (typeof params === Primitives.STRING)\n params = {\"0\": params};\n return await firstValueFrom(this.translateService.get(phrase, (params || {}) as object));;\n }\n\n\n protected checkDarkMode(): void {\n this.mediaService.isDarkMode().subscribe(isDark => {\n this.isDarkMode = isDark;\n this.mediaService.toggleClass(\n [this.component],\n AngularEngineKeys.DARK_PALETTE_CLASS,\n this.isDarkMode\n );\n });\n }\n\n /**\n * @description Retrieves or sets the locale context for the component.\n * @summary Gets the locale identifier from the locale context system. If a locale parameter\n * is provided, it updates the localeRoot property and resolves the new locale context.\n * If no locale is currently set, it initializes it from the localeRoot.\n * @protected\n * @param {string} [locale] - Optional locale identifier to set\n * @return {string} The current locale identifier\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected getLocale(locale?: string): string {\n if (locale || !this.locale) {\n if (locale)\n this.localeRoot = locale;\n if (this.localeRoot)\n this.locale = getLocaleContext(this.localeRoot as string)\n }\n return this.locale as string;\n }\n\n /**\n * @description Retrieves or generates the route path for the component.\n * @summary Gets the navigation route associated with this component. If no route is explicitly\n * set and a model is available, it automatically generates a route based on the model's\n * class name using the pattern `/model/{ModelName}`. Returns an empty string if neither\n * a route nor a model is available.\n * @return {string} The route path for this component\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n getRoute(): string {\n if (!this.route && this.model instanceof Model)\n this.route = `/model/${this.model?.constructor.name}`;\n return this.route || '';\n }\n\n /**\n * @description Resolves and initializes a model from various input formats.\n * @summary Accepts a model in multiple formats (string name, Model instance, or ModelConstructor)\n * and resolves it to a Model instance. When a string is provided, it looks up the model\n * by name in the Model registry. After resolution, it delegates to setModelDefinitions\n * to complete the model initialization and configuration.\n * @template M - The model type extending from Model\n * @param {string | Model | ModelConstructor<M>} model - The model to resolve and initialize\n * @return {void}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n getModel<M extends Model>(model: string | Model | ModelConstructor<M>): void {\n if (!(model instanceof Model) && typeof model === Primitives.STRING)\n model = Model.get(model as string) as ModelConstructor<M>;\n this.setModelDefinitions(this.model as Model);\n }\n\n /**\n * @description Configures component properties based on model decorators and metadata.\n * @summary Extracts rendering configuration from the model's decorators using the rendering\n * engine. This includes props, item configuration, and child component definitions. It sets\n * up the mapper for field transformations, configures the item renderer with appropriate\n * properties, and establishes the route for navigation. This method bridges the model's\n * decorator metadata with the component's runtime configuration.\n * @param {Model} model - The model instance to extract definitions from\n * @return {void}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n setModelDefinitions(model: Model): void {\n if (model instanceof Model) {\n this.getRoute();\n this.model = model;\n const engine = NgxRenderingEngine.get() as unknown as NgxRenderingEngine\n const field = engine.getDecorators(this.model as Model, {});\n const { props, item, children } = field;\n this.props = Object.assign(props || {}, { children: children || [] }, this.props);\n if (item?.props?.['mapper'])\n this.mapper = item?.props!['mapper'] || {};\n this.item = {\n tag: item?.tag || '',\n ...item?.props,\n ...(this.mapper ? { mapper: this.mapper } : {}),\n ...{ route: item?.props?.['route'] || this.route },\n } as KeyValue;\n }\n }\n\n /**\n * @description Parses and applies properties from the props object to the component instance.\n * @summary This method iterates through the properties of the provided instance object\n * and applies any matching properties from the component's props configuration to the\n * component instance. This allows for dynamic property assignment based on configuration\n * stored in the props object, enabling flexible component customization without requiring\n * explicit property binding for every possible configuration option.\n * The method performs a safe property assignment by checking if each key from the instance\n * exists in the props object before applying it. This prevents accidental property\n * overwriting and ensures only intended properties are modified.\n * @param {KeyValue} instance - The component instance object to process\n * @param {string[]} [skip=[]] - Array of property names to skip during parsing\n * @return {void}\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant D as NgxComponentDirective\n * participant P as Props Object\n *\n * C->>D: parseProps(instance, skip)\n * D->>D: Get Object.keys(instance)\n * loop For each key in instance\n * D->>D: Check if key in skip array\n * alt Key not in skip\n * D->>P: Check if key exists in this.props\n * alt Key exists in props\n * D->>D: Set this[key] = this.props[key]\n * D->>P: delete this.props[key]\n * else Key not in props\n * Note over D: Skip this key\n * end\n * end\n * end\n * @protected\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected parseProps(instance: KeyValue, skip: string[] = []): void {\n Object.keys(instance).forEach((key) => {\n if (Object.keys(this.props).includes(key) && !skip.includes(key)) {\n (this as KeyValue)[key] = this.props[key];\n delete this.props[key];\n }\n });\n }\n\n\n /**\n * @description Tracks items in ngFor loops for optimal change detection performance.\n * @summary Provides a tracking function for Angular's *ngFor directive to optimize rendering\n * performance. This method generates unique identifiers for list items based on their index\n * and content, allowing Angular to efficiently track changes and minimize DOM manipulations\n * during list updates. The tracking function is essential for maintaining component state\n * and preventing unnecessary re-rendering of unchanged items.\n * @protected\n * @param {number} index - The index of the item in the list\n * @param {KeyValue | string | number} item - The item data to track\n * @return {string | number} A unique identifier for the item\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected trackItemFn(\n index: number,\n item: KeyValue | string | number\n ): string | number {\n return `${index}-${item}`;\n }\n\n /**\n * @description Handles custom events from child components or DOM elements.\n * @summary Processes custom events by extracting event handlers and delegating to appropriate\n * handler classes. Supports both CustomEvent format with detail property and direct event\n * objects. If specific handlers are defined in the event, it instantiates the handler class\n * and invokes its handle method. If no handler is found or defined, the event is emitted\n * up the component hierarchy via the listenEvent output.\n * @param {IBaseCustomEvent | ICrudFormEvent | CustomEvent} event - The event to handle\n * @return {Promise<void>} A promise that resolves when event handling is complete\n * @mermaid\n * sequenceDiagram\n * participant C as Child Component\n * participant D as NgxComponentDirective\n * participant H as Event Handler\n * participant P as Parent Component\n *\n * C->>D: handleEvent(event)\n * alt Event is CustomEvent\n * D->>D: Extract event.detail\n * end\n * D->>D: Get event name and handlers\n * alt Handlers defined\n * alt Handler exists for event\n * D->>H: new Handler(router)\n * D->>H: handle(event)\n * H-->>D: return result\n * else No handler found\n * D->>D: log.debug(\"No handler found\")\n * end\n * else No handlers\n * D->>P: listenEvent.emit(event)\n * end\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n\tasync handleEvent(event: IBaseCustomEvent | ICrudFormEvent | CustomEvent): Promise<void> {\n let name = \"\";\n const log = this.log.for(this.handleEvent);\n if (event instanceof CustomEvent) {\n if (!event.detail)\n return log.debug(`No handler for event ${name}`);\n name = event.detail?.name;\n event = event.detail;\n }\n const handlers = (event as ICrudFormEvent)?.['handlers'] as Record<string, NgxEventHandler<unknown>> | undefined;\n name = name || (event as IBaseCustomEvent)?.['name'];\n if (handlers && Object.keys(handlers || {})?.length) {\n if (!handlers[name])\n return log.debug(`No handler found for event ${name}`);\n try {\n const clazz = new (handlers as KeyValue)[name](this.router);\n const result = clazz.handle(event);\n return (result instanceof Promise) ?\n await result : result;\n } catch (e: unknown) {\n log.error(`Failed to handle ${name} event`, e as Error)\n }\n }\n this.listenEvent.emit(event as IBaseCustomEvent | ICrudFormEvent);\n\t}\n\n /**\n * @description Determines if a specific operation is allowed in the current context.\n * @summary This method checks if an operation is included in the list of available\n * CRUD operations and if it's not the current operation (unless the current operation\n * is CREATE). This is used to enable/disable or show/hide operation buttons in the UI.\n * Returns false if the operations array is undefined or the operation is not in the list.\n * @param {string} operation - The operation to check\n * @return {boolean} True if the operation is allowed, false otherwise\n * @mermaid\n * sequenceDiagram\n * participant D as NgxComponentDirective\n * participant U as UI\n *\n * U->>D: isAllowed(operation)\n * alt operations is undefined\n * D-->>U: Return false\n * else\n * D->>D: Check if operation is in operations\n * D->>D: Check if operation is not current operation\n * D-->>U: Return result\n * end\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n isAllowed(operation: string): boolean {\n if (!this.operations)\n return false;\n return this.operations.includes(operation as CrudOperations) && (this.operation !== OperationKeys.CREATE && ((this.operation || \"\").toLowerCase() !== operation || !this.operation));\n }\n\n\n /**\n * @description Navigates to a different operation for the current model.\n * @summary This method constructs a navigation URL based on the component's base route,\n * the requested operation, and optionally a model ID. It then uses the Angular router\n * service to navigate to the constructed URL. This is typically used when switching\n * between different CRUD operations (create, read, update, delete) on a model.\n * The URL format is: {route}/{operation}/{id?}\n * @param {string} operation - The operation to navigate to (e.g., 'create', 'read', 'update', 'delete')\n * @param {string} [id] - Optional model ID to include in the navigation URL\n * @return {Promise<boolean>} A promise that resolves to true if navigation was successful\n * @mermaid\n * sequenceDiagram\n * participant U as UI\n * participant D as NgxComponentDirective\n * participant R as Router\n *\n * U->>D: Click operation button\n * D->>D: changeOperation(operation, id)\n * D->>D: Construct navigation URL\n * Note over D: URL: {route}/{operation}/{id?}\n * D->>R: navigateByUrl(page)\n * R->>R: Navigate to new route\n * R-->>D: Return navigation result\n * D-->>U: Display new operation view\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n async changeOperation(operation: string, id?: string): Promise<boolean> {\n let page = `${this.route}/${operation}/`.replace('//', '/');\n if (!id)\n id = this.modelId as string;\n if (this.modelId)\n page = `${page}${this.modelId || id}`;\n return this.router.navigateByUrl(page);\n }\n}\n","import {\n Directive,\n ElementRef,\n EnvironmentInjector,\n EventEmitter,\n inject,\n Input,\n OnChanges,\n OnDestroy,\n TemplateRef,\n Type,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n IRenderedModel,\n AngularDynamicOutput,\n IBaseCustomEvent\n} from './interfaces';\nimport { FormParent, KeyValue } from './types';\nimport { NgxRenderingEngine } from './NgxRenderingEngine';\n\nimport { NgxComponentDirective } from './NgxComponentDirective';\n\n@Directive()\nexport class NgxRenderableComponentDirective extends NgxComponentDirective\n implements OnChanges, OnDestroy, IRenderedModel {\n\n /**\n * @description Injector used for dependency injection in the dynamic component.\n * @summary This injector is used when creating the dynamic component to provide it with\n * access to the application's dependency injection system. It ensures that the dynamically\n * created component can access the same services and dependencies as statically created\n * components.\n *\n * @type {EnvironmentInjector}\n * @memberOf NgxRenderableComponentDirective\n */\n protected injector: EnvironmentInjector = inject(EnvironmentInjector);\n\n\n /**\n * @description Reference to the container where the dynamic component will be rendered.\n * @summary This ViewContainerRef provides the container where the dynamically created\n * component will be inserted into the DOM. It's marked as static to ensure it's available\n * during the ngOnInit lifecycle hook when the component is created.\n *\n * @type {ViewContainerRef}\n * @memberOf NgxRenderableComponentDirective\n */\n\n @ViewChild('componentOuter', { static: true, read: ViewContainerRef })\n protected vcr!: ViewContainerRef;\n\n @ViewChild('componentInner', { read: TemplateRef, static: true })\n inner?: TemplateRef<unknown>;\n\n /**\n * @description Global properties to pass to the rendered component.\n * @summary This input property allows passing a set of properties to the dynamically\n * rendered component. These properties will be mapped to the component's inputs if they\n * match. Properties that don't match any input on the target component will be filtered out\n * with a warning.\n *\n * @type {Record<string, unknown>}\n * @default {}\n * @memberOf NgxComponentDirective\n */\n @Input()\n globals: Record<string, unknown> = {};\n\n /**\n * @description Repository model for data operations.\n * @summary The data model repository that this component will use for CRUD operations.\n * This provides a connection to the data layer for retrieving and manipulating data.\n *\n * @type {Model| undefined}\n * @memberOf NgxComponentDirective\n */\n @Input()\n parentForm!: FormParent | ElementRef<unknown> | undefined;\n\n\n @Input()\n projectable: boolean = true;\n\n\n @Input()\n rendererId?: string;\n\n protected output?: AngularDynamicOutput;\n\n protected instance!: KeyValue | undefined;\n\n protected readonly JSON = JSON;\n\n // @Output()\n // listenEvent: EventEmitter<IBaseCustomEvent> =\n // new EventEmitter<IBaseCustomEvent>();\n\n /**\n * @description Cleans up resources when the component is destroyed.\n * @summary Performs cleanup operations when the component is being destroyed by Angular.\n * This includes unsubscribing from all event emitters of the dynamic component and\n * destroying the rendering engine instance to prevent memory leaks.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant C as ComponentRendererComponent\n * participant R as NgxRenderingEngine\n *\n * A->>C: ngOnDestroy()\n * alt component exists\n * C->>C: unsubscribeEvents()\n * C->>R: destroy()\n * end\n *\n * @return {Promise<void>} A promise that resolves when cleanup is complete\n * @memberOf NgxComponentDirective\n */\n override async ngOnDestroy(): Promise<void> {\n super.ngOnDestroy();\n if (this.instance) {\n this.unsubscribeEvents();\n await NgxRenderingEngine.destroy();\n }\n this.output = undefined;\n }\n\n\n /**\n * @description Subscribes to events emitted by the dynamic component.\n * @summary This method sets up subscriptions to all EventEmitter properties of the\n * dynamically created component. When an event is emitted by the dynamic component,\n * it is captured and re-emitted through the listenEvent output property with additional\n * metadata about the event source.\n *\n * @mermaid\n * sequenceDiagram\n * participant C as ComponentRendererComponent\n * participant D as Dynamic Component\n * participant P as Parent Component\n *\n * C->>C: subscribeEvents()\n * C->>D: Get instance properties\n * loop For each property\n * C->>C: Check if property is EventEmitter\n * alt is EventEmitter\n * C->>D: Subscribe to event\n * D-->>C: Event emitted\n * C->>P: Re-emit event with metadata\n * end\n * end\n *\n * @private\n * @return {void}\n * @memberOf NgxComponentDirective\n */\n protected async subscribeEvents(component?: Type<unknown>): Promise<void> {\n if(!component)\n component = this?.output?.component;\n if(!this.instance && component)\n this.instance = component;\n if (this.instance && component) {\n const componentKeys = Object.keys(this.instance);\n for (const key of componentKeys) {\n const value = this.instance[key];\n if (value instanceof EventEmitter)\n (this.instance as KeyValue)[key].subscribe(async (event: Partial<IBaseCustomEvent>) => {\n await this.handleEvent({\n component: component.name || '',\n name: key,\n ...event,\n } as IBaseCustomEvent);\n });\n }\n }\n }\n\n\n /**\n * @description Unsubscribes from all events of the dynamic component.\n * @summary This method cleans up event subscriptions when the component is being destroyed.\n * It iterates through all properties of the dynamic component instance and unsubscribes\n * from any EventEmitter properties to prevent memory leaks and unexpected behavior after\n * the component is destroyed.\n *\n * @mermaid\n * sequenceDiagram\n * participant C as ComponentRendererComponent\n * participant D as Dynamic Component\n *\n * C->>C: unsubscribeEvents()\n * C->>D: Get instance properties\n * loop For each property\n * C->>C: Check if property is EventEmitter\n * alt is EventEmitter\n * C->>D: Unsubscribe from event\n * end\n * end\n *\n * @private\n * @return {void}\n * @memberOf NgxComponentDirective\n */\n protected unsubscribeEvents(): void {\n if (this.instance) {\n const componentKeys = Object.keys(this.instance);\n for (const key of componentKeys) {\n const value = this.instance[key];\n if (value instanceof EventEmitter)\n this.instance[key].unsubscribe();\n }\n }\n }\n}\n","import {\n Component,\n ComponentMirror,\n Injector,\n Input,\n OnDestroy,\n OnInit,\n reflectComponentType,\n TemplateRef,\n Type\n} from '@angular/core';\n/**\n * @module module:lib/components/component-renderer/component-renderer.component\n * @description Component renderer module.\n * @summary Provides `ComponentRendererComponent` which renders dynamic child\n * components based on configuration or data. Useful for rendering custom\n * fields, nested components or templated content at runtime.\n *\n * @link {@link ComponentRendererComponent}\n */\nimport { NgComponentOutlet } from '@angular/common';\n\nimport { NgxRenderingEngine } from '../../engine/NgxRenderingEngine';\nimport { KeyValue } from '../../engine/types';\nimport { AngularEngineKeys, BaseComponentProps } from '../../engine/constants';\nimport { NgxRenderableComponentDirective } from '../../engine/NgxRenderableComponentDirective';\n\n/**\n * @description Dynamic component renderer for Decaf Angular applications.\n * @summary This component provides a flexible way to dynamically render Angular components\n * at runtime based on a tag name. It handles the creation, property binding, and event\n * subscription for dynamically loaded components. This is particularly useful for\n * building configurable UIs where components need to be determined at runtime.\n *\n * @component {ComponentRendererComponent}\n * @example\n * <ngx-decaf-component-renderer\n * [tag]=\"tag\"\n * [globals]=\"globals\"\n * (listenEvent)=\"listenEvent($event)\">\n * </ngx-decaf-component-renderer>\n *\n * @mermaid\n * classDiagram\n * class ComponentRendererComponent {\n * +ViewContainerRef vcr\n * +string tag\n * +Record~string, unknown~ globals\n * +EnvironmentInjector injector\n * +ComponentRef~unknown~ component\n * +EventEmitter~IBaseCustomEvent~ listenEvent\n * +ngOnInit()\n * +ngOnDestroy()\n * +ngOnChanges(changes)\n * -createComponent(tag, globals)\n * -subscribeEvents()\n * -unsubscribeEvents()\n * }\n * ComponentRendererComponent --|> OnInit\n * ComponentRendererComponent --|> OnChanges\n * ComponentRendererComponent --|> OnDestroy\n *\n * @implements {OnInit}\n * @implements {OnChanges}\n * @implements {OnDestroy}\n */\n@Component({\n selector: 'ngx-decaf-component-renderer',\n templateUrl: './component-renderer.component.html',\n styleUrls: ['./component-renderer.component.scss'],\n imports: [NgComponentOutlet],\n standalone: true,\n host: {'[attr.id]': 'uid'},\n})\nexport class ComponentRendererComponent extends NgxRenderableComponentDirective implements OnInit, OnDestroy {\n\n /**\n * @description The tag name of the component to be dynamically rendered.\n * @summary This input property specifies which component should be rendered by providing\n * its registered tag name. The tag must correspond to a component that has been registered\n * with the NgxRenderingEngine. This is a required input as it determines which component\n * to create.\n *\n * @type {string}\n * @required\n * @memberOf ComponentRendererComponent\n */\n @Input({ required: true })\n tag!: string;\n\n @Input()\n children: KeyValue[] = [];\n\n @Input()\n override projectable: boolean = true;\n\n @Input()\n parent: undefined | KeyValue = undefined;\n\n\n /**\n * @description Initializes the component after Angular first displays the data-bound properties.\n * @summary Sets up the component by creating the dynamic component specified by the tag input.\n * This method is called once when the component is initialized and triggers the dynamic\n * component creation process with the provided tag name and global properties.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant C as ComponentRendererComponent\n * participant R as NgxRenderingEngine\n *\n * A->>C: ngOnInit()\n * C->>C: createComponent(tag, globals)\n * C->>R: components(tag)\n * R-->>C: Return component constructor\n * C->>C: Process component inputs\n * C->>C: Create component instance\n * C->>C: subscribeEvents()\n *\n * @return {void}\n * @memberOf ComponentRendererComponent\n */\n ngOnInit(): void {\n if (!this.parent) {\n this.createComponent(this.tag, this.globals);\n } else {\n this.createParentComponent();\n }\n }\n\n /**\n * @description Creates and renders a dynamic component.\n * @summary This method handles the creation of a dynamic component based on the provided tag.\n * It retrieves the component constructor from the rendering engine, processes its inputs,\n * filters out unmapped properties, creates the component instance, and sets up event subscriptions.\n *\n * @param {string} tag - The tag name of the component to create\n * @param {KeyValue} globals - Global properties to pass to the component\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant C as ComponentRendererComponent\n * participant R as NgxRenderingEngine\n * participant V as ViewContainerRef\n *\n * C->>R: components(tag)\n * R-->>C: Return component constructor\n * C->>C: reflectComponentType(component)\n * C->>C: Process input properties\n * C->>C: Filter unmapped properties\n * C->>V: clear()\n * C->>R: createComponent(component, props, metadata, vcr, injector, [])\n * R-->>C: Return component reference\n * C->>C: subscribeEvents()\n *\n * @private\n * @memberOf ComponentRendererComponent\n */\n private createComponent(tag: string, globals: KeyValue = {}): void {\n const component = NgxRenderingEngine.components(tag)\n ?.constructor as Type<unknown>;\n const metadata = reflectComponentType(component);\n const componentInputs = (metadata as ComponentMirror<unknown>).inputs;\n const props = globals?.['item'] || globals?.['props'] || {};\n if (props?.['tag'])\n delete props['tag'];\n if (props?.[AngularEngineKeys.CHILDREN] && !this.children.length)\n this.children = props[AngularEngineKeys.CHILDREN] as KeyValue[];\n props[AngularEngineKeys.CHILDREN] = this.children || [];\n const inputKeys = Object.keys(props);\n const unmappedKeys: string[] = [];\n\n for (const input of inputKeys) {\n if (!inputKeys.length) break;\n const prop = componentInputs.find(\n (item: { propName: string }) => item.propName === input,\n );\n if (!prop) {\n delete props[input];\n unmappedKeys.push(input);\n }\n }\n\n function hasProperty(key: string): boolean {\n return Object.values(componentInputs).some(({propName}) => propName === key);\n }\n\n const hasChildrenInput = hasProperty(AngularEngineKeys.CHILDREN);\n if (!this.projectable && hasChildrenInput)\n props[AngularEngineKeys.CHILDREN] = this.children;\n\n const hasRootForm = hasProperty(BaseComponentProps.PARENT_FORM);\n if (hasRootForm && this.parentForm)\n props[BaseComponentProps.PARENT_FORM] = this.parentForm;\n\n props['className'] = (props['className'] ?\n props['className'] + ' ' + this.className : this.className || \"\");\n\n this.vcr.clear();\n // const projectable = (this.children?.length && this.projectable);\n // const template = projectable ? this.vcr.createEmbeddedView(this.inner as TemplateRef<unknown>, this.injector).rootNodes : [];\n this.instance = NgxRenderingEngine.createComponent(\n component,\n props,\n this.injector as Injector,\n metadata as ComponentMirror<unknown>,\n this.vcr,\n [],\n );\n this.subscribeEvents(component);\n }\n\n private createParentComponent() {\n const { component, inputs } = this.parent as KeyValue;\n const metadata = reflectComponentType(component) as ComponentMirror<unknown>;\n const template = this.projectable ? this.vcr.createEmbeddedView(this.inner as TemplateRef<unknown>, this.injector).rootNodes : [];\n this.instance = NgxRenderingEngine.createComponent(\n component,\n inputs,\n this.injector,\n metadata,\n this.vcr,\n template,\n );\n this.subscribeEvents(component);\n }\n}\n","<!-- Keep to avoid id conflicts -->\n\n<ng-template #componentOuter></ng-template>\n\n<ng-template #componentInner>\n @if (parent?.children?.length) {\n @for(child of parent.children; track child) {\n @if (!child.children?.length) {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n } @else {\n <ngx-decaf-component-renderer [parent]=\"child\"> </ngx-decaf-component-renderer>\n }\n }\n }\n @if (projectable) {\n @if (children?.length) {\n @for(child of children; track child) {\n @if (child.children?.length) {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n } @else {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n }\n }\n\n</ng-template>\n\n","/**\n * @module lib/engine/NgxFormFieldDirective\n * @description Base directive for CRUD form fields in Decaf Angular applications.\n * @summary Provides the NgxFormFieldDirective abstract class that implements ControlValueAccessor\n * and FieldProperties to enable form field integration with Angular's reactive forms system.\n * This directive handles form control lifecycle, validation, multi-entry forms, and CRUD operations.\n */\nimport { CrudOperationKeys, FieldProperties, RenderingError } from '@decaf-ts/ui-decorators';\nimport { FormParent, KeyValue, PossibleInputTypes } from './types';\nimport { CrudOperations, InternalError, OperationKeys } from '@decaf-ts/db-decorators';\nimport { ControlValueAccessor, FormArray, FormControl, FormGroup } from '@angular/forms';\nimport { Directive, Inject, Input, OnChanges, SimpleChanges } from '@angular/core';\nimport { NgxFormService } from '../services/NgxFormService';\nimport { sf } from '@decaf-ts/decorator-validation';\nimport { ComponentEventNames } from './constants';\nimport { FunctionLike } from './types';\nimport { NgxComponentDirective } from './NgxComponentDirective';\nimport { CPTKN } from '../for-angular-common.module';\n\n/**\n * @description Abstract base directive for CRUD form fields in Angular applications.\n * @summary Provides the foundation for all form field components in Decaf applications by implementing\n * Angular's ControlValueAccessor interface and FieldProperties for validation. This directive manages\n * form control integration, validation state, multi-entry forms (FormArrays), and CRUD operation context.\n * It handles form group lifecycle, error messaging, change detection, and parent-child form relationships.\n * Extend this class to create custom form field components that seamlessly integrate with Angular's\n * reactive forms and Decaf's validation system.\n * @class NgxFormFieldDirective\n * @extends {NgxComponentDirective}\n * @implements {ControlValueAccessor}\n * @implements {FieldProperties}\n * @example\n * ```typescript\n * @Component({\n * selector: 'app-text-field',\n * templateUrl: './text-field.component.html',\n * providers: [{\n * provide: NG_VALUE_ACCESSOR,\n * useExisting: forwardRef(() => TextFieldComponent),\n * multi: true\n * }]\n * })\n * export class TextFieldComponent extends NgxFormFieldDirective {\n * constructor() {\n * super();\n * }\n * }\n * ```\n */\n@Directive()\nexport abstract class NgxFormFieldDirective extends NgxComponentDirective implements OnChanges, ControlValueAccessor, FieldProperties {\n\n /**\n * @description Index of the currently active form group in a form array.\n * @summary When working with multiple form groups (form arrays), this indicates\n * which form group is currently active or being edited. This is used to manage\n * focus and data binding in multi-entry scenarios.\n * @type {number}\n * @default 0\n * @public\n */\n @Input()\n activeFormGroupIndex: number = 0;\n\n\n @Input({ required: true })\n override operation: CrudOperations = OperationKeys.CREATE;\n\n /**\n * @description Parent form container for this field.\n * @summary Reference to the parent FormGroup or FormArray that contains this field.\n * When this field is part of a multi-entry structure, this contains the FormArray\n * with all form groups. This enables management of multiple instances of the same\n * field structure within a single form.\n * @type {FormParent}\n * @public\n */\n @Input()\n parentForm!: FormParent;\n\n /**\n * @description Field mapping configuration for options.\n * @summary Defines how fields from the data model should be mapped to properties used by the component.\n * This allows for flexible data binding between the model and the component's display logic.\n * Can be either a key-value mapping object or a function that performs the mapping.\n * @type {KeyValue | FunctionLike}\n * @public\n */\n @Input()\n optionsMapper: KeyValue | FunctionLike = {};\n\n /**\n * @description Angular FormGroup instance for the field.\n * @summary The FormGroup that contains this field's FormControl. Used for managing\n * the field's validation state and value within the reactive forms structure.\n * @type {FormGroup | undefined}\n * @public\n */\n formGroup!: FormGroup | undefined;\n\n /**\n * @description Angular FormControl instance for this field.\n * @summary The FormControl that manages this field's value, validation state, and user interactions.\n * @type {FormControl}\n * @public\n */\n formControl!: FormControl;\n\n /**\n * @description Dot-separated path to this field in the form structure.\n * @summary Used to locate this field within nested form structures.\n * @type {string}\n * @public\n */\n path!: string;\n\n /**\n * @description The input type of this field.\n * @summary Determines the HTML input type or component type to render.\n * @type {PossibleInputTypes}\n * @public\n */\n type!: PossibleInputTypes ;\n\n /**\n * @description Whether the field is disabled.\n * @summary When true, the field cannot be edited by the user.\n * @type {boolean}\n * @public\n */\n disabled?: boolean;\n\n /**\n * @description Page number for multi-page forms.\n * @summary Indicates which page this field belongs to in a multi-page form structure.\n * @type {number}\n * @public\n */\n page!: number;\n\n // Validation properties\n\n /**\n * @description Date/time format string for parsing and display.\n * @type {string}\n * @public\n */\n format?: string;\n\n /**\n * @description Controls field visibility based on CRUD operations.\n * @summary Can be a boolean or an array of operation keys where the field should be hidden.\n * @type {boolean | CrudOperationKeys[]}\n * @public\n */\n hidden?: boolean | CrudOperationKeys[];\n\n /**\n * @description Maximum value or date allowed.\n * @type {number | Date}\n * @public\n */\n max?: number | Date;\n\n /**\n * @description Maximum length for text input.\n * @type {number}\n * @public\n */\n maxlength?: number;\n\n /**\n * @description Minimum value or date allowed.\n * @type {number | Date}\n * @public\n */\n min?: number | Date;\n\n /**\n * @description Minimum length for text input.\n * @type {number}\n * @public\n */\n minlength?: number;\n\n /**\n * @description Regex pattern for validation.\n * @type {string | undefined}\n * @public\n */\n pattern?: string | undefined;\n\n /**\n * @description Whether the field is read-only.\n * @type {boolean}\n * @public\n */\n readonly?: boolean;\n\n /**\n * @description Whether the field is required.\n * @type {boolean}\n * @public\n */\n required?: boolean;\n\n /**\n * @description Step value for numeric inputs.\n * @type {number}\n * @public\n */\n step?: number;\n\n /**\n * @description Field name that this field's value must equal.\n * @type {string}\n * @public\n */\n equals?: string;\n\n /**\n * @description Field name that this field's value must differ from.\n * @type {string}\n * @public\n */\n different?: string;\n\n /**\n * @description Field name that this field's value must be less than.\n * @type {string}\n * @public\n */\n lessThan?: string;\n\n /**\n * @description Field name that this field's value must be less than or equal to.\n * @type {string}\n * @public\n */\n lessThanOrEqual?: string;\n\n /**\n * @description Field name that this field's value must be greater than.\n * @type {string}\n * @public\n */\n greaterThan?: string;\n\n /**\n * @description Field name that this field's value must be greater than or equal to.\n * @type {string}\n * @public\n */\n greaterThanOrEqual?: string;\n\n /**\n * @description Current value of the field.\n * @summary Can be a string, number, date, or array of strings for multi-select fields.\n * @type {string | number | Date | string[]}\n * @public\n */\n value!: string | number | Date | string[];\n\n /**\n * @description Whether the field supports multiple values.\n * @summary When true, the field is rendered as part of a FormArray structure.\n * @type {boolean}\n * @public\n */\n multiple!: boolean;\n\n /**\n * @description Flag tracking if validation error event has been dispatched.\n * @summary Prevents duplicate validation error events from being dispatched.\n * @type {boolean}\n * @private\n */\n private validationErrorEventDispatched: boolean = false;\n\n /**\n * @description Reference to the parent HTML element.\n * @summary Used for DOM manipulation and event handling.\n * @type {HTMLElement}\n * @protected\n */\n protected parent?: HTMLElement;\n\n // eslint-disable-next-line @angular-eslint/prefer-inject\n constructor(@Inject(CPTKN) componentName: string = \"ComponentCrudField\") {\n super(componentName);\n }\n\n\n /**\n * @description Gets the currently active form group based on context.\n * @summary Returns the appropriate FormGroup based on whether this field supports\n * multiple values. For single-value fields, returns the main form group.\n * For multi-value fields, returns the form group at the active index from the parent FormArray.\n * If no formGroup is set, returns the parent of the formControl.\n * @return {FormGroup} The currently active FormGroup for this field\n * @public\n */\n get activeFormGroup(): FormGroup {\n if (!this.formGroup)\n return this.formControl.parent as FormGroup;\n\n if (this.multiple) {\n if (this.formGroup instanceof FormArray)\n return this.formGroup.at(this.activeFormGroupIndex) as FormGroup;\n return this.formGroup;\n }\n\n return this.formGroup as FormGroup;\n }\n\n /**\n * @description String formatting utility function.\n * @summary Provides access to the sf (string format) function for formatting error messages\n * and other string templates. Used primarily for localizing and parameterizing validation messages.\n * @type {function(string, ...string): string}\n * @public\n */\n sf = sf;\n\n /**\n * @description Callback function invoked when the field value changes.\n * @summary Function registered by Angular's forms system through registerOnChange.\n * Called automatically when the field's value is updated to notify the form of the change.\n * @type {function(): unknown}\n * @public\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: () => unknown = () => {};\n\n /**\n * @description Callback function invoked when the field is touched.\n * @summary Function registered by Angular's forms system through registerOnTouched.\n * Called when the field is blurred or otherwise marked as touched.\n * @type {function(): unknown}\n * @public\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onTouch: () => unknown = () => {};\n\n /**\n * @description Writes a value to the form field.\n * @summary Part of Angular's ControlValueAccessor interface. Sets the field's value\n * when the form programmatically updates it. This is called by Angular forms when\n * the model value changes.\n * @param {string} obj - The value to be set\n * @return {void}\n * @public\n */\n writeValue(obj: string): void {\n this.value = obj;\n }\n\n /**\n * @description Registers the onChange callback function.\n * @summary Part of Angular's ControlValueAccessor interface. Stores the function\n * that Angular forms provides to be called when the field value changes.\n * @param {function(): unknown} fn - The function to be called on change\n * @return {void}\n * @public\n */\n registerOnChange(fn: () => unknown): void {\n this.onChange = fn;\n }\n\n /**\n * @description Registers the onTouched callback function.\n * @summary Part of Angular's ControlValueAccessor interface. Stores the function\n * that Angular forms provides to be called when the field is touched/blurred.\n * @param {function(): unknown} fn - The function to be called on touch\n * @return {void}\n * @public\n */\n registerOnTouched(fn: () => unknown): void {\n this.onTouch = fn;\n }\n\n /**\n * @description Sets the disabled state of the field.\n * @summary Part of Angular's ControlValueAccessor interface. Called by Angular forms\n * when the disabled state of the control changes.\n * @param {boolean} isDisabled - Whether the field should be disabled\n * @return {void}\n * @public\n */\n setDisabledState?(isDisabled: boolean): void {\n this.disabled = isDisabled;\n }\n\n /**\n * @description Performs setup after the view has been initialized.\n * @summary Retrieves and returns the parent HTML element based on the current CRUD operation.\n * For READ and DELETE operations, returns the immediate parent element. For CREATE and UPDATE\n * operations, finds the parent div element and registers it with the form service.\n * @return {HTMLElement} The parent element of the field\n * @throws {RenderingError} If unable to retrieve parent form element for CREATE/UPDATE operations\n * @throws {InternalError} If the operation is invalid\n * @public\n */\n afterViewInit(): HTMLElement {\n this.checkDarkMode();\n let parent: HTMLElement;\n if (this.component?.nativeElement)\n this.isModalChild = this.component.nativeElement.closest('ion-modal') ? true : false;\n switch (this.operation) {\n case OperationKeys.READ:\n case OperationKeys.DELETE:\n return this.component.nativeElement.parentElement;\n case OperationKeys.CREATE:\n case OperationKeys.UPDATE:\n try {\n parent = NgxFormService.getParentEl(this.component.nativeElement, 'div');\n } catch (e: unknown) {\n throw new RenderingError(`Unable to retrieve parent form element for the ${this.operation}: ${e instanceof Error ? e.message : e}`);\n }\n // NgxFormService.register(parent.id, this.formGroup, this as AngularFieldDefinition);\n return parent;\n default:\n throw new InternalError(`Invalid operation: ${this.operation}`);\n }\n }\n\n /**\n * @description Angular lifecycle hook for detecting input property changes.\n * @summary Overrides the parent ngOnChanges to handle changes to activeFormGroupIndex and value.\n * When activeFormGroupIndex changes in a multiple field scenario, updates the active form group\n * and form control. When value changes, updates the form control value. Delegates to parent\n * implementation for initial change detection.\n * @param {SimpleChanges} changes - Object containing the changed properties\n * @return {void}\n * @public\n */\n override async ngOnChanges(changes: SimpleChanges): Promise<void> {\n if (!this.initialized)\n await super.ngOnChanges(changes);\n if (changes['activeFormGroupIndex'] && this.multiple &&\n !changes['activeFormGroupIndex'].isFirstChange() && changes['activeFormGroupIndex'].currentValue !== this.activeFormGroupIndex) {\n\n this.activeFormGroupIndex = changes['activeFormGroupIndex'].currentValue;\n this.formGroup = this.activeFormGroup;\n this.formControl = this.formGroup.get(this.name) as FormControl;\n }\n if (changes['value'] && !changes['value'].isFirstChange()\n && (changes['value'].currentValue !== undefined && changes['value'].currentValue !== this.value))\n this.setValue(changes['value'].currentValue);\n }\n\n /**\n * @description Cleanup logic when the component is destroyed.\n * @summary Unregisters the form group from the form service to prevent memory leaks\n * and clean up form references.\n * @return {void}\n * @public\n */\n onDestroy(): void {\n if (this.formGroup)\n NgxFormService.unregister(this.formGroup);\n }\n\n /**\n * @description Sets the value of the form control.\n * @summary Updates the form control's value and triggers validation. This is used\n * when the value needs to be programmatically updated from outside the form control.\n * @param {unknown} value - The value to set\n * @return {void}\n * @public\n */\n setValue(value: unknown): void {\n this.formControl.setValue(value);\n this.formControl.updateValueAndValidity();\n }\n\n handleModalChildChanges() {\n if (this.isModalChild)\n this.changeDetectorRef.detectChanges();\n }\n\n /**\n * @description Retrieves validation error messages for the field.\n * @summary Checks the form control for validation errors and returns formatted error messages.\n * If errors exist, dispatches a validation error event to parent accordion components.\n * Error messages are translated and formatted with relevant field properties.\n * @param {HTMLElement} parent - The parent HTML element used to find accordion components\n * @return {string | void} Formatted error message string, or void if no errors\n * @public\n */\n getErrors(parent: HTMLElement): string | void {\n const formControl = this.formControl;\n if (formControl) {\n const accordionComponent = parent.closest('ngx-decaf-fieldset')?.querySelector('ion-accordion-group');\n if ((!formControl.pristine || formControl.touched) && !formControl.valid) {\n const errors: Record<string, string>[] = Object.keys(formControl.errors ?? {}).map(key => ({\n key: key,\n message: key,\n }));\n if (errors.length) {\n if (accordionComponent && !this.validationErrorEventDispatched) {\n const validationErrorEvent = new CustomEvent(ComponentEventNames.VALIDATION_ERROR, {\n detail: {fieldName: this.name, hasErrors: true},\n bubbles: true\n });\n accordionComponent.dispatchEvent(validationErrorEvent);\n this.validationErrorEventDispatched = true;\n }\n }\n for(const error of errors) {\n const instance = this as KeyValue;\n return `* ${ this.translateService.instant(`errors.${error?.['message']}`, {\"0\": `${instance[error?.['key']] ?? \"\"}`})}`;\n }\n\n }\n }\n }\n}\n","import { apply, metadata } from '@decaf-ts/decoration';\nimport { NgxRenderingEngine } from './NgxRenderingEngine';\nimport { AngularEngineKeys } from './constants';\nimport { Constructor, Metadata } from '@decaf-ts/decoration';\nimport { InternalError } from '@decaf-ts/db-decorators';\nimport { reflectComponentType, Type } from '@angular/core';\n\n/**\n * @description Marks an Angular component as dynamically loadable\n * @summary Decorator that registers an Angular component with the NgxRenderingEngine for dynamic loading.\n * This decorator must be applied before the @Component decorator to properly extract component metadata.\n * It adds metadata to the component class and registers it with the rendering engine using its selector.\n * @function Dynamic\n * @return {Function} A decorator function that can be applied to Angular component classes\n * @mermaid\n * sequenceDiagram\n * participant C as Component Class\n * participant D as Dynamic Decorator\n * participant R as NgxRenderingEngine\n * participant M as Angular Metadata\n * C->>D: Apply decorator\n * D->>M: reflectComponentType()\n * M-->>D: Return component metadata\n * alt No metadata found\n * D->>D: Throw InternalError\n * else Metadata found\n * D->>R: registerComponent(selector, constructor)\n * D->>C: Apply metadata\n * end\n * @category Decorators\n */\nexport function Dynamic() {\n return apply(\n (original: object) => {\n const metadata = reflectComponentType(original as Type<unknown>);\n\n if (!metadata)\n throw new InternalError(\n `Could not find Component metadata. @Dynamic decorator must come above @Component`\n );\n\n NgxRenderingEngine.registerComponent(\n metadata.selector,\n original as unknown as Constructor<unknown>\n );\n },\n metadata(\n Metadata.key(AngularEngineKeys.REFLECT, AngularEngineKeys.DYNAMIC),\n true\n )\n );\n}\n\n\n// export interface UICustomEvents {\n// render: () => HandlerLike;\n// init: () => FunctionLike;\n// }\n\n// export function uion(event: string, handler: FunctionLike) {\n// return (target: any, propertyKey?: any) => {\n// const metadata = {\n// [event]: handler,\n// };\n// propMetadata(getUIAttributeKey(propertyKey, 'handlers'), metadata)(\n// target,\n// propertyKey\n// );\n// };\n// // return (model: unknown, property: unknown) => {\n// // const meta: UIHandlerMetadata = {\n// // [event]: handler,\n// // };\n// // return metadata(\n// // getUIAttributeKey(property as string, 'on'),\n// // meta\n// // )(model, property);\n// // };\n// }\n\n\n// export function uionrender(handler: FunctionLike) {\n// return uion(\"render\", handler);\n// }\n\n// @uion(op, handler)\n\n// @uionrender(handler){\n// return uion(\"redenr\", handler)\n// }\n","/**\n * @module module:lib/components/model-renderer/model-renderer.component\n * @description Model renderer component module.\n * @summary Exposes `ModelRendererComponent` which dynamically renders UI components\n * from model definitions using the `NgxRenderingEngine`. It handles model changes,\n * event subscription and lifecycle for the rendered output.\n *\n * @link {@link ModelRendererComponent}\n */\n\nimport {\n Component,\n Input,\n SimpleChanges\n} from '@angular/core';\nimport { Model, sf } from '@decaf-ts/decorator-validation';\nimport { AngularEngineKeys, BaseComponentProps } from '../../engine/constants';\nimport { AngularDynamicOutput } from '../../engine/interfaces';\nimport { Renderable } from '@decaf-ts/ui-decorators';\nimport { NgxRenderableComponentDirective } from '../../engine/NgxRenderableComponentDirective';\n\n/**\n * @description Component for rendering dynamic models\n * @summary This component is responsible for dynamically rendering models,\n * handling model changes, and managing event subscriptions for the rendered components.\n * It uses the NgxRenderingEngine to render the models and supports both string and Model inputs.\n * @class\n * @template M - Type extending Model\n * @param {Injector} injector - Angular Injector for dependency injection\n * @example\n * <ngx-decaf-model-renderer\n * [model]=\"myModel\"\n * [globals]=\"globalVariables\"\n * (listenEvent)=\"handleEvent($event)\">\n * </ngx-decaf-model-renderer>\n * @mermaid\n * sequenceDiagram\n * participant App\n * participant ModelRenderer\n * participant RenderingEngine\n * participant Model\n * App->>ModelRenderer: Input model\n * ModelRenderer->>Model: Parse if string\n * Model-->>ModelRenderer: Parsed model\n * ModelRenderer->>RenderingEngine: Render model\n * RenderingEngine-->>ModelRenderer: Rendered output\n * ModelRenderer->>ModelRenderer: Subscribe to events\n * ModelRenderer-->>App: Emit events\n */\n@Component({\n standalone: true,\n imports: [],\n selector: 'ngx-decaf-model-renderer',\n templateUrl: './model-renderer.component.html',\n styleUrl: './model-renderer.component.scss',\n host: {'[attr.id]': 'uid'}\n\n})\nexport class ModelRendererComponent<M extends Model>\n extends NgxRenderableComponentDirective {\n\n /**\n * @description Set if render content projection is allowed\n * @default true\n */\n @Input()\n override projectable: boolean = true;\n\n // private injector: Injector = inject(Injector);\n\n // constructor() {}\n\n /**\n * @description Refreshes the rendered model\n * @param {string | M} model - The model to be rendered\n */\n private refresh(model: string | M) {\n model =\n typeof model === 'string'\n ? (Model.build({}, model) as M)\n : model;\n this.output = (model as unknown as Renderable).render<AngularDynamicOutput>(\n this.globals || {},\n this.vcr,\n this.injector,\n this.inner,\n this.projectable\n );\n if (this.output?.inputs)\n this.rendererId = sf(\n AngularEngineKeys.RENDERED_ID,\n (this.output.inputs as Record<string, unknown>)['rendererId'] as string,\n );\n this.instance = this.output?.component;\n this.subscribeEvents();\n }\n\n /**\n * @description Lifecycle hook that is called when data-bound properties of a directive change\n * @param {SimpleChanges} changes - Object containing changes\n */\n override async ngOnChanges(changes: SimpleChanges): Promise<void> {\n if (changes[BaseComponentProps.MODEL]) {\n const { currentValue } = changes[BaseComponentProps.MODEL];\n this.refresh(currentValue);\n }\n }\n\n\n}\n"," <!-- Keep to avoid id conflicts -->\n <div class=\"dcf-hidden\" [id]=\"uid\"></div>\n\n <ng-template #componentOuter></ng-template>\n <!-- <ng-template #inner>\n <div class=\"dcf-grid dcf-grid-small dcf-model-renderer-component dcf-child-width-1-1\" [id]=\"rendererId || ''\">\n @for (child of output?.children; track child) {\n @if (child?.children?.length) {\n <ngx-decaf-component-renderer [parent]=\"child\" />\n } @else {\n <ng-container\n #childComponents\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n </div>\n </ng-template> -->\n","/**\n * @module module:lib/engine/NgxParentComponentDirective\n * @description Directive base for parent container components used by the rendering system.\n * @summary Provides NgxParentComponentDirective which offers inputs for children metadata,\n * column/row configuration and parent component wiring used by layout and container components.\n *\n * @link {@link NgxParentComponentDirective}\n */\nimport { Directive, Input, OnInit } from '@angular/core';\nimport { NgxComponentDirective } from './NgxComponentDirective';\nimport { FormParent, KeyValue } from './types';\nimport { FieldDefinition, IPagedComponentProperties, UIMediaBreakPoints, UIMediaBreakPointsType, UIModelMetadata } from '@decaf-ts/ui-decorators';\nimport { Model } from '@decaf-ts/decorator-validation';\nimport { IComponentProperties } from './interfaces';\nimport { Subscription, timer } from 'rxjs';\n\n/**\n * @description Layout component for creating responsive grid layouts in Angular applications.\n * @summary This component provides a flexible grid system that can be configured with dynamic\n * rows and columns. It supports responsive breakpoints and can render child components within\n * the grid structure. The component extends NgxComponentDirective to inherit common functionality\n * and integrates with the model and component renderer systems.\n *\n * @class NgxParentComponentDirective\n * @extends {NgxComponentDirective}\n * @implements {OnInit}\n */\n@Directive()\nexport class NgxParentComponentDirective extends NgxComponentDirective implements OnInit {\n\n /**\n * @description Unique identifier for the current record.\n * @summary A unique identifier for the current record being displayed or manipulated.\n * This is typically used in conjunction with the primary key for operations on specific records.\n *\n * @type {string | number}\n */\n @Input()\n page: number = 1;\n\n\n /**\n * @description Unique identifier for the current record.\n * @summary A unique identifier for the current record being displayed or manipulated.\n * This is typically used in conjunction with the primary key for operations on specific records.\n *\n * @type {string | number}\n */\n @Input()\n pages: number | IPagedComponentProperties[] = 1;\n\n\n /**\n * @description Array of UI model metadata for the currently active page.\n * @summary Contains only the UI model metadata for fields that should be displayed\n * on the currently active page. This is a filtered subset of the children array,\n * updated whenever the user navigates between pages.\n *\n * @type { UIModelMetadata | UIModelMetadata[] | FieldDefinition | FieldDefinition[] | undefined }\n */\n activePage: UIModelMetadata | UIModelMetadata[] | FieldDefinition | FieldDefinition[] | undefined = undefined;\n\n\n /**\n * @description The currently active page number.\n * @summary Tracks which page of the multi-step form is currently being displayed.\n * This property is updated as users navigate through the form steps using\n * the next/back buttons or programmatic navigation.\n *\n * @type {number}\n */\n activeIndex: number = 1;\n\n /**\n * @description The parent form object that represents the parent-child relationship in the form hierarchy.\n * @summary This input binds the parent form object to the directive, enabling hierarchical form structures.\n * It allows the directive to interact with the parent form and manage child components effectively.\n *\n * @type {FormParent}\n */\n @Input()\n parentForm!: FormParent;\n\n\n /**\n * @description Array of UI model metadata for all form fields.\n * @summary Contains the complete collection of UI model metadata that defines\n * the structure, validation, and presentation of form fields across all pages.\n * Each metadata object contains information about field type, validation rules,\n * page assignment, and display properties.\n *\n * @type {UIModelMetadata[]}\n */\n @Input()\n children: UIModelMetadata[] | IComponentProperties[] | FieldDefinition[] | KeyValue[] = [];\n\n\n /**\n * @description Number of columns or array of column definitions for the grid layout.\n * @summary Defines the column structure of the grid. When a number is provided, it creates\n * that many equal-width columns. When an array is provided, each element can define specific\n * column properties or sizing. This allows for flexible grid layouts that can adapt to\n * different content requirements.\n *\n * @type {(number | string[])}\n * @default 1\n */\n @Input()\n cols: number | string[] = 1;\n\n /**\n * @description Number of rows or array of row definitions for the grid layout.\n * @summary Defines the row structure of the grid. When a number is provided, it creates\n * that many equal-height rows. When an array is provided, each element can define specific\n * row properties or sizing. This provides control over vertical spacing and content organization.\n *\n * @type {(number | string[])}\n * @default 1\n */\n @Input()\n rows: number | KeyValue[] | string[] = 1;\n\n /**\n * @description Defines the body style of the card.\n * @summary Specifies the appearance of the card body, allowing customization\n * between default, small, or blank styles. This input is used to control the\n * visual presentation of the card content.\n * @type {'default' | 'small' | 'blank'}\n * @default 'default'\n */\n @Input()\n cardBody: 'default' | 'small' | 'blank' = 'default';\n\n /**\n * @description Specifies the type of the card.\n * @summary Determines the card's visual style, such as clear or shadowed.\n * This input allows for flexible styling of the card component to match\n * different design requirements.\n * @type {'clear' | 'shadow'}\n * @default 'clear'\n */\n @Input()\n cardType: 'clear' | 'shadow' = 'clear';\n\n\n /**\n * @description Media breakpoint for responsive behavior.\n * @summary Determines the responsive breakpoint at which the layout should adapt.\n * This affects how the grid behaves on different screen sizes, allowing for\n * mobile-first or desktop-first responsive design patterns. The breakpoint\n * is automatically processed to ensure compatibility with the UI framework.\n *\n * @type {UIMediaBreakPointsType}\n * @default 'medium'\n */\n @Input()\n breakpoint?: UIMediaBreakPointsType | string = UIMediaBreakPoints.MEDIUM;\n\n\n /**\n * @description Determines if the layout should match the parent container's size or configuration.\n * @summary Boolean flag that controls whether the component should adapt its layout to match its parent.\n * When true, the component will attempt to align or size itself according to the parent container.\n *\n * @type {boolean}\n * @default true\n */\n @Input()\n match: boolean = true;\n\n\n /**\n * @description Preloads card placeholders for rendering.\n * @summary Used to create an array of placeholder elements for card components,\n * typically to reserve space or trigger rendering logic before actual data is loaded.\n *\n * @type {any[]}\n * @default [undefined]\n */\n preloadCards: string[] = new Array(1);\n\n\n /**\n * @description Subscription for timer-based operations.\n * @summary Manages the timer subscription used for asynchronous operations\n * like updating active children after page transitions. This subscription\n * is cleaned up in ngOnDestroy to prevent memory leaks.\n *\n * @private\n * @type {Subscription}\n * @memberOf SteppedFormComponent\n */\n protected timerSubscription!: Subscription;\n\n async ngOnInit(model?: Model | string): Promise<void> {\n if (model)\n this.model = model as unknown as string;\n if (this.model && !this.repository)\n this._repository = this.repository;\n }\n\n override ngOnDestroy(): Promise<void> | void {\n super.ngOnDestroy();\n if (this.timerSubscription)\n this.timerSubscription.unsubscribe();\n }\n\n protected getActivePage(page: number): UIModelMetadata | UIModelMetadata[] | FieldDefinition | undefined {\n const content = this.children[page] as FieldDefinition;\n this.activePage = undefined;\n this.preloadCards = [... new Array(1)];\n this.timerSubscription = timer(1).subscribe(() =>\n this.activePage = {... this.children[page] as FieldDefinition }\n );\n this.activeIndex = page;\n if(content)\n return content;\n return undefined;\n }\n}\n","import { Component, EnvironmentInjector, EventEmitter, inject, Input, OnInit, Output, ViewChild} from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { OverlayEventDetail} from \"@ionic/core\";\n\nimport {\n IonButton,\n IonButtons,\n IonContent,\n IonHeader,\n IonModal,\n IonSpinner,\n IonTitle,\n IonToolbar,\n ModalOptions\n} from '@ionic/angular/standalone';\nimport { ModelRendererComponent } from '../model-renderer/model-renderer.component';\nimport * as allIcons from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { NgxRenderingEngine } from '../../engine/NgxRenderingEngine';\nimport { Dynamic } from '../../engine/decorators';\nimport { KeyValue, SelectOption } from '../../engine/types';\nimport { IBaseCustomEvent } from '../../engine/interfaces';\nimport {ActionRoles, DefaultModalOptions} from '../../engine/constants';\nimport { NgxParentComponentDirective } from '../../engine/NgxParentComponentDirective';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { OperationKeys } from '@decaf-ts/db-decorators';\nimport { Primitives } from '@decaf-ts/decorator-validation';\nimport { ComponentRendererComponent } from '../component-renderer/component-renderer.component';\n\n/**\n * @description Modal component for displaying dynamic content in a modal dialog.\n * @summary This component provides a flexible and reusable modal dialog implementation\n * for Angular applications. It supports dynamic content rendering, customizable options,\n * and event handling for modal lifecycle events. The modal can be used for various purposes,\n * such as displaying forms, lightboxes, or selection dialogs.\n *\n * @class ModalComponent\n * @example\n * ```typescript\n * <ngx-decaf-modal [isOpen]=\"true\" [title]=\"'Example Modal'\"></ngx-decaf-modal>\n * ```\n * @mermaid\n * sequenceDiagram\n * participant User\n * participant ModalComponent\n * User->>ModalComponent: Open modal\n * ModalComponent->>ModalController: Initialize modal\n * ModalController-->>ModalComponent: Modal options set\n * User->>ModalComponent: Interact with modal\n * ModalComponent->>ModalController: Handle dismiss event\n */\n\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-modal',\n templateUrl: 'modal.component.html',\n styleUrls: ['modal.component.scss'],\n standalone: true,\n imports: [IonModal, ComponentRendererComponent, ModelRendererComponent, TranslatePipe, IonSpinner, IonButton, IonButtons, IonContent, IonHeader, IonTitle, IonToolbar],\n host: {'[attr.id]': 'uid'},\n})\n/**\n * @description A reusable modal component that wraps Ionic's IonModal functionality.\n * @summary Provides a flexible modal dialog implementation with support for custom content, positioning, fullscreen mode, and lightbox mode. Extends NgxParentComponentDirective to inherit common component functionality.\n *\n * @extends {NgxParentComponentDirective}\n * @implements {OnInit}\n *\n * @example\n * ```typescript\n * // Basic usage in template\n * <app-modal\n * [isOpen]=\"showModal\"\n * [title]=\"'Confirmation'\"\n * [inlineContent]=\"'Are you sure?'\"\n * (willDismissEvent)=\"handleDismiss($event)\">\n * </app-modal>\n *\n * // Programmatic usage\n * const modal = await modalComponent.create({ title: 'Settings' });\n * ```\n *\n * @remarks\n * - The modal supports inline content that can be positioned at the top or bottom\n * - Fullscreen and lightbox modes are available for different display needs\n * - The component automatically sanitizes HTML content for security\n * - Modal dismissal can be handled through cancel or confirm actions\n * - Global configuration can be passed through the globals input\n *\n * @public\n */\nexport class ModalComponent extends NgxParentComponentDirective implements OnInit {\n\n @ViewChild('component')\n modal!: IonModal;\n\n /**\n * @description Title of the modal dialog.\n * @summary Specifies the title text displayed in the modal header.\n * @type {string | undefined}\n */\n @Input()\n title?: string;\n\n /**\n * @description Determines whether the modal is open.\n * @summary Controls the visibility of the modal dialog. When set to true, the modal is displayed.\n * @type {boolean}\n * @default false\n */\n @Input()\n isOpen: boolean = false;\n\n /**\n * @description Tag identifier for the modal.\n * @summary Provides a unique tag for identifying the modal instance.\n * @type {string | undefined}\n */\n @Input()\n tag?: string;\n\n /**\n * @description Options for configuring the modal.\n * @summary Allows customization of modal behavior and appearance through the ModalOptions interface.\n * @type {ModalOptions | undefined}\n */\n @Input()\n options?: ModalOptions;\n\n /**\n * @description Global key-value pairs for modal configuration.\n * @summary Stores global settings that can be accessed within the modal instance.\n * @type {KeyValue | undefined}\n */\n @Input()\n globals?: KeyValue;\n\n /**\n * @description Inline content to be displayed in the modal.\n * @summary Specifies the HTML or SafeHtml content to be rendered inside the modal.\n * @type {string | SafeHtml | undefined}\n */\n @Input()\n inlineContent?: string | SafeHtml;\n\n /**\n * @description Position of the inline content within the modal.\n * @summary Determines whether the inline content is displayed at the top or bottom of the modal.\n * @type {'top' | 'bottom'}\n * @default 'bottom'\n */\n @Input()\n inlineContentPosition: 'top' | 'bottom' = 'bottom';\n\n /**\n * @description Enables fullscreen mode for the modal.\n * @summary When set to true, the modal occupies the entire screen.\n * @type {boolean}\n * @default false\n */\n @Input()\n fullscreen: boolean = false;\n\n /**\n * @description Enables lightbox mode for the modal.\n * @summary When set to true, the modal is displayed as a lightbox.\n * @type {boolean}\n * @default false\n */\n @Input()\n lightBox: boolean = false;\n\n\n /**\n * @description Event emitted when the modal is about to be dismissed.\n * @summary Emits an OverlayEventDetail object containing details about the dismiss event.\n * @type {EventEmitter<OverlayEventDetail>}\n */\n @Output()\n willDismissEvent: EventEmitter<OverlayEventDetail> = new EventEmitter<OverlayEventDetail>();\n\n /**\n * @description Sanitizer instance for bypassing security and sanitizing HTML content.\n * @summary Used to sanitize dynamic HTML content, ensuring it is safe to render in the DOM.\n * @type {DomSanitizer}\n */\n domSanitizer: DomSanitizer = inject(DomSanitizer);\n\n constructor() {\n super(\"ModalComponent\");\n addIcons(allIcons);\n }\n\n /**\n * @description Lifecycle hook that initializes the modal component.\n * @summary Sets up the modal controller and sanitizes inline content if provided.\n *\n * @returns {Promise<void>} - A promise that resolves when initialization is complete.\n */\n override async ngOnInit(): Promise<void> {\n if (this.inlineContent && typeof this.inlineContent === Primitives.STRING) {\n this.inlineContent = this.domSanitizer.bypassSecurityTrustHtml(this.inlineContent as string);\n }\n }\n\n /**\n * @description Initializes the modal with the provided options.\n * @summary Merges default options with user-provided options and sets global configuration.\n *\n * @param {KeyValue} [options={}] - Additional options for modal initialization.\n * @returns {Promise<void>} - A promise that resolves when initialization is complete.\n */\n override async initialize(options: KeyValue = {}): Promise<void> {\n this.options = Object.assign({}, DefaultModalOptions, this.options, options);\n this.globals = Object.assign({}, this.globals || {}, { isModalChild: true });\n this.initialized = true;\n }\n\n /**\n * @description Creates and presents the modal.\n * @summary Initializes the modal with the provided properties and displays it.\n *\n * @param {KeyValue} [props={}] - Properties to initialize the modal.\n * @returns {Promise<ModalComponent>} - A promise that resolves with the modal instance.\n */\n async create(props: KeyValue = {}): Promise<ModalComponent> {\n await this.initialize(props);\n await this.present();\n return this;\n }\n\n /**\n * @description Presents the modal.\n * @summary Sets the modal's visibility to true and triggers change detection.\n *\n * @returns {Promise<void>} - A promise that resolves when the modal is presented.\n */\n async present(): Promise<void> {\n this.isOpen = true;\n this.changeDetectorRef.detectChanges();\n }\n\n /**\n * @description Handles custom events for the modal.\n * @summary Stops event propagation and triggers confirm or cancel actions based on event data.\n *\n * @param {IBaseCustomEvent} event - The custom event to handle.\n * @returns {Promise<void>} - A promise that resolves when the event is handled.\n */\n override async handleEvent(event: IBaseCustomEvent): Promise<void> {\n if (event instanceof Event) {\n event.stopImmediatePropagation();\n }\n await (event?.data ? this.confirm(event) : this.cancel());\n }\n\n /**\n * @description Handles the modal dismiss event.\n * @summary This method is triggered when the modal is about to be dismissed. It emits the `willDismissEvent` with the event details.\n *\n * @param {CustomEvent<OverlayEventDetail>} event - The dismiss event containing overlay details.\n * @returns {Promise<OverlayEventDetail>} - A promise that resolves with the overlay event details.\n */\n async handleWillDismiss(event: CustomEvent<OverlayEventDetail>): Promise<OverlayEventDetail> {\n const { detail } = event;\n this.willDismissEvent.emit(event as OverlayEventDetail);\n return detail;\n }\n\n /**\n * @description Cancels the modal and dismisses it with a cancel action.\n * @summary This method is used to programmatically close the modal with a cancel action.\n *\n * @returns {Promise<void>} - A promise that resolves when the modal is dismissed.\n */\n async cancel(): Promise<void> {\n await (this.modal as IonModal).dismiss(undefined, ActionRoles.cancel);\n }\n\n /**\n * @description Confirms the modal and dismisses it with a confirm action.\n * @summary This method is used to programmatically close the modal with a confirm action, passing optional event data.\n *\n * @param {IBaseCustomEvent} event - The custom event containing data to pass during confirmation.\n * @returns {Promise<void>} - A promise that resolves when the modal is dismissed.\n */\n async confirm(event: IBaseCustomEvent): Promise<void> {\n await (this.modal as IonModal).dismiss(event?.data || undefined, ActionRoles.confirm);\n }\n}\n\n/**\n * @description Retrieves a modal component instance.\n * @summary Creates and initializes a modal component with the provided properties and options.\n *\n * @param {Partial<ModalComponent>} [props={}] - Properties to initialize the modal component.\n * @param {Partial<ModalOptions>} [modalProps={}] - Additional modal options.\n * @param {EnvironmentInjector} [injector] - Optional environment injector for dependency injection.\n * @returns {Promise<IonModal>} - A promise that resolves with the modal instance.\n */\nexport async function getNgxModalComponent(props: Partial<ModalComponent> = {}, modalProps: Partial<ModalOptions> = {}, injector?: EnvironmentInjector): Promise<IonModal> {\n const { globals } = { ...props };\n if (!globals || !globals?.['operation']) {\n props.globals = { ...(globals || {}), operation: OperationKeys.CREATE };\n }\n const component = await (NgxRenderingEngine.createComponent(ModalComponent, props, injector || undefined) as ModalComponent).create(modalProps);\n return component.modal;\n}\n\n/**\n * @description Presents a lightbox modal with inline content.\n * @summary Displays a modal in lightbox mode with the specified content and properties.\n *\n * @param {string | SafeHtml} inlineContent - The content to display in the lightbox modal.\n * @param {Partial<ModalComponent>} [props={}] - Properties to initialize the modal component.\n * @param {EnvironmentInjector} [injector] - Optional environment injector for dependency injection.\n * @returns {Promise<void>} - A promise that resolves when the modal is presented.\n */\nexport async function presentNgxLightBoxModal(inlineContent: string | SafeHtml, props: Partial<ModalComponent> = {}, injector?: EnvironmentInjector): Promise<void> {\n return (await getNgxModalComponent({ props, ...{ inlineContent, lightBox: true } }, {}, injector || undefined)).present();\n}\n\n/**\n * @description Retrieves a modal for selecting options.\n * @summary Creates and initializes a modal component for displaying a list of selectable options.\n *\n * @param {SelectOption[]} options - The list of options to display in the modal.\n * @param {EnvironmentInjector} [injector] - Optional environment injector for dependency injection.\n * @returns {Promise<IonModal>} - A promise that resolves with the modal instance.\n */\nexport async function getNgxSelectOptionsModal(options: SelectOption[], injector?: EnvironmentInjector): Promise<IonModal> {\n const props = {\n tag: 'ngx-decaf-list',\n globals: {\n data: options,\n item: { tag: true },\n pk: 'value',\n mapper: { title: 'text', uid: 'value' },\n },\n };\n return (await getNgxModalComponent(props, {}, injector || undefined));\n}\n","<ion-modal\n [id]=\"uid\"\n [isOpen]=\"isOpen\"\n (willDismiss)=\"handleWillDismiss($event)\"\n [backdropDismiss]=\"options?.backdropDismiss\"\n [showBackdrop]=\"options?.showBackdrop\"\n [animated]=\"options?.animated\"\n [canDismiss]=\"options?.canDismiss\"\n [class.dcf-fullscreen-modal]=\"fullscreen\"\n [class.dcf-lightbox-modal]=\"lightBox\"\n class=\"dcf-modal-component\"\n #component\n>\n <ng-template>\n <ion-header [transparent]=\"lightBox\">\n <ion-toolbar>\n @if (title) {\n <ion-title>{{ title | translate }}</ion-title>\n }\n <ion-buttons slot=\"end\">\n <ion-button size=\"small\" type=\"button\" class=\"dcf-button-close\" (click)=\"cancel()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n\n <ion-content>\n <section class=\"dcf-modal-body\">\n @if (!tag && !model && !inlineContent) {\n <div class=\"dcf-loading-container\">\n <ion-spinner name=\"crescent\" color=\"primary\"></ion-spinner>\n </div>\n } @else {\n @if (inlineContent && inlineContentPosition === \"top\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n @if (model) {\n <ngx-decaf-model-renderer\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"globals\"\n />\n }\n @if(tag && globals) {\n <ngx-decaf-component-renderer\n [tag]=\"tag\"\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"{props: globals}\"\n />\n }\n @if (inlineContent && inlineContentPosition === \"bottom\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n }\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n","/**\n * @module module:lib/components/crud-field/crud-field.component\n * @description CRUD field component module.\n * @summary Exposes `CrudFieldComponent`, a dynamic form field used in CRUD forms supporting\n * many input types, validation and integration with `NgxFormFieldDirective` utilities.\n *\n * @link {@link CrudFieldComponent}\n */\n\nimport {\n AfterViewInit,\n Component,\n CUSTOM_ELEMENTS_SCHEMA,\n ElementRef,\n HostListener,\n Input,\n OnDestroy,\n OnInit,\n ViewChild\n} from '@angular/core';\nimport { FormArray, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { TranslatePipe} from '@ngx-translate/core';\nimport { AutocompleteTypes, CheckboxCustomEvent, SelectInterface } from '@ionic/core';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport {\n IonCheckbox,\n IonInput,\n IonItem,\n IonLabel,\n IonRadio,\n IonRadioGroup,\n IonSelect,\n IonSelectOption,\n IonText,\n IonTextarea,\n} from '@ionic/angular/standalone';\nimport { CrudOperationKeys, HTML5InputTypes } from '@decaf-ts/ui-decorators';\nimport { addIcons } from 'ionicons';\nimport { chevronDownOutline, chevronUpOutline } from 'ionicons/icons';\nimport { getModelAndRepository } from '../../for-angular-common.module';\nimport { CrudFieldOption, FieldUpdateMode, KeyValue, FunctionLike, PossibleInputTypes, StringOrBoolean, FormParent, SelectOption } from '../../engine/types';\nimport { dataMapper, generateRandomValue } from '../../utils';\nimport { NgxFormFieldDirective } from '../../engine/NgxFormFieldDirective';\nimport { Dynamic } from '../../engine/decorators';\nimport { getLocaleContextByKey } from '../../i18n/Loader';\nimport { getNgxSelectOptionsModal } from '../modal/modal.component';\nimport { ActionRoles } from '../../engine/constants';\n\n/**\n * @description A dynamic form field component for CRUD operations.\n * @summary The CrudFieldComponent is a versatile form field component that adapts to different\n * input types and CRUD operations. It extends NgxFormFieldDirective to inherit form handling capabilities\n * and implements lifecycle hooks to properly initialize, render, and clean up. This component\n * supports various input types (text, number, date, select, etc.), validation rules, and styling\n * options, making it suitable for building dynamic forms for create, read, update, and delete\n * operations.\n *\n * @param {CrudOperations} operation - The CRUD operation being performed (create, read, update, delete)\n * @param {string} name - The field name, used as form control identifier\n * @param {PossibleInputTypes} type - The input type (text, number, date, select, etc.)\n * @param {string|number|Date} value - The initial value of the field\n * @param {boolean} disabled - Whether the field is disabled\n * @param {string} label - The display label for the field\n * @param {string} placeholder - Placeholder text when field is empty\n * @param {string} format - Format pattern for the field value\n * @param {boolean} hidden - Whether the field should be hidden\n * @param {number|Date} max - Maximum allowed value\n * @param {number} maxlength - Maximum allowed length\n * @param {number|Date} min - Minimum allowed value\n * @param {number} minlength - Minimum allowed length\n * @param {string} pattern - Validation pattern\n * @param {boolean} readonly - Whether the field is read-only\n * @param {boolean} required - Whether the field is required\n * @param {number} step - Step value for number inputs\n * @param {FormGroup} formGroup - The parent form group\n * @param {StringOrBoolean} translatable - Whether field labels should be translated\n *\n * @component CrudFieldComponent\n * @example\n * <ngx-decaf-crud-field\n * operation=\"create\"\n * name=\"firstName\"\n * type=\"text\"\n * label=\"<NAME>\"\n * placeholder=\"<NAME>\"\n * [value]=\"model.firstName\"\n * [disabled]=\"model.readOnly\">\n *\n *\n * @memberOf module:for-angular\n */\n@Dynamic()\n@Component({\n standalone: true,\n imports: [\n ReactiveFormsModule,\n TranslatePipe,\n IonInput,\n IonItem,\n IonCheckbox,\n IonRadioGroup,\n IonRadio,\n IonSelect,\n IonSelectOption,\n IonLabel,\n IonText,\n IonTextarea\n ],\n selector: 'ngx-decaf-crud-field',\n templateUrl: './crud-field.component.html',\n styleUrl: './crud-field.component.scss',\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n host: {'[attr.id]': 'uid', '[attr.class]': 'className'},\n})\nexport class CrudFieldComponent extends NgxFormFieldDirective implements OnInit, OnDestroy, AfterViewInit {\n\n /**\n * @description The CRUD operation being performed.\n * @summary Specifies which CRUD operation (Create, Read, Update, Delete) the field is being used for.\n * This affects how the field behaves and is rendered. For example, fields might be read-only in\n * 'read' mode but editable in 'create' or 'update' modes.\n *\n * @type {CrudOperations}\n * @memberOf CrudFieldComponent\n */\n @Input({ required: true })\n override operation!: CrudOperations;\n\n /**\n * @summary The flat field name used as the form control identifier in immediate parent FormGroup.\n * @description\n * Specifies the name of the field, which is used as the FormControl identifier in immediate parent FormGroup.\n * This value must be unique within the immediate parent FormGroup context and should not contain dots or nesting.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input({ required: true })\n override name!: string;\n\n\n @Input()\n override className: string = 'dcf-width-1-1';\n\n /**\n * @summary The full field path used for form control resolution.\n * @description Specifies the hierarchical path of the field, used to resolve its location within the parent FormGroup (or nested FormGroups).\n * It is used as the identifier in the rendered HTML, and may include nesting (e.g., 'address.billing.street') and\n * should match the structure of the data model\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input({ required: true })\n override path!: string;\n\n /**\n * @description The parent field path, if this field is nested.\n * @summary Specifies the full dot-delimited path of the parent field. This is only set when the field is nested.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n /**\n * @description The parent field path for nested field structures.\n * @summary Specifies the full dot-delimited path of the parent field when this field\n * is part of a nested structure. This is used for hierarchical form organization\n * and proper form control resolution in complex form structures.\n *\n * @type {string}\n * @default ''\n * @memberOf CrudFieldComponent\n */\n @Input()\n override childOf: string = '';\n\n /**\n * @description The input type of the field.\n * @summary Defines the type of input to render, such as text, number, date, select, etc.\n * This determines which Ionic form component will be used to render the field and how\n * the data will be formatted and validated.\n *\n * @type {PossibleInputTypes}\n * @memberOf CrudFieldComponent\n */\n @Input({ required: true })\n override type!: PossibleInputTypes;\n\n /**\n * @description The initial value of the field.\n * @summary Sets the initial value of the form field. This can be a string, number, or Date\n * depending on the field type. For select fields, this should match one of the option values.\n *\n * @type {string | number | Date}\n * @default ''\n * @memberOf CrudFieldComponent\n */\n @Input()\n override value: string | number | Date | string[] = '';\n\n /**\n * @description Whether the field is disabled.\n * @summary When true, the field will be rendered in a disabled state, preventing user interaction.\n * Disabled fields are still included in the form model but cannot be edited by the user.\n *\n * @type {boolean}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override disabled?: boolean;\n\n /**\n * @description The display label for the field.\n * @summary The text label displayed alongside the field to identify it to the user.\n * This label can be translated if the translatable property is set to true.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input({ required: true })\n label!: string;\n\n /**\n * @description Placeholder text when field is empty.\n * @summary Text that appears in the input when it has no value. This provides a hint to the user\n * about what kind of data is expected. The placeholder disappears when the user starts typing.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input()\n placeholder!: string;\n\n /**\n * @description Format pattern for the field value.\n * @summary Specifies a format pattern for the field value, which can be used for date formatting,\n * number formatting, or other type-specific formatting requirements.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override format?: string;\n\n /**\n * @description Whether the field should be hidden.\n * @summary When true, the field will not be visible in the UI but will still be part of the form model.\n * This is useful for fields that need to be included in form submission but should not be displayed to the user.\n *\n * @type {boolean}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override hidden: boolean | CrudOperationKeys[] = false;\n\n /**\n * @description Maximum allowed value for the field.\n * @summary For number inputs, this sets the maximum allowed numeric value.\n * For date inputs, this sets the latest allowed date.\n *\n * @type {number | Date}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override max?: number | Date;\n\n /**\n * @description Maximum allowed length for text input.\n * @summary For text inputs, this sets the maximum number of characters allowed.\n * This is used for validation and may also be used to limit input in the UI.\n *\n * @type {number}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override maxlength?: number;\n\n /**\n * @description Minimum allowed value for the field.\n * @summary For number inputs, this sets the minimum allowed numeric value.\n * For date inputs, this sets the earliest allowed date.\n *\n * @type {number | Date}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override min?: number | Date;\n\n /**\n * @description Minimum allowed length for text input.\n * @summary For text inputs, this sets the minimum number of characters required.\n * This is used for validation to ensure the input meets a minimum length requirement.\n *\n * @type {number}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override minlength?: number;\n\n /**\n * @description Validation pattern for text input.\n * @summary A regular expression pattern used to validate text input.\n * The input value must match this pattern to be considered valid.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override pattern?: string;\n\n /**\n * @description Whether the field is read-only.\n * @summary When true, the field will be rendered in a read-only state. Unlike disabled fields,\n * read-only fields are still focusable but cannot be modified by the user.\n *\n * @type {boolean}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override readonly: boolean = false;\n\n /**\n * @description Whether the field is required.\n * @summary When true, the field must have a value for the form to be valid.\n * Required fields are typically marked with an indicator in the UI.\n *\n * @type {boolean}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override required?: boolean;\n\n /**\n * @description Step value for number inputs.\n * @summary For number inputs, this sets the increment/decrement step when using\n * the up/down arrows or when using a range slider.\n *\n * @type {number}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override step?: number;\n\n /**\n * @description Field name for equality validation comparison.\n * @summary Specifies another field name that this field's value must be equal to for validation.\n * This is commonly used for password confirmation fields or other scenarios where\n * two fields must contain the same value.\n *\n * @type {string | undefined}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override equals?: string;\n\n /**\n * @description Field name for inequality validation comparison.\n * @summary Specifies another field name that this field's value must be different from for validation.\n * This is used to ensure that two fields do not contain the same value, which might be\n * required for certain business rules or security constraints.\n *\n * @type {string | undefined}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override different?: string;\n\n /**\n * @description Field name for less-than validation comparison.\n * @summary Specifies another field name that this field's value must be less than for validation.\n * This is commonly used for date ranges, numeric ranges, or other scenarios where\n * one field must have a smaller value than another.\n *\n * @type {string | undefined}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override lessThan?: string;\n\n /**\n * @description Field name for less-than-or-equal validation comparison.\n * @summary Specifies another field name that this field's value must be less than or equal to\n * for validation. This provides inclusive upper bound validation for numeric or date comparisons.\n *\n * @type {string | undefined}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override lessThanOrEqual?: string;\n\n /**\n * @description Field name for greater-than validation comparison.\n * @summary Specifies another field name that this field's value must be greater than for validation.\n * This is commonly used for date ranges, numeric ranges, or other scenarios where\n * one field must have a larger value than another.\n *\n * @type {string | undefined}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override greaterThan?: string;\n\n /**\n * @description Field name for greater-than-or-equal validation comparison.\n * @summary Specifies another field name that this field's value must be greater than or equal to\n * for validation. This provides inclusive lower bound validation for numeric or date comparisons.\n *\n * @type {string | undefined}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override greaterThanOrEqual?: string;\n\n /**\n * @description Alignment of the field content.\n * @summary Controls the horizontal alignment of the field content.\n * This affects how the content is positioned within the field container.\n *\n * @type {'start' | 'center'}\n * @memberOf CrudFieldComponent\n */\n @Input()\n alignment?: 'start' | 'center';\n\n /**\n * @description Initial checked state for checkbox or toggle inputs.\n * @summary For checkbox or toggle inputs, this sets the initial checked state.\n * When true, the checkbox or toggle will be initially checked.\n *\n * @type {boolean}\n * @memberOf CrudFieldComponent\n */\n @Input()\n checked?: boolean;\n\n /**\n * @description Justification of items within the field.\n * @summary Controls how items are justified within the field container.\n * This is particularly useful for fields with multiple elements, such as radio groups.\n *\n * @type {'start' | 'end' | 'space-between'}\n * @memberOf CrudFieldComponent\n */\n @Input()\n justify?: 'start' | 'end' | 'space-between';\n\n /**\n * @description Text for the cancel button in select inputs.\n * @summary For select inputs with a cancel button, this sets the text displayed on the cancel button.\n * This is typically used in select dialogs to provide a way for users to dismiss the selection without making a change.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input()\n cancelText?: string;\n\n /**\n * @description Interface style for select inputs.\n * @summary Specifies the interface style for select inputs, such as 'alert', 'action-sheet', or 'popover'.\n * This determines how the select options are presented to the user.\n *\n * @type {SelectInterface}\n * @memberOf CrudFieldComponent\n */\n @Input()\n interface: SelectInterface = 'popover';\n\n /**\n * @description Options for select or radio inputs.\n * @summary Provides the list of options for select or radio inputs. Each option can have a value and a label.\n * This is used to populate the dropdown or radio group with choices.\n *\n * @type {CrudFieldOption[]}\n * @memberOf CrudFieldComponent\n */\n @Input()\n options!: FunctionLike | CrudFieldOption[] | KeyValue[];\n\n /**\n * @description Mode of the field.\n * @summary Specifies the visual mode of the field, such as 'ios' or 'md'.\n * This affects the styling and appearance of the field to match the platform style.\n *\n * @type {'ios' | 'md'}\n * @memberOf CrudFieldComponent\n */\n @Input()\n mode?: 'ios' | 'md';\n\n /**\n * @description Spellcheck attribute for text inputs.\n * @summary Enables or disables spellchecking for text inputs.\n * When true, the browser will check the spelling of the input text.\n *\n * @type {boolean}\n * @default false\n * @memberOf CrudFieldComponent\n */\n @Input()\n spellcheck: boolean = false;\n\n /**\n * @description Input mode for text inputs.\n * @summary Hints at the type of data that might be entered by the user while editing the element.\n * This can affect the virtual keyboard layout on mobile devices.\n *\n * @type {'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search'}\n * @default 'none'\n * @memberOf CrudFieldComponent\n */\n @Input()\n inputmode:\n | 'none'\n | 'text'\n | 'tel'\n | 'url'\n | 'email'\n | 'numeric'\n | 'decimal'\n | 'search' = 'none';\n\n /**\n * @description Autocomplete behavior for the field.\n * @summary Specifies whether and how the browser should automatically complete the input.\n * This can improve user experience by suggesting previously entered values.\n *\n * @type {AutocompleteTypes}\n * @default 'off'\n * @memberOf CrudFieldComponent\n */\n @Input()\n autocomplete: AutocompleteTypes = 'off';\n\n /**\n * @description Fill style for the field.\n * @summary Determines the fill style of the field, such as 'outline' or 'solid'.\n * This affects the border and background of the field.\n *\n * @type {'outline' | 'solid'}\n * @default 'outline'\n * @memberOf CrudFieldComponent\n */\n @Input()\n fill: 'outline' | 'solid' = 'outline';\n\n /**\n * @description Placement of the label relative to the field.\n * @summary Specifies where the label should be placed relative to the field.\n * Options include 'start', 'end', 'floating', 'stacked', and 'fixed'.\n *\n * @type {'start' | 'end' | 'floating' | 'stacked' | 'fixed'}\n * @default 'floating'\n * @memberOf CrudFieldComponent\n */\n @Input()\n labelPlacement: 'start' | 'end' | 'floating' | 'stacked' | 'fixed' =\n 'floating';\n\n /**\n * @description Update mode for the field.\n * @summary Determines when the field value should be updated in the form model.\n * Options include 'change', 'blur', and 'submit'.\n *\n * @type {FieldUpdateMode}\n * @default 'change'\n * @memberOf CrudFieldComponent\n */\n @Input()\n updateOn: FieldUpdateMode = 'change';\n\n /**\n * @description Reference to the field component.\n * @summary Provides a reference to the field component element, allowing direct access to its properties and methods.\n *\n * @type {ElementRef}\n * @memberOf CrudFieldComponent\n */\n @ViewChild('component', { read: ElementRef })\n override component!: ElementRef;\n\n /**\n * @description Parent form group.\n * @summary References the parent form group to which this field belongs.\n * This is necessary for integrating the field with Angular's reactive forms.\n *\n * @type {FormGroup}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override formGroup: FormGroup | undefined;\n\n\n /**\n * @description Angular FormControl instance for this field.\n * @summary The specific FormControl instance that manages this field's state, validation,\n * and value. This provides direct access to Angular's reactive forms functionality\n * for this individual field within the broader form structure.\n *\n * @type {FormControl}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override formControl!: FormControl;\n\n /**\n * @description Indicates if this field supports multiple values.\n * @summary When true, this field can handle multiple values, typically used in\n * multi-select scenarios or when the field is part of a form array structure\n * that allows multiple entries of the same field type.\n *\n * @type {boolean}\n * @default false\n * @memberOf CrudFieldComponent\n */\n @Input()\n override multiple: boolean = false;\n\n /**\n * @description Unique identifier for the current record.\n * @summary A unique identifier for the current record being displayed or manipulated.\n * This is typically used in conjunction with the primary key for operations on specific records.\n *\n * @type {string | number}\n */\n @Input()\n override uid: string = generateRandomValue(12);\n\n\n @Input()\n override page!: number;\n\n /**\n * @description Translatability of field labels.\n * @summary Indicates whether the field labels should be translated based on the current language settings.\n * This is useful for applications supporting multiple languages.\n *\n * @type {StringOrBoolean}\n * @default true\n * @memberOf CrudFieldComponent\n */\n @Input()\n translatable: StringOrBoolean = true;\n\n /**\n * @description Component initialization lifecycle method.\n * @summary Initializes the field component based on the operation type and field configuration.\n * For READ and DELETE operations, removes the form group to make fields read-only.\n * For other operations, sets up icons, configures multi-value support if needed,\n * and sets default values for radio buttons if no value is provided.\n *\n * @returns {void}\n * @memberOf CrudFieldComponent\n */\n async ngOnInit(): Promise<void> {\n this.options = await this.getOptions();\n addIcons({chevronDownOutline, chevronUpOutline});\n if (Array.isArray(this.hidden) && !(this.hidden as string[]).includes(this.operation)) {\n this.hidden = false;\n }\n if ([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation)) {\n this.formGroup = undefined;\n } else {\n if (!this.parentForm && this.formGroup instanceof FormGroup || this.formGroup instanceof FormArray)\n this.parentForm = (this.formGroup.root || this.formControl.root) as FormParent;\n if (this.multiple) {\n this.formGroup = this.activeFormGroup as FormGroup;\n if (!this.parentForm)\n this.parentForm = this.formGroup.parent as FormArray;\n this.formControl = (this.formGroup as FormGroup).get(this.name) as FormControl;\n }\n if (!this.value && (this.options as []).length)\n this.setValue((this.options as CrudFieldOption[])[0].value);\n\n if (this.type === HTML5InputTypes.CHECKBOX) {\n if(this.labelPlacement === 'floating')\n this.labelPlacement = 'end';\n if (Array.isArray(this.value))\n this.setValue(this.value);\n }\n }\n }\n\n /**\n * Returns a list of options for select or radio inputs, with their `text` property\n * localized if it does not already include the word 'options'. The localization key\n * is generated from the component's label, replacing 'label' with 'options'.\n *\n * @returns {CrudFieldOption[]} The array of parsed and localized options.\n * @memberOf CrudFieldComponent\n */\n async getOptions(): Promise<CrudFieldOption[]> {\n if (!this.options)\n return [];\n if (this.options instanceof Function) {\n if (this.options.name === 'options')\n this.options = this.options() as FunctionLike;\n const fnName = (this.options as FunctionLike)?.name;\n if (fnName) {\n if (fnName === 'function') {\n this.options = (this.options as FunctionLike)() as KeyValue[];\n } else {\n const repo = getModelAndRepository((this.options as KeyValue)?.['name']);\n if(repo) {\n const {repository} = repo;\n this.options = await repository.select().execute();\n }\n\n }\n }\n }\n if (this.optionsMapper) {\n if (this.optionsMapper instanceof Function || typeof this.optionsMapper === 'function') {\n const mapper = this.optionsMapper as (option: KeyValue) => CrudFieldOption;\n this.options = (this.options as (CrudFieldOption | KeyValue)[]).map((option: KeyValue) => {\n return mapper(option);\n });\n } else if (Object.keys(this.optionsMapper).length > 0) {\n this.options = dataMapper(this.options as KeyValue[], this.optionsMapper as Record<string, string>);\n }\n }\n const options = (this.options as CrudFieldOption[]).map(async(option) => {\n const text = await this.translate((!option.text.includes('options') ?\n getLocaleContextByKey(`${this.label.toLowerCase().replace('label', 'options')}`, option.text)\n : option.text));\n return {\n value: option.value,\n text: text.includes('.options') ? option.text : text\n };\n });\n this.options = await Promise.all(options);\n if (this.options.length > 10 && this.interface === 'popover')\n this.interface = 'modal';\n return this.options as CrudFieldOption[];\n }\n\n\n async openSelectOptions(event: Event, selectInterface: SelectInterface): Promise<void> {\n if(selectInterface === 'modal') {\n event.preventDefault();\n event.stopImmediatePropagation();\n const modal = await getNgxSelectOptionsModal(this.options as SelectOption[]);\n const {data, role} = await modal.onWillDismiss();\n if(role === ActionRoles.confirm && data !== this.value)\n this.setValue(data);\n }\n }\n\n\n /**\n * @description Component after view initialization lifecycle method.\n * @summary Calls the parent afterViewInit method for READ and DELETE operations.\n * This ensures proper initialization of read-only fields that don't require\n * form functionality but still need view setup.\n *\n * @returns {Promise<void>}\n * @memberOf CrudFieldComponent\n */\n async ngAfterViewInit(): Promise<void> {\n if (this.type === HTML5InputTypes.RADIO && !this.value)\n this.setValue((this.options as CrudFieldOption[])[0].value); // TODO: migrate to RenderingEngine\n }\n\n\n /**\n * @description Component cleanup lifecycle method.\n * @summary Performs cleanup operations for READ and DELETE operations by calling\n * the parent onDestroy method. This ensures proper resource cleanup for\n * read-only field components.\n *\n * @returns {void}\n * @memberOf CrudFieldComponent\n */\n override ngOnDestroy(): void {\n super.ngOnDestroy();\n if ([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation))\n this.onDestroy();\n }\n\n toggleOptionSelection(val: string, event: CheckboxCustomEvent) {\n const { checked } = event.detail;\n let value = Array.isArray(this.formControl.value) ? this.formControl.value : [];\n if (checked) {\n if (!value.includes(val))\n value = [...value, val];\n } else {\n value = value.filter(v => v !== val);\n }\n this.setValue(value);\n this.formControl.updateValueAndValidity();\n }\n\n\n isOptionChecked(value: string): boolean {\n if (!this.formControl.value || !Array.isArray(this.formControl.value))\n return false;\n return this.formControl.value.includes(value);\n }\n\n\n /**\n * @description Handles fieldset group update events from parent fieldsets.\n * @summary Processes events triggered when an existing group needs to be updated.\n * Updates the active form group index and refreshes the form group and form control\n * references to point to the group being edited.\n *\n * @param {CustomEvent} event - The fieldset update group event containing update details\n * @returns {void}\n * @memberOf CrudFieldComponent\n */\n @HostListener('window:fieldsetUpdateGroupEvent', ['$event'])\n handleFieldsetUpdateGroupEvent(event: CustomEvent): void {\n const {formGroup, index} = event.detail;\n this.activeFormGroupIndex = index;\n this.formGroup = formGroup;\n this.formControl = (this.formGroup as FormGroup).get(this.name) as FormControl;\n this.value = this.formControl.value;\n }\n}\n","@if (operation === 'read' || operation === 'delete') {\n <ng-container>\n <div>\n <ion-item [class]=\"'dcf-input-item ' + operation\" #component>\n <ion-label>\n {{ label | translate }}<br />\n @if (value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n @if (['checkbox'].includes(type)) {\n <ion-icon aria-hidden=\"true\" class=\"dcf-margin-small-top\" [color]=\"!isDarkMode ? 'primary' : 'light'\" size=\"large\" name=\"checkmark-circle-outline\"></ion-icon>\n } @else {\n <br />\n }\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n @if (formControl) {\n <ng-container [formGroup]=\"multiple ? activeFormGroup : formControl.parent\">\n <div\n [id]=\"uid\" #container\n [class]=\"'dcf-input-item ' + (operation || 'create')\"\n [class.dcf-field-required]=\"required\"\n [class.dcf-field-readonly]=\"readonly\"\n >\n @if (type === 'textarea') {\n <ion-textarea\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [inputmode]=\"inputmode\"\n [spellcheck]=\"spellcheck\"\n [rows]=\"rows\"\n [labelPlacement]=\"labelPlacement\"\n [value]=\"value\"\n [fill]=\"fill\"\n [errorText]=\"getErrors(container)\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [label]=\"label | translate\"\n #component>\n </ion-textarea>\n }\n @else if (type === 'checkbox') {\n @if (!options?.length) {\n <ion-item class=\"dcf-width-1-1\" [hidden]=\"hidden\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify || 'start'\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span>{{label | translate}}</span>\n </ion-checkbox>\n\n </ion-item>\n } @else {\n <div class=\"dcf-checkbox-group\">\n <label class=\"dcf-label\" [for]=\"path\">{{ label | translate }}</label>\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-item class=\"dcf-width-1-1\" [button]=\"true\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"option.text\"\n [mode]=\"'md'\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"option.value\"\n [readonly]=\"readonly\"\n [checked]=\"isOptionChecked(option.value)\"\n (ionChange)=\"toggleOptionSelection(option.value, $event)\"\n #component>\n <span>{{ $index + 1 }}. {{ option?.text | translate }}</span>\n </ion-checkbox>\n </ion-item>\n }\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n }\n\n }\n @else if (type === 'radio' && options?.length) {\n <ion-radio-group class=\"dcf-width-1-1\" [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track $index) {\n <ion-item>\n <ion-radio\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [errorText]=\"getErrors(container)\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ option?.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if (type === 'select') {\n <div>\n <ion-select\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [interface]=\"interface\"\n [mode]=\"'md'\"\n [hidden]=\"hidden || !options?.length\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"label | translate\"\n [value]=\"value\"\n (click)=\"openSelectOptions($event, interface)\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [interface]=\"interface\" #component>\n @if (options?.length) {\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n }\n </ion-select>\n <div class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></div>\n @if (!options?.length) {\n <ion-text color=\"danger\">\n * {{ 'errors.empty_options' | translate:{'0': name} }}\n </ion-text>\n }\n </div>\n }\n @else {\n <ion-input\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [type]=\"type\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [max]=\"max !== undefined ? max : null\"\n [min]=\"min !== undefined ? min : null\"\n [pattern]=\"pattern !== undefined ? pattern : null\"\n [step]=\"step !== undefined ? step : null\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [label]=\"label | translate\" #component />\n }\n </div>\n </ng-container>\n } @else {\n <div>\n <p class=\"dcf-error\">\n {{ 'errors.form.control' | translate:{'0': name} }}\n </p>\n </div>\n }\n\n}\n\n","import { AfterViewInit, Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from \"@angular/core\";\nimport { FormArray, FormGroup } from \"@angular/forms\";\nimport { CrudOperations, OperationKeys } from \"@decaf-ts/db-decorators\";\nimport { Model } from \"@decaf-ts/decorator-validation\";\nimport { NgxFormService } from \"../services/NgxFormService\";\nimport { ICrudFormEvent, IFormElement } from \"./interfaces\";\nimport { FieldUpdateMode, FormParent, HTMLFormTarget } from \"./types\";\nimport { ICrudFormOptions, IRenderedModel } from \"./interfaces\";\nimport { ActionRoles, ComponentEventNames } from \"./constants\";\nimport { NgxParentComponentDirective } from \"./NgxParentComponentDirective\";\nimport { NgxFormFieldDirective } from \"./NgxFormFieldDirective\";\nimport { generateRandomValue } from \"../utils\";\nimport { timer } from \"rxjs\";\nimport { FieldDefinition, UIFunctionLike, UIModelMetadata } from \"@decaf-ts/ui-decorators\";\n\n@Directive()\nexport abstract class NgxFormDirective extends NgxParentComponentDirective implements OnInit, AfterViewInit, IFormElement, OnDestroy, IRenderedModel {\n\n\n /**\n * @description Reactive form group associated with this fieldset.\n * @summary The FormGroup instance that contains all form controls within this fieldset.\n * Used for form validation, value management, and integration with Angular's reactive forms.\n *\n * @type {FormGroup}\n */\n @Input()\n parentFormId!: string;\n\n /**\n * @description Indicates whether this form is being used inside a modal dialog.\n * @summary When true, the form may alter its submit/reset behavior to integrate\n * with modal lifecycle (for example, emitting cancel events instead of\n * navigating back). Useful for components rendered inside Ionic/Angular\n * modal containers where navigation/back behavior differs from standard pages.\n *\n * Typical effects:\n * - `handleReset` will emit a cancel event instead of performing a navigation\n * - `ngAfterViewInit` checks for modal context to adjust change detection\n *\n * @type {boolean}\n * @default false\n */\n @Input()\n modalForm: boolean = false;\n\n\n /**\n * @description Reference to the reactive form DOM element.\n * @summary ViewChild reference that provides direct access to the form's DOM element.\n * This enables programmatic manipulation of the form element and access to native\n * HTML form properties and methods when needed.\n *\n * @type {ElementRef}\n */\n @ViewChild('component', { static: false, read: ElementRef })\n override component!: ElementRef;\n\n\n /**\n * @description Field update trigger mode for form validation.\n * @summary Determines when form field validation should be triggered. Options include\n * 'change', 'blur', or 'submit'. This affects the user experience by controlling\n * when validation feedback is shown to the user during form interaction.\n *\n * @type {FieldUpdateMode}\n * @default 'change'\n */\n @Input()\n updateOn: FieldUpdateMode = 'change';\n\n /**\n * @description Form submission target specification.\n * @summary Specifies where to display the response after form submission, similar\n * to the HTML form target attribute. Options include '_self', '_blank', '_parent',\n * '_top', or a named frame. Controls the browser behavior for form responses.\n *\n * @type {HTMLFormTarget}\n * @default '_self'\n */\n @Input()\n target: HTMLFormTarget = '_self';\n\n /**\n * @description HTTP method or submission strategy for the form.\n * @summary Defines how the form should be submitted. 'get' and 'post' correspond\n * to standard HTTP methods for traditional form submission, while 'event' uses\n * Angular event-driven submission for single-page application workflows.\n *\n * @type {'get' | 'post' | 'event'}\n * @default 'event'\n */\n @Input()\n method: 'get' | 'post' | 'event' = 'event';\n\n /**\n * @description Configuration options for the CRUD form behavior.\n * @summary Contains various configuration settings that control form rendering,\n * validation, and behavior. These options are merged with default settings\n * during component initialization to customize the form's functionality.\n *\n * @type {ICrudFormOptions}\n */\n @Input()\n options!: ICrudFormOptions;\n\n\n /**\n * @description Optional action identifier for form submission context.\n * @summary Specifies a custom action name that will be included in the submit event.\n * If not provided, defaults to the standard submit event constant. Used to\n * distinguish between different types of form submissions within the same component.\n *\n * @type {string | undefined}\n */\n @Input()\n action?: string;\n\n /**\n * @description The current CRUD operation being performed.\n * @summary Specifies the type of operation this form is handling (CREATE, READ, UPDATE, DELETE).\n * This is a required input that determines form behavior, validation rules, and available actions.\n * The operation affects form state, button visibility, and submission logic.\n *\n * @type {CrudOperations}\n * @required\n */\n @Input({ required: true })\n override operation: CrudOperations = OperationKeys.CREATE;\n\n /**\n * @description Custom event handlers for form actions.\n * @summary A record of event handler functions keyed by event names that can be\n * triggered during form operations. These handlers provide extensibility for\n * custom business logic and can be invoked for various form events and actions.\n *\n * @type {Record<string, UIFunctionLike>}\n */\n @Input()\n override handlers!: Record<string, UIFunctionLike>;\n\n /**\n * @description Angular reactive FormGroup for form state management.\n * @summary The FormGroup instance that manages all form controls, validation,\n * and form state. This is the main interface for accessing form values and\n * controlling form behavior. May be undefined for read-only operations.\n *\n * @type {FormGroup | undefined}\n */\n @Input()\n formGroup: FormParent | undefined = undefined;\n\n /**\n * @description Unique identifier for the form renderer.\n * @summary A unique string identifier used to register and manage this form\n * instance within the NgxFormService. This ID is also used as the HTML id\n * attribute for the form element, enabling DOM queries and form management.\n *\n * @type {string}\n */\n @Input()\n rendererId!: string;\n\n\n /**\n * @description Event emitter for form submission events.\n * @summary Emits ICrudFormEvent objects when the form is submitted, providing\n * form data, component information, and any associated handlers to parent\n * components. This enables decoupled handling of form submission logic.\n *\n * @type {EventEmitter<ICrudFormEvent>}\n */\n @Output()\n submitEvent: EventEmitter<ICrudFormEvent> = new EventEmitter<ICrudFormEvent>();\n\n /**\n * @description Unique identifier for the current record instance.\n * @summary This property holds a unique string value that identifies the specific record being managed by the form.\n * It is automatically generated if not provided, ensuring each form instance has a distinct identifier.\n * The uid is used for tracking, referencing, and emitting events related to the current record, and may be used\n * in conjunction with the primary key for CRUD operations.\n *\n * @type {string}\n * @default Randomly generated 12-character string\n */\n @Input()\n allowClear: boolean = true;\n\n @Input()\n override match: boolean = false;\n\n // protected override enableDarkMode: boolean = true;\n\n // /**\n // * @description Angular change detection service.\n // * @summary Injected service that provides manual control over change detection cycles.\n // * This is essential for ensuring that programmatic DOM changes (like setting accordion\n // * attributes) are properly reflected in the component's state and trigger appropriate\n // * view updates when modifications occur outside the normal Angular change detection flow.\n // *\n // * @protected\n // * @type {ChangeDetectorRef}\n // * @memberOf CrudFormComponent\n // */\n // protected changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);\n\n // /**\n // * @description Angular Renderer2 service for safe DOM manipulation.\n // * @summary Injected service that provides a safe, platform-agnostic way to manipulate DOM elements.\n // * This service ensures proper handling of DOM operations across different platforms and environments,\n // * including server-side rendering and web workers.\n // *\n // * @protected\n // * @type {Renderer2}\n // * @memberOf CrudFormComponent\n // */\n // protected renderer: Renderer2 = inject(Renderer2);\n\n // /**\n // * @description Translation service for internationalization.\n // * @summary Injected service that provides translation capabilities for UI text.\n // * Used to translate button labels and validation messages based on the current locale.\n // *\n // * @protected\n // * @type {TranslateService}\n // * @memberOf CrudFormComponent\n // */\n // protected translateService: TranslateService = inject(TranslateService);\n\n\n protected activeFormGroupIndex: number = 0;\n\n get activeFormGroup(): FormParent {\n return this.getFormArrayIndex(this.activeFormGroupIndex) as FormParent;\n }\n\n /**\n * @description Component initialization lifecycle method.\n * @summary Initializes the component by setting up the logger, configuring form state\n * based on the operation type, and merging configuration options. For READ and DELETE\n * operations, the formGroup is set to undefined since these operations don't require\n * form input. Configuration options are merged with default settings.\n *\n * @returns {Promise<void>}\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n override async ngOnInit(model?: Model | string): Promise<void> {\n if(!this.uid)\n this.uid = generateRandomValue(12);\n // dont call super.ngOnInit to model conflicts\n if (this.operation === OperationKeys.READ || this.operation === OperationKeys.DELETE)\n this.formGroup = undefined;\n this.initialized = true;\n }\n\n async ngAfterViewInit(): Promise<void> {\n if (this.isModalChild)\n this.changeDetectorRef.detectChanges();\n }\n\n /**\n * @description Component cleanup lifecycle method.\n * @summary Performs cleanup operations when the component is destroyed.\n * Unregisters the FormGroup from the NgxFormService to prevent memory leaks\n * and ensure proper resource cleanup.\n *\n * @returns {void}\n */\n override ngOnDestroy(): void {\n super.ngOnDestroy();\n if (this.formGroup)\n NgxFormService.unregister(this.formGroup);\n }\n\n getFormArrayIndex(index: number): FormParent | undefined {\n if (!(this.formGroup instanceof FormArray) && this.formGroup) {\n if (this.formGroup.disabled)\n (this.formGroup as FormParent).enable();\n return this.formGroup;\n }\n\n const formGroup = (this.formGroup as FormArray).at(index) as FormGroup;\n if(formGroup.disabled)\n (formGroup as FormParent).enable();\n if (formGroup) {\n if (this.children.length) {\n const children = [... this.children];\n this.children = [];\n this.changeDetectorRef.detectChanges();\n this.children = [... children.map(child => {\n const props = (child.props || {}) as NgxFormFieldDirective;\n const name = props.name;\n const control = formGroup.get(name);\n child.props.value = control?.value;\n child.props.formGroup = formGroup;\n child.props.activeFormGroupIndex = index;\n child.props.formControl = control;\n return child;\n })];\n this.changeDetectorRef.detectChanges();\n }\n }\n return formGroup || undefined;\n }\n\n\n /**\n * @description Handles form reset or navigation back functionality.\n * @summary Provides different reset behavior based on the current operation.\n * For CREATE and UPDATE operations, resets the form to its initial state.\n * For READ and DELETE operations, navigates back in the browser history\n * since these operations don't have modifiable form data to reset.\n *\n * @returns {void}\n */\n handleReset(): void {\n if (this.isModalChild) {\n this.submitEvent.emit({\n data: null,\n component: this.componentName,\n name: ActionRoles.cancel,\n });\n return;\n }\n if (![OperationKeys.DELETE, OperationKeys.READ].includes(this.operation) && this.allowClear)\n return NgxFormService.reset(this.formGroup as FormGroup);\n this.location.back();\n }\n\n async handleSubmit(event?: SubmitEvent, eventName?: string, componentName?: string): Promise<boolean | void> {\n if (event) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n const isValid = NgxFormService.validateFields(this.formGroup as FormGroup);\n if (this.isModalChild)\n this.changeDetectorRef.detectChanges();\n if (!isValid) {\n return false;\n }\n const data = NgxFormService.getFormData(this.formGroup as FormGroup);\n this.submitEvent.emit({\n data,\n component: componentName || this.componentName,\n name: eventName || this.action || ComponentEventNames.SUBMIT,\n handlers: this.handlers,\n });\n }\n\n /**\n * @description Updates the active form group and children for the specified page.\n * @summary Extracts the FormGroup for the given page from the FormArray and filters\n * the children to show only fields belonging to that page. Uses a timer to ensure\n * proper Angular change detection when updating the activeContent.\n *\n * @param {number} page - The page number to activate\n * @return {UIModelMetadata | UIModelMetadata[] | FieldDefinition | undefined}\n *\n * @private\n * @mermaid\n * sequenceDiagram\n * participant S as SteppedFormComponent\n * participant F as FormArray\n * participant T as Timer\n *\n * S->>F: Extract FormGroup at index (page - 1)\n * F-->>S: Return page FormGroup\n * S->>S: Set activeContent = undefined\n * S->>T: timer(10).subscribe()\n * T-->>S: Filter children for active page\n * S->>S: Set activeContent\n *\n * @memberOf SteppedFormComponent\n */\n protected override getActivePage(page: number): UIModelMetadata | UIModelMetadata[] | FieldDefinition | undefined {\n if (!(this.formGroup instanceof FormArray))\n this.formGroup = this.formGroup?.parent as FormArray;\n this.formGroup = (this.formGroup as FormArray).at(page - 1) as FormGroup;\n this.activePage = undefined;\n this.timerSubscription = timer(10).subscribe(() =>\n this.activePage = (this.children as UIModelMetadata[]).filter(c => c.props?.['page'] === page)\n );\n if(this.activePage)\n return this.activePage;\n return undefined;\n }\n\n}\n","/**\n * @module lib.components.card\n * @description Reusable Card UI component module.\n * @summary\n * Exports the `CardComponent`, a standalone Angular component built on Ionic's `IonCard` primitives.\n * The component exposes inputs to control visual style, content and layout and integrates with\n * the application's media service to react to dark-mode changes. See {@link CardComponent}.\n */\nimport { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';\nimport { Color } from '@ionic/core';\nimport { IonCard, IonCardContent, IonCardHeader, IonCardTitle , IonCardSubtitle } from '@ionic/angular/standalone';\nimport { Dynamic } from '../../engine/decorators';\nimport { NgxComponentDirective, } from '../../engine/NgxComponentDirective';\nimport { SafeHtml } from '@angular/platform-browser';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { AngularEngineKeys } from '../../engine/constants';\n\n/**\n * @description Reusable, presentational card UI component for use across the application.\n * @summary\n * CardComponent is a standalone Angular component built on Ionic's `IonCard` primitives.\n * It exposes several `@Input()` properties to control appearance and content:\n * `type`, `title`, `body`, `subtitle`, `color`, `separator`, `borders`, `inlineContent`, and `inlineContentPosition`.\n * The component integrates with the application's media service to react to dark-mode changes\n * and toggles the dark-palette CSS class on the host element accordingly.\n *\n * @param {('clear'|'shadow')} type - Visual rendering style for the card; 'clear' (default) or 'shadow'.\n * @param {string} title - Primary title text displayed in the card header.\n * @param {('small'|'default'|'blank')} body - Body size preset controlling padding/typography; defaults to 'default'.\n * @param {string} subtitle - Optional subtitle rendered under the title.\n * @param {Color} color - Ionic color token applied to the card header/title.\n * @param {boolean} separator - When true, renders a divider between header and body.\n * @param {boolean} borders - Controls whether borders are rendered; defaults to true.\n * @param {string|SafeHtml} inlineContent - Inline HTML/SafeHtml to render inside the body.\n * @param {('top'|'bottom')} inlineContentPosition - Where to render `inlineContent` relative to the body; defaults to 'bottom'.\n * @return {void}\n * @class CardComponent\n * @example\n * <ngx-decaf-card\n * [type]=\"'shadow'\"\n * [title]=\"'Account overview'\"\n * [subtitle]=\"'Summary for the current user'\"\n * [color]=\"'primary'\"\n * [separator]=\"true\"\n * [borders]=\"true\"\n * [inlineContent]=\"safeHtmlValue\"\n * inlineContentPosition=\"top\"\n * >\n * <!-- card content here -->\n * </ngx-decaf-card>\n *\n * @mermaid\n * sequenceDiagram\n * participant App as Consumer\n * participant Card as CardComponent\n * participant Media as MediaService\n * App->>Card: instantiate\n * Card->>Media: isDarkMode()\n * Media-->>Card: Observable<boolean> (isDark)\n * Card->>Card: toggleClass(..., isDark)\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-card',\n templateUrl: './card.component.html',\n styleUrls: ['./card.component.scss'],\n imports: [TranslatePipe, IonCard, IonCardHeader, IonCardContent, IonCardTitle, IonCardSubtitle],\n standalone: true,\n encapsulation: ViewEncapsulation.None,\n})\nexport class CardComponent extends NgxComponentDirective implements OnInit {\n\n /**\n * @description Visual rendering style for the card.\n * @summary Controls the card's surface treatment. Use 'clear' for a flat look or 'shadow' to add elevation.\n * @type {'clear'|'shadow'}\n * @default 'clear'\n */\n @Input()\n type: 'clear' | 'shadow' = 'clear';\n\n /**\n * @description Primary title text for the card header.\n * @summary Rendered prominently at the top of the card; consumers should pass a short, human-friendly string.\n * @type {string}\n * @default ''\n */\n @Input()\n title: string = '';\n\n /**\n * @description Body size preset for the card.\n * @summary Adjusts padding and typographic scale inside the card body. 'small' reduces spacing, 'blank' hides the body area.\n * @type {'small'|'default'|'blank'}\n * @default 'default'\n */\n @Input()\n body: 'small'| 'default' | 'blank' = 'default';\n\n /**\n * @description Optional subtitle shown below the title in the header area.\n * @summary Use for short secondary text such as an explanation or contextual note.\n * @type {string}\n * @default ''\n */\n @Input()\n subtitle: string = '';\n\n /**\n * @description Ionic color token applied to the card.\n * @summary When provided, the color token (for example 'primary' or 'tertiary') is applied to title/header elements where supported.\n * @type {Color}\n * @default ''\n */\n @Input()\n color: Color = '';\n\n /**\n * @description Toggle to render a visual separator between header and content.\n * @summary When true, a divider line (or equivalent styling) is rendered to separate the header from the body.\n * @type {boolean}\n * @default false\n */\n @Input()\n separator: boolean = false;\n\n /**\n * @description Controls whether the card renders borders.\n * @summary Set to false to remove borders for inline or transparent card designs. Marked `override` to explicitly shadow the base directive's value.\n * @type {boolean}\n * @default true\n */\n @Input()\n override borders: boolean = true;\n\n /**\n * @description Inline HTML or SafeHtml content to render inside the card body.\n * @summary Useful for short snippets of rich content provided by the consumer. When passing raw HTML prefer `SafeHtml` to avoid sanitization issues.\n * @type {string|SafeHtml}\n */\n @Input()\n inlineContent?: string | SafeHtml;\n\n /**\n * @description Position where `inlineContent` is rendered within the body.\n * @summary Pass 'top' to render inline content above the body or 'bottom' to render it below. Defaults to 'bottom'.\n * @type {'top'|'bottom'}\n */\n @Input()\n inlineContentPosition: 'top' | 'bottom' = 'bottom';\n\n /**\n * @description Internal component identifier used by the base `NgxComponentDirective`.\n * @summary Read-only-ish string identifying the concrete component class for instrumentation, styling helpers and debug logs.\n * @type {string}\n */\n protected override componentName: string = 'CardComponent';\n\n /**\n * @description Angular lifecycle hook: component initialization.\n * @summary\n * ngOnInit sets the component as initialized and subscribes to the application's media service\n * dark-mode observable. On each emission it updates the local isDarkMode flag and calls the\n * media service helper to toggle the dark-palette CSS class on the component host element.\n * The subscription uses the provided mediaService observable and performs side effects only.\n *\n * @return {void}\n */\n ngOnInit(): void {\n this.mediaService.isDarkMode().subscribe(isDark => {\n this.isDarkMode = isDark;\n this.mediaService.toggleClass(\n [this.component],\n AngularEngineKeys.DARK_PALETTE_CLASS,\n this.isDarkMode\n );\n });\n this.initialize();\n }\n}\n","<ion-card\n [class]=\"'dcf-card ' + className + ' ' + 'dcf-card-' + body\"\n [color]=\"color\"\n mode=\"md\"\n [class.dcf-card-separator]=\"separator\"\n [class.dcf-card-shadow]=\"type === 'shadow'\"\n [class.dcf-card-bordered]=\"borders\"\n [class.dcf-card-separator]=\"separator\"\n #component\n>\n @if (title || subtitle) {\n <ion-card-header>\n @if (title) {\n <ion-card-title>{{\n locale ? (title | translate) : title\n }}</ion-card-title>\n }\n @if (subtitle) {\n <ion-card-subtitle>{{\n locale ? (subtitle | translate) : subtitle\n }}</ion-card-subtitle>\n }\n </ion-card-header>\n }\n <ion-card-content>\n @if (inlineContent && inlineContentPosition === \"top\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n\n <ng-content slot=\"content\"></ng-content>\n\n @if (inlineContent && inlineContentPosition === \"bottom\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n </ion-card-content>\n</ion-card>\n","/**\n * @module module:lib/components/layout/layout.component\n * @description Layout component module.\n * @summary Provides `LayoutComponent` which offers a responsive grid layout\n * for arranging child components using configurable rows, columns and breakpoints.\n * Useful for building responsive UIs that render model and component renderers.\n *\n * @link {@link LayoutComponent}\n */\n\nimport { Component, Input, OnInit} from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Primitives } from '@decaf-ts/decorator-validation';\nimport { UIElementMetadata } from '@decaf-ts/ui-decorators';\nimport { NgxParentComponentDirective } from '../../engine/NgxParentComponentDirective';\nimport { KeyValue } from '../../engine/types';\nimport { IComponentProperties } from '../../engine/interfaces';\nimport { Dynamic } from '../../engine/decorators';\nimport { filterString } from '../../utils/helpers';\nimport { ComponentRendererComponent } from '../component-renderer/component-renderer.component';\nimport { ModelRendererComponent } from '../model-renderer/model-renderer.component';\nimport { LayoutGridGap } from '../../engine/types';\nimport { LayoutGridGaps } from '../../engine/constants';\nimport { CardComponent } from '../card/card.component';\n\n/**\n * @description Layout component for creating responsive grid layouts in Angular applications.\n * @summary This component provides a flexible grid system that can be configured with dynamic\n * rows and columns. It supports responsive breakpoints and can render child components within\n * the grid structure. The component extends NgxParentComponentDirective to inherit common functionality\n * and integrates with the model and component renderer systems.\n *\n * @class LayoutComponent\n * @extends {NgxParentComponentDirective}\n * @implements {OnInit}\n * @memberOf LayoutComponent\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-layout',\n templateUrl: './layout.component.html',\n styleUrls: ['./layout.component.scss'],\n imports: [TranslatePipe, CardComponent, ModelRendererComponent, ComponentRendererComponent],\n standalone: true,\n\n})\nexport class LayoutComponent extends NgxParentComponentDirective implements OnInit {\n\n /**\n * @description Media breakpoint for responsive behavior.\n * @summary Determines the responsive breakpoint at which the layout should adapt.\n * This affects how the grid behaves on different screen sizes, allowing for\n * mobile-first or desktop-first responsive design patterns. The breakpoint\n * is automatically processed to ensure compatibility with the UI framework.\n *\n * @type {UIMediaBreakPointsType}\n * @default 'medium'\n * @memberOf LayoutComponent\n */\n @Input()\n gap: LayoutGridGap = LayoutGridGaps.collapse;\n\n\n /**\n * @description Media breakpoint for responsive behavior.\n * @summary Determines the responsive breakpoint at which the layout should adapt.\n * This affects how the grid behaves on different screen sizes, allowing for\n * mobile-first or desktop-first responsive design patterns. The breakpoint\n * is automatically processed to ensure compatibility with the UI framework.\n *\n * @type {UIMediaBreakPointsType}\n * @default 'medium'\n * @memberOf LayoutComponent\n */\n @Input()\n grid: boolean = true;\n\n /**\n * @description Media breakpoint for responsive behavior.\n * @summary Determines the responsive breakpoint at which the layout should adapt.\n * This affects how the grid behaves on different screen sizes, allowing for\n * mobile-first or desktop-first responsive design patterns. The breakpoint\n * is automatically processed to ensure compatibility with the UI framework.\n *\n * @type {UIMediaBreakPointsType}\n * @default 'medium'\n * @memberOf LayoutComponent\n */\n @Input()\n flexMode: boolean = false;\n\n /**\n * @description Media breakpoint for responsive behavior.\n * @summary Determines the responsive breakpoint at which the layout should adapt.\n * This affects how the grid behaves on different screen sizes, allowing for\n * mobile-first or desktop-first responsive design patterns. The breakpoint\n * is automatically processed to ensure compatibility with the UI framework.\n *\n * @type {UIMediaBreakPointsType}\n * @default 'medium'\n * @memberOf LayoutComponent\n */\n @Input()\n rowCard: boolean = true;\n\n /**\n * @description Maximum number of columns allowed in the grid layout.\n * @summary Specifies the upper limit for the number of columns that can be displayed in the grid.\n * This ensures that the layout remains visually consistent and prevents excessive columns\n * from being rendered, which could disrupt the design.\n *\n * @type {number}\n * @default 6\n * @memberOf LayoutComponent\n */\n @Input()\n private maxColsLength: number = 6;\n\n /**\n * @description Creates an instance of LayoutComponent.\n * @summary Initializes a new LayoutComponent with the component name \"LayoutComponent\".\n * This constructor calls the parent NgxParentComponentDirective constructor to set up base\n * functionality and component identification.\n *\n * @memberOf LayoutComponent\n */\n constructor() {\n super('LayoutComponent')\n }\n\n /**\n * @description Getter that converts columns input to an array format.\n * @summary Transforms the cols input property into a standardized string array format.\n * When cols is a number, it creates an array with that many empty string elements.\n * When cols is already an array, it returns the array as-is. This normalization\n * ensures consistent handling of column definitions in the template.\n *\n * @type {string[]}\n * @readonly\n * @memberOf LayoutComponent\n */\n get _cols(): string[] {\n let cols = this.cols;\n if(typeof cols === Primitives.BOOLEAN) {\n cols = 1;\n this.flexMode = true;\n }\n if (typeof cols === Primitives.NUMBER)\n cols = Array.from({length: Number(cols)}, () => '');\n return cols as string[];\n }\n\n\n /**\n * @description Calculates the number of columns for a given row.\n * @summary Determines the effective number of columns in a row based on the row's column definitions,\n * the total number of columns in the layout, and the maximum allowed columns.\n *\n * @param {KeyValue | IComponentProperties} row - The row object containing column definitions.\n * @returns {number} The number of columns for the row, constrained by the layout's maximum column limit.\n * @memberOf LayoutComponent\n */\n getRowColsLength(row: KeyValue | IComponentProperties): number {\n let length: number = (row.cols as [])?.length ?? 1;\n const colsLength = (this.cols as [])?.length;\n const rowsLength = (typeof this.rows === Primitives.NUMBER ? this.rows : (this.rows as [])?.length) as number;\n if (length > this.maxColsLength)\n length = this.maxColsLength;\n\n if (length !== colsLength) {\n length = colsLength;\n if (this.flexMode) {\n length = row.cols.reduce((acc: number, curr: KeyValue) => {\n if (rowsLength > 1)\n return acc + (typeof curr['col'] === Primitives.NUMBER ? curr['col']: 1);\n return acc + (\n typeof curr['col'] === Primitives.NUMBER ? curr['col']:\n curr['col'] === 'full' ? 0 : curr['col']\n );\n }, 0);\n }\n }\n return length;\n }\n\n /**\n * @description Getter that converts rows input to an array format.\n * @summary Transforms the rows input property into a standardized string array format.\n * When rows is a number, it creates an array with that many empty string elements.\n * When rows is already an array, it returns the array as-is. This normalization\n * ensures consistent handling of row definitions in the template.\n *\n * @type {KeyValue[]}\n * @readonly\n * @memberOf LayoutComponent\n */\n get _rows(): KeyValue[] {\n let rows = this.rows;\n if (typeof rows === Primitives.NUMBER)\n rows = Array.from({length: Number(rows)}, () => ({title: ''})) as Partial<IComponentProperties>[];\n\n let rowsLength = (rows as string[]).length;\n if (rowsLength === 1 && this.flexMode) {\n this.children.forEach((child) => {\n const row = child?.['props'].row || 1;\n if (row > rowsLength) {\n rowsLength += 1;\n (rows as KeyValue[]).push({title: ''});\n }\n });\n\n this.rows = rowsLength;\n };\n return (rows as KeyValue[]).map((row, index) => {\n const rowsLength = this.rows;\n return {\n title: typeof row === Primitives.STRING ? row : row?.['title'] || \"\",\n cols: this.children.filter((child) => {\n let row = (child as UIElementMetadata).props?.['row'] ?? 1;\n if (row > rowsLength)\n row = rowsLength as number;\n child['col'] = (child as UIElementMetadata).props?.['col'] ?? (this.cols as string[])?.length ?? 1;\n if (row === index + 1)\n return child;\n })\n };\n }).map((row, index) => {\n const colsLength = this.getRowColsLength(row);\n row.cols = row.cols.map((c: KeyValue) => {\n let {col} = c;\n if (typeof col === Primitives.STRING)\n col = col === 'half' ? '1-2' : col === 'full' ? '1-1': col;\n\n if (!this.flexMode) {\n if (typeof col === Primitives.NUMBER) {\n col = (col === colsLength ?\n `1-1` : `${col}-${colsLength}`);\n }\n } else {\n\n if (typeof col === Primitives.NUMBER)\n col = (colsLength <= this.maxColsLength) ? `${col}-${colsLength}` : `${index + 1}-${col}`;\n col = ['2-4', '3-6'].includes(col) ? `1-2` : col;\n }\n col = `dcf-child-${col}-${this.breakpoint} dcf-width-${col}`;\n const childClassName = c?.['props']?.className || '';\n const colClass = `${col}@${this.breakpoint} ${filterString(childClassName ,'-width-')}`;\n // to prevent layout glitches, before send class to child component remove width classes\n if (c?.['props']?.className)\n c['props'].className = filterString(c?.['props']?.className ,'-width-', false);\n return Object.assign(c, {colClass});\n })\n return row;\n })\n }\n\n\n\n\n /**\n * @description Angular lifecycle hook that runs after component initialization.\n * @summary Called once, after the first ngOnChanges(). This method triggers the\n * component's initialization process, which includes property parsing and grid\n * setup. It ensures the component is properly configured before rendering.\n *\n * @memberOf LayoutComponent\n */\n override async ngOnInit(): Promise<void> {\n super.parseProps(this);\n\n if (this.breakpoint)\n this.breakpoint = `${this.breakpoint.startsWith('x') ? this.breakpoint.substring(0,2) : this.breakpoint.substring(0,1)}`.toLowerCase();\n this.cols = this._cols;\n this.rows = this._rows;\n // if (this._rows.length === 1)\n // this.match = false;\n // if (this._cols.length === 1)\n // this.grid = false;\n this.initialized = true;\n this.changeDetectorRef.detectChanges();\n }\n}\n","<section class=\"dcf-layout-container\">\n @if (initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n @if (row?.cols?.length) {\n <div\n [id]=\"uid\"\n [class]=\"\n (!grid\n ? 'dcf-layout-row '\n : 'dcf-layout-row dcf-grid ' + 'dcf-grid-' + gap) +\n ' ' +\n (className || '')\n \"\n [class.dcf-grid-match]=\"match\"\n [class.dcf-grid-bordered]=\"borders\"\n >\n @if (row?.title?.length) {\n <div class=\"dcf-width-1-1 dcf-grid-title\">\n <h3 class=\"\">{{ row.title | translate }}</h3>\n </div>\n }\n @for (\n child of row.cols;\n track trackItemFn($index, child.col);\n let colIndex = $index\n ) {\n\n <div\n [class]=\"'dcf-grid-col ' + child.colClass\"\n [class.dcf-first-column]=\"$index === 0\"\n [class.dcf-layout-separator]=\"child.props?.separator ?? false\"\n >\n <div>\n\n @if (child.tag === \"ngx-decaf-crud-form\") {\n\n <ngx-decaf-card\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ngx-decaf-card>\n } @else {\n\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [parentForm]=\"parentForm || child.parentForm || child?.formGroup\"\n [children]=\"child?.children || []\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{ props: child.props }\"\n />\n }\n </div>\n </div>\n }\n </div>\n }\n }\n }\n</section>\n","/**\n * @module module:lib/components/crud-form/crud-form.component\n * @description CRUD form component module.\n * @summary Provides `CrudFormComponent` — a wrapper that composes dynamic form\n * fields and layout to produce create/read/update/delete forms with validation\n * and submission handling.\n *\n * @link {@link CrudFormComponent}\n */\n\nimport {\n Component\n} from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { IonButton, IonIcon } from '@ionic/angular/standalone';\nimport { Dynamic } from '../../engine/decorators';\nimport { DefaultFormReactiveOptions, ComponentEventNames } from '../../engine/constants';\nimport { NgxFormDirective } from '../../engine/NgxFormDirective';\nimport { ComponentRendererComponent } from '../../components/component-renderer/component-renderer.component';\nimport { LayoutComponent } from '../layout/layout.component';\n\n\n@Dynamic()\n@Component({\n standalone: true,\n selector: 'ngx-decaf-crud-form',\n templateUrl: './crud-form.component.html',\n styleUrls: ['./crud-form.component.scss'],\n imports: [ReactiveFormsModule, LayoutComponent, ComponentRendererComponent, IonButton, IonIcon],\n host: {'[attr.id]': 'uid'},\n})\n\nexport class CrudFormComponent extends NgxFormDirective {\n\n constructor() {\n super('CrudFormComponent');\n }\n\n /**\n * @description Component initialization lifecycle method.\n * @summary Initializes the component by setting up the logger, configuring form state\n * based on the operation type, and merging configuration options. For READ and DELETE\n * operations, the formGroup is set to undefined since these operations don't require\n * form input. Configuration options are merged with default settings.\n *\n * @returns {Promise<void>}\n * @memberOf CrudFormComponent\n */\n override async ngOnInit(): Promise<void> {\n this.options = Object.assign(\n {},\n DefaultFormReactiveOptions,\n this.options || {},\n );\n await super.ngOnInit();\n }\n\n /**\n * @description Handles delete operations by emitting delete events.\n * @summary Processes delete requests by emitting a submit event with the\n * record's unique identifier as data. This allows parent components to\n * handle the actual deletion logic while maintaining separation of concerns.\n * The event includes the uid and standard component identification.\n *\n * @returns {void}\n * @memberOf CrudFormComponent\n */\n handleDelete(): void {\n this.submitEvent.emit({\n data: this.modelId,\n component: 'CrudFormComponent',\n name: ComponentEventNames.SUBMIT,\n });\n }\n}\n","@if (operation !== 'read' && operation !== 'delete') {\n <form\n [class]=\"'dcf-form-grid ' + operation\" #component\n [id]=\"rendererId\"\n [formGroup]=\"formGroup\"\n (ngSubmit)=\"handleSubmit($event)\"\n novalidate\n [target]=\"target\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n <ngx-decaf-layout\n [className]=\"'dcf-crud-form-grid dcf-grid-nested '\"\n [children]=\"children || []\"\n [parentForm]=\"formGroup || parentForm\"\n [match]=\"match ?? false\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [cols]=\"cols\" />\n }\n @if (initialized) {\n <div class=\"dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left\">\n <div>\n <ion-button type=\"submit\" [expand]=\"action ? 'block' : 'default'\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{ action ? action : options.buttons.submit.text}}\n </ion-button>\n </div>\n @if (!action) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n Back\n </ion-button>\n </div>\n }\n </div>\n }\n\n </form>\n} @else {\n <section [class]=\"'dcf-grid dcf-grid-small dcf-child-width-1-1 dcf-form-grid ' + operation\" #component [id]=\"uid\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n @for (child of children; track $index) {\n <div class=\"dcf-form-item\">\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n [projectable]=\"false\"\n [children]=\"child?.children || []\"\n [globals]=\"{props: child.props}\"\n />\n </div>\n }\n }\n </section>\n <section [class]=\"'dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if ([OperationKeys.READ, OperationKeys.DELETE].includes(operation) && modelId) {\n <div>\n <ion-button\n (click)=\"handleDelete()\"\n color=\"danger\"\n type=\"button\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n Delete\n </ion-button>\n </div>\n\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n\n <div>\n <ion-button\n type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n </div>\n }\n\n @if (options.buttons.clear) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{ [OperationKeys.DELETE, OperationKeys.READ, OperationKeys.UPDATE].includes(operation) ? 'Back' : options.buttons.clear?.text}}\n </ion-button>\n </div>\n\n }\n </section>\n}\n\n","import { Directive, ElementRef, inject, Input, OnInit } from '@angular/core';\nimport { NgxMediaService } from '../services/NgxMediaService';\nimport { HttpClient } from '@angular/common/http';\n\n@Directive({\n selector: '[ngx-decaf-svg]',\n standalone: true\n})\nexport class NgxSvgDirective implements OnInit {\n\n @Input('ngx-decaf-svg')\n path!: string;\n\n mediaService: NgxMediaService = inject(NgxMediaService);\n element: ElementRef = inject(ElementRef);\n\n http: HttpClient = inject(HttpClient);\n\n ngOnInit(): void {\n this.path = this.path?.trim() || this.element?.nativeElement?.getAttribute('src')?.trim() || '';\n if (this.path)\n this.mediaService.loadSvgObserver(this.http, this.path, this.element.nativeElement);\n }\n}\n","import { Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';\nimport { Color } from '@ionic/core';\nimport { IonButton, IonIcon } from '@ionic/angular/standalone';\nimport * as allIcons from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { Dynamic } from '../../engine/decorators';\nimport { NgxMediaService } from '../../services/NgxMediaService';\nimport { NgxSvgDirective } from '../../directives/NgxSvgDirective';\n\n\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-icon',\n templateUrl: './icon.component.html',\n styleUrls: ['./icon.component.scss'],\n imports: [NgxSvgDirective, IonIcon, IonButton],\n standalone: true,\n host: {'[attr.id]': 'uid', '[attr.aria-hidden]': '!button'},\n})\nexport class IconComponent implements OnInit {\n\n /** @description Reference to the component's native DOM element.\n * @summary Provides direct access to the native DOM element of the component through Angular's\n * ViewChild decorator. This reference can be used to manipulate the DOM element directly,\n * apply custom styles, or access native element properties and methods. The element is\n * identified by the 'component' template reference variable.\n * @type {ElementRef}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @ViewChild('component', { read: ElementRef, static: false })\n component!: ElementRef;\n\n @Input()\n name?: string;\n\n @Input()\n color: Color = \"dark\";\n\n @Input()\n slot?: 'start' | 'end' | 'icon-only' = 'icon-only';\n\n @Input()\n button: boolean = false\n\n @Input()\n buttonFill: 'clear' | 'outline' | 'solid' | 'default' = 'clear';\n\n @Input()\n buttonShape: 'round' | 'default' = 'round';\n\n @Input()\n width!: string;\n\n @Input()\n size?: 'large' | 'small' | 'default' = 'default';\n\n type: 'image' | 'ionic' = 'ionic';\n\n isSvg: boolean = false;\n\n initialized: boolean = false;\n\n @Input()\n inline: boolean = false;\n\n isDarkMode: boolean = false;\n\n mediaService: NgxMediaService = new NgxMediaService();\n\n constructor() {\n addIcons(allIcons);\n }\n\n ngOnInit(): void {\n if(this.button)\n this.slot = 'icon-only';\n if(this.name?.includes('.')) {\n this.type = 'image';\n this.isSvg = this.name.endsWith('.svg');\n }\n this.mediaService.isDarkMode().subscribe(isDark => {\n this.isDarkMode = isDark;\n });\n this.initialized = true;\n }\n}\n","<div class=\"dcf-icon\" #component>\n @if (initialized) {\n @if (button) {\n <ion-button [fill]=\"buttonFill\" [shape]=\"buttonShape\" [color]=\"isDarkMode ? 'light' : color\" [size]=\"size\">\n @if (type === \"image\") {\n @if (isSvg) {\n <span\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [class]=\"color ? 'dcf-color-' + color : ''\"\n [style.width]=\"width\"\n [ngx-decaf-svg]=\"name\"\n >\n ></span\n >\n } @else {\n <img\n aria-hidden=\"true\"\n [alt]=\"name\"\n [title]=\"name\"\n [slot]=\"slot\"\n [src]=\"name\"\n [style.width]=\"width\"\n title=\"icon\"\n />\n }\n } @else {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [ios]=\"name\"\n [md]=\"name\"\n [color]=\"isDarkMode ? 'light' : color\"\n [name]=\"name\"\n />\n }\n </ion-button>\n } @else {\n @if (type === \"image\") {\n @if (isSvg) {\n <span\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [class]=\"color ? 'dcf-color-' + color : ''\"\n [style.width]=\"width\"\n [ngx-decaf-svg]=\"name\"\n >\n </span>\n } @else {\n <img\n aria-hidden=\"true\"\n [alt]=\"name\"\n [title]=\"name\"\n [slot]=\"slot\"\n [src]=\"name\"\n [style.width]=\"width\"\n title=\"icon\"\n />\n }\n }\n @if (type === \"ionic\") {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [ios]=\"name\"\n [md]=\"name\"\n [size]=\"size\"\n [color]=\"isDarkMode ? 'light' : color\"\n [name]=\"name\"\n />\n }\n }\n }\n</div>\n","/**\n * @module module:lib/components/empty-state/empty-state.component\n * @description Empty state component module.\n * @summary Exposes `EmptyStateComponent` which displays a standardized empty\n * state UI with optional icon, title, subtitle and action button. Supports\n * localization and sanitized HTML for dynamic subtitles.\n *\n * @link {@link EmptyStateComponent}\n */\n\nimport { Component, inject, Input, OnInit } from '@angular/core';\nimport { IonButton } from '@ionic/angular/standalone';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Dynamic } from '../../engine/decorators';\nimport { ElementSizes } from '../../engine/constants';\nimport { ElementSize, StringOrBoolean } from '../../engine/types';\nimport { stringToBoolean } from '../../utils/helpers';\nimport { FunctionLike } from '../../engine/types';\nimport { CardComponent } from '../card/card.component';\nimport { IconComponent } from '../../components/icon/icon.component';\n\n\n/**\n * @description Component for displaying empty state messages with optional actions.\n * @summary This component provides a standardized way to display empty state messages\n * when no data is available or when a user needs to take an action to populate content.\n * It includes customizable title, subtitle, icon, and action button elements that can be\n * styled and configured through input properties. The component supports localization\n * and can trigger navigation or custom actions when the button is clicked.\n *\n * @mermaid\n * classDiagram\n * class EmptyStateComponent {\n * +string title\n * +string titleColor\n * +string subtitle\n * +string subtitleColor\n * +StringOrBoolean showIcon\n * +string icon\n * +string iconSize\n * +string iconColor\n * +string|Function buttonLink\n * +string buttonText\n * +string buttonFill\n * +string buttonColor\n * +string buttonSize\n * +string searchValue\n * -Router Router\n * +ngOnInit()\n * +handleClick()\n * }\n * EmptyStateComponent --|> NgxBaseComponentDirective\n * EmptyStateComponent --|> OnInit\n *\n * @extends {NgxBaseComponentDirective}\n * @implements {OnInit}\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-empty-state',\n templateUrl: './empty-state.component.html',\n styleUrls: ['./empty-state.component.scss'],\n standalone: true,\n imports: [\n IconComponent,\n TranslatePipe,\n IonButton,\n CardComponent\n ]\n})\nexport class EmptyStateComponent extends CardComponent implements OnInit {\n\n\n /**\n * @description The main title displayed in the empty state.\n * @summary Specifies the primary message to show in the empty state component.\n * This text is typically used to inform the user about why they're seeing an empty view.\n * If translatable is true, this will be processed through the localization system.\n *\n * @type {string}\n * @default \"title\"\n * @memberOf EmptyStateComponent\n */\n @Input()\n override title: string = \"title\";\n\n /**\n * @description The color of the title text.\n * @summary Specifies the color for the title text using the application's color system.\n * The value should correspond to a color variable defined in the application's theme.\n * The component will automatically prefix this with \"color-\" to create the CSS class.\n *\n * @type {string}\n * @default 'gray-6'\n * @memberOf EmptyStateComponent\n */\n @Input()\n titleColor: string = 'gray-6';\n\n /**\n * @description The secondary message displayed in the empty state.\n * @summary Provides additional context or instructions below the main title.\n * This text is typically used to guide the user on what actions they can take.\n * If translatable is true, this will be processed through the localization system.\n *\n * @type {string | undefined}\n * @memberOf EmptyStateComponent\n */\n @Input()\n override subtitle: string = \"\";\n\n\n /**\n * @description The color of the subtitle text.\n * @summary Specifies the color for the subtitle text using the application's color system.\n * The value should correspond to a color variable defined in the application's theme.\n * The component will automatically prefix this with \"color-\" to create the CSS class.\n *\n * @type {string}\n * @default 'gray-4'\n * @memberOf EmptyStateComponent\n */\n @Input()\n subtitleColor: string = 'gray-4';\n\n /**\n * @description Controls whether the icon is displayed.\n * @summary Determines if the visual icon should be shown in the empty state.\n * This can be provided as a boolean or a string that will be converted to a boolean.\n * Icons help visually communicate the empty state context to users.\n *\n * @type {StringOrBoolean}\n * @default true\n * @memberOf EmptyStateComponent\n */\n @Input()\n showIcon: StringOrBoolean = true;\n\n /**\n * @description The name of the icon to display.\n * @summary Specifies which icon to show when showIcon is true.\n * The component uses the icon system defined in the application,\n * and this value should correspond to an available icon name.\n *\n * @type {string}\n * @default \"folder-open-outline\"\n * @memberOf EmptyStateComponent\n */\n @Input()\n icon: string = \"folder-open-outline\";\n\n /**\n * @description The size of the displayed icon.\n * @summary Controls the size of the icon shown in the empty state.\n * Can be either 'large' or 'small' to accommodate different layout needs.\n *\n * @type {'large' | 'small' | undefined}\n * @default 'large'\n * @memberOf EmptyStateComponent\n */\n @Input()\n iconSize?: Extract<ElementSize, 'large' | 'small'> = ElementSizes.large;\n\n /**\n * @description The color of the displayed icon.\n * @summary Specifies the color for the icon using Ionic's predefined color system.\n * This allows the icon to match the application's color scheme.\n *\n * @type {string}\n * @default 'medium'\n * @memberOf EmptyStateComponent\n */\n @Input()\n iconColor?: string = 'medium';\n\n /**\n * @description The navigation target or action for the button.\n * @summary Specifies where the button should navigate to when clicked or what function\n * it should execute. This can be either a URL string or a function that handles navigation.\n * When not provided, the button will not perform any action.\n *\n * @type {string | FunctionLike | undefined}\n * @memberOf EmptyStateComponent\n */\n @Input()\n buttonLink?: string | FunctionLike;\n\n /**\n * @description The text displayed on the action button.\n * @summary Specifies the label for the action button in the empty state.\n * If translatable is true, this will be processed through the localization system.\n * If not provided, the button will not display any text.\n *\n * @type {string | undefined}\n * @memberOf EmptyStateComponent\n */\n @Input()\n buttonText?: string;\n\n /**\n * @description The fill style of the action button.\n * @summary Controls the visual style of the button using Ionic's button fill options.\n * 'solid' creates a button with a solid background, 'outline' creates a button with\n * just a border, and 'clear' creates a button with no background or border.\n *\n * @type {'clear' | 'solid' | 'outline'}\n * @default 'solid'\n * @memberOf EmptyStateComponent\n */\n @Input()\n buttonFill: 'clear' | 'solid' | 'outline' = 'solid';\n\n /**\n * @description The color of the action button.\n * @summary Specifies the color for the button using Ionic's color system.\n * This allows the button to match the application's color scheme.\n *\n * @type {string}\n * @default 'primary'\n * @memberOf EmptyStateComponent\n */\n @Input()\n buttonColor: string = 'primary';\n\n /**\n * @description The size of the action button.\n * @summary Controls the size of the button shown in the empty state.\n * Can be 'large', 'small', or 'default' to accommodate different layout needs.\n *\n * @type {'large' | 'small' | 'default'}\n * @default 'default'\n * @memberOf EmptyStateComponent\n */\n @Input()\n buttonSize: Extract<ElementSize, 'large' | 'small' | 'default'> = 'default';\n\n /**\n * @description The search value that resulted in no results.\n * @summary When the empty state is shown due to a search with no results,\n * this property can hold the search term that was used. This can be displayed\n * in the empty state message to provide context to the user.\n *\n * @type {string}\n * @memberOf EmptyStateComponent\n */\n @Input()\n searchValue!: string;\n\n\n /**\n * @description Sanitizer instance for bypassing security and sanitizing HTML content.\n * @summary Used to sanitize dynamic HTML content, ensuring it is safe to render in the DOM.\n * @type {DomSanitizer}\n * @memberOf EmptyStateComponent\n */\n private sanitizer: DomSanitizer = inject(DomSanitizer);\n\n /**\n * @description The sanitized subtitle for search results.\n * @summary Holds the processed and sanitized HTML content for the subtitle when a search yields no results.\n * @type {SafeHtml}\n * @memberOf EmptyStateComponent\n */\n searchSubtitle!: SafeHtml;\n\n /**\n * @description Flag to enable creation by model route.\n * @summary Indicates whether the component should allow creation of new items via a model route when no button link is provided.\n * @type {boolean}\n * @default false\n * @memberOf EmptyStateComponent\n */\n enableCreationByModelRoute: boolean = false;\n\n\n /**\n * @description Creates an instance of EmptyStateComponent.\n * @summary Initializes a new EmptyStateComponent by calling the parent class constructor\n * with the component name for logging and identification purposes. This component provides\n * a standardized way to display empty state messages with optional icons and action buttons.\n *\n * @memberOf EmptyStateComponent\n */\n constructor() {\n super(\"EmptyStateComponent\");\n this.type = 'clear';\n this.componentName = \"EmptyStateComponent\";\n this.enableDarkMode = true;\n }\n\n /**\n * @description Initializes the component after Angular first displays the data-bound properties.\n * @summary Sets up the component by processing boolean inputs, applying localization to text\n * elements if translation is enabled, and formatting CSS classes for title and subtitle colors.\n * This method prepares the component for user interaction by ensuring all properties are\n * properly initialized and localized.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant E as EmptyStateComponent\n *\n * A->>E: ngOnInit()\n * E->>E: Process translatable flag\n * E->>E: Process showIcon flag\n * E->>E: Get locale settings\n * alt translatable is true\n * E->>E: Localize title\n * E->>E: Localize subtitle\n * E->>E: Localize buttonText\n * end\n * E->>E: Format title CSS class\n * E->>E: Format subtitle CSS class\n *\n * @return {Promise<void>}\n * @memberOf EmptyStateComponent\n */\n override async ngOnInit(): Promise<void> {\n super.ngOnInit();\n this.showIcon = stringToBoolean(this.showIcon);\n this.titleColor = `dcf-title dcf-color-${this.titleColor}`;\n this.subtitleColor = `dcf-subtitle dcf-color-${this.subtitleColor}`;\n if (this.searchValue)\n this.searchSubtitle = await this.getSearchSubtitle(this.subtitle as string);\n if (!this.buttonLink && this.model && this.route)\n this.enableCreationByModelRoute = true;\n }\n\n /**\n * @description Handles click events on the action button.\n * @summary This method is triggered when the user clicks the action button in the empty state\n * component. It supports three navigation patterns: 1) no action when buttonLink is not provided,\n * 2) custom function execution when buttonLink is a function, and 3) navigation to a specific URL\n * when buttonLink is a string. This flexibility allows the empty state to trigger various actions\n * based on the context in which it's used.\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant E as EmptyStateComponent\n * participant N as Router\n *\n * U->>E: Click action button\n * E->>E: handleClick()\n * alt buttonLink is not provided\n * E-->>U: Return false (no action)\n * else buttonLink is a function\n * E->>E: Execute buttonLink function\n * E-->>U: Return function result\n * else buttonLink is a URL string\n * E->>N: navigateForward(buttonLink)\n * N-->>E: Return navigation result\n * E-->>U: Return navigation result\n * end\n *\n * @return {boolean | void | Promise<boolean> | FunctionLike}\n * - false if no action is taken\n * - The result of the buttonLink function if it's a function\n * - A Promise resolving to the navigation result if buttonLink is a URL\n * @memberOf EmptyStateComponent\n */\n handleClick(): boolean | void | Promise<boolean> | FunctionLike {\n const fn = this.buttonLink;\n if (!fn)\n return false;\n if (fn instanceof Function)\n return fn() as FunctionLike;\n return this.router.navigate([fn as string]);\n }\n\n\n /**\n * @description Generates a localized and sanitized subtitle for search results.\n * @summary This method takes a content string, typically the subtitle, and processes it\n * through the translation service. It replaces a placeholder ('0') with the actual\n * search value, then sanitizes the result to safely use as HTML. This is particularly\n * useful for displaying dynamic, localized messages in the empty state when a search\n * yields no results.\n *\n * @param {string} content - The content string to be translated and processed\n * @return {Promise<SafeHtml>} A promise that resolves to a sanitized HTML string\n *\n * @mermaid\n * sequenceDiagram\n * participant E as EmptyStateComponent\n * participant T as TranslateService\n * participant S as DomSanitizer\n *\n * E->>T: instant(content, {'0': searchValue})\n * T-->>E: Return translated string\n * E->>S: bypassSecurityTrustHtml(translatedString)\n * S-->>E: Return sanitized SafeHtml\n *\n * @memberOf EmptyStateComponent\n */\n async getSearchSubtitle(content: string): Promise<SafeHtml> {\n const result = await this.translate(content, {'0': this.searchValue});\n return this.sanitizer.bypassSecurityTrustHtml(result);\n }\n}\n","<div class=\"decaf-empty-state-component\" #component>\n <ngx-decaf-card [className]=\"className\"\n [borders]=\"borders\"\n [body]=\"body\"\n >\n @if (icon && showIcon) {\n <div class=\"dcf-icon-container\">\n <ngx-decaf-icon\n aria-hidden=\"true\"\n [name]=\"icon\"\n [size]=\"iconSize\"\n [color]=\"!this.isDarkMode ? iconColor : ''\"\n />\n </div>\n }\n @if (title) {\n <h4 class=\"dcf-ititle\" [class]=\"isDarkMode ? 'light' : titleColor\" [innerHTML]=\"title\"></h4>\n }\n @if (subtitle) {\n <p [class]=\"isDarkMode ? 'light' : subtitleColor\" [innerHTML]=\"searchValue ? searchSubtitle : subtitle\"></p>\n }\n @if (!enableCreationByModelRoute) {\n @if (buttonLink && buttonText) {\n <div>\n <ion-button\n [size]=\"buttonSize\"\n [fill]=\"buttonFill\"\n [color]=\"buttonColor\"\n (click)=\"handleClick()\">\n {{ buttonText }}\n </ion-button>\n </div>\n }\n } @else {\n\n <div>\n <ion-button\n class=\"dcf-margin-top\"\n [size]=\"buttonSize\"\n [fill]=\"buttonFill\"\n [color]=\"buttonColor\"\n (click)=\"changeOperation(OperationKeys.CREATE)\" fill=\"clear\">\n {{ buttonText?.length ? buttonText : locale + '.button_create' | translate }}\n </ion-button>\n </div>\n\n }\n </ngx-decaf-card>\n</div>\n","/**\n * @module module:lib/components/fieldset/fieldset.component\n * @description Fieldset component module.\n * @summary Provides `FieldsetComponent` — a dynamic, collapsible fieldset container\n * for grouping form controls with validation, reorder and add/remove capabilities.\n * Ideal for complex forms that require nested groupings and dynamic items.\n *\n * @link {@link FieldsetComponent}\n */\n\nimport {\n AfterViewInit,\n Component,\n Input,\n ViewChild,\n OnInit,\n} from '@angular/core';\nimport {\n FormArray,\n FormControl,\n FormGroup,\n ReactiveFormsModule,\n} from '@angular/forms';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n alertCircleOutline,\n createOutline,\n addOutline,\n trashOutline,\n} from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport {\n IonAccordion,\n IonAccordionGroup,\n IonButton,\n IonItem,\n IonLabel,\n IonList,\n ItemReorderEventDetail,\n IonReorderGroup,\n IonReorder,\n IonIcon,\n IonText,\n} from '@ionic/angular/standalone';\nimport { OperationKeys } from '@decaf-ts/db-decorators';\nimport { ReservedModels } from '@decaf-ts/decorator-validation';\nimport { NgxFormDirective } from '../../engine/NgxFormDirective';\nimport { NgxFormService } from '../../services/NgxFormService';\nimport { LayoutComponent } from '../layout/layout.component';\nimport { FormParent, KeyValue } from '../../engine/types';\nimport {\n IFieldSetItem,\n IFieldSetValidationEvent,\n} from '../../engine/interfaces';\nimport { Dynamic } from '../../engine/decorators';\nimport { itemMapper } from '../../utils/helpers';\nimport { UIModelMetadata } from '@decaf-ts/ui-decorators';\nimport { timer } from 'rxjs';\n\n/**\n * @description Dynamic fieldset component with collapsible accordion functionality.\n * @summary This component provides a sophisticated fieldset container that automatically\n * adapts its behavior based on CRUD operations. It integrates seamlessly with Ionic's\n * accordion components to create expandable/collapsible sections for organizing form\n * content and related information. The component intelligently determines its initial\n * state based on the operation type, opening automatically for READ and DELETE operations\n * while remaining closed for CREATE and UPDATE operations.\n *\n * @example\n * ```html\n * <!-- Basic usage with automatic state management -->\n * <ngx-decaf-fieldset\n * name=\"Personal Information\"\n * [operation]=\"OperationKeys.READ\"\n * target=\"_self\">\n * <ion-input label=\"Name\" placeholder=\"Enter name\"></ion-input>\n * <ion-input label=\"Email\" type=\"email\" placeholder=\"Enter email\"></ion-input>\n * </ngx-decaf-fieldset>\n *\n * <!-- Advanced usage with custom operation -->\n * <ngx-decaf-fieldset\n * name=\"Contact Details\"\n * [operation]=\"currentOperation\"\n * target=\"_blank\">\n * <!-- Complex form fields -->\n * </ngx-decaf-fieldset>\n * ```\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant F as FieldsetComponent\n * participant I as Ionic Accordion\n * participant D as DOM\n *\n * F->>F: ngAfterViewInit()\n * alt operation is READ or DELETE\n * F->>F: Set isOpen = true\n * F->>D: Query accordion element\n * F->>I: Set value attribute to 'open'\n * F->>F: Trigger change detection\n * end\n * U->>I: Click accordion header\n * I->>F: handleChange(event)\n * F->>F: Update isOpen state\n * F->>I: Reflect new state\n *\n * @memberOf FieldsetComponent\n */\n@Dynamic()\n@Component({\n standalone: true,\n selector: 'ngx-decaf-fieldset',\n templateUrl: './fieldset.component.html',\n styleUrls: ['./fieldset.component.scss'],\n schemas: [],\n imports: [\n TranslatePipe,\n ReactiveFormsModule,\n IonAccordionGroup,\n IonAccordion,\n IonList,\n IonItem,\n IonLabel,\n IonText,\n IonReorder,\n IonReorderGroup,\n IonButton,\n IonIcon,\n LayoutComponent,\n ],\n})\nexport class FieldsetComponent\n extends NgxFormDirective\n implements OnInit, AfterViewInit\n{\n /**\n * @description Reference to the ion-accordion-group component for programmatic control.\n * @summary ViewChild reference that provides direct access to the Ionic accordion group component.\n * This enables programmatic control over the accordion's expand/collapse state, allowing\n * the component to open/close the accordion based on validation errors, CRUD operations,\n * or other business logic requirements.\n *\n * @type {IonAccordionGroup}\n * @memberOf FieldsetComponent\n */\n @ViewChild('accordionComponent', { static: false })\n accordionComponent!: IonAccordionGroup;\n\n /**\n * @description The display name or title of the fieldset section.\n * @summary Sets the legend or header text that appears in the accordion header. This text\n * provides a clear label for the collapsible section, helping users understand what content\n * is contained within. The name is displayed prominently and serves as the clickable area\n * for expanding/collapsing the fieldset.\n *\n * @type {string}\n * @default 'Child'\n * @memberOf FieldsetComponent\n */\n @Input()\n formControl!: FormControl;\n\n /**\n * @description The parent component identifier for hierarchical fieldset relationships.\n * @summary Specifies the parent component name that this fieldset belongs to in a hierarchical\n * form structure. This property is used for event bubbling and establishing parent-child\n * relationships between fieldsets in complex forms with nested structures.\n *\n * @type {string}\n * @default 'Child'\n * @memberOf FieldsetComponent\n */\n @Input()\n collapsable: boolean = true;\n\n /**\n * @description Custom type definitions for specialized fieldset behavior.\n * @summary Defines custom data types or validation rules that should be applied to this fieldset.\n * Can be a single type string or array of types that determine how the fieldset handles\n * data validation, formatting, and display behavior for specialized use cases.\n *\n * @type {string | string[]}\n * @memberOf FieldsetComponent\n */\n @Input()\n customTypes!: string | string[];\n\n /**\n * @description Primary title text for the fieldset content.\n * @summary Display title used for fieldset identification and content organization.\n * Provides semantic meaning to the grouped form fields.\n *\n * @type {string}\n * @memberOf FieldsetComponent\n */\n @Input()\n title!: string;\n\n /**\n * @description Secondary descriptive text for the fieldset.\n * @summary Additional information that provides context or instructions\n * related to the fieldset content and purpose.\n *\n * @type {string}\n * @memberOf FieldsetComponent\n */\n @Input()\n description!: string;\n\n /**\n * @description Enables multiple item management within the fieldset.\n * @summary Boolean flag that determines if the fieldset supports adding multiple values.\n * When true, displays a reorderable list of items with add/remove functionality.\n *\n * @type {boolean}\n * @default false\n * @memberOf FieldsetComponent\n */\n @Input()\n multiple: boolean = true;\n\n /**\n * @description Array of raw values stored in the fieldset.\n * @summary Contains the actual data values that have been added to the fieldset.\n * This is the source of truth for the fieldset's data state.\n *\n * @type {KeyValue[]}\n * @default []\n * @memberOf FieldsetComponent\n */\n @Input()\n value: KeyValue[] = [];\n\n /**\n * @description Controls whether borders are displayed around the fieldset.\n * @summary Boolean flag that determines if the fieldset should be visually outlined with borders.\n * When true, borders are shown to visually separate the fieldset from surrounding content.\n *\n * @type {boolean}\n * @default true\n * @memberOf FieldsetComponent\n */\n @Input()\n override borders: boolean = true;\n\n /**\n * @description Array of formatted items for UI display.\n * @summary Contains the processed items ready for display in the component template.\n * These items are mapped from the raw values using the mapper configuration.\n *\n * @type {IFieldSetItem[]}\n * @default []\n * @memberOf FieldsetComponent\n */\n items: IFieldSetItem[] = [];\n\n /**\n * @description Currently selected item for update operations.\n * @summary Holds the item being edited when in update mode. Used to track\n * which item is being modified and apply changes to the correct item.\n *\n * @type {IFieldSetItem | undefined}\n * @memberOf FieldsetComponent\n */\n updatingItem!: IFieldSetItem | undefined;\n\n /**\n * @description Current state of the accordion (expanded or collapsed).\n * @summary Boolean flag that tracks whether the fieldset accordion is currently open or closed.\n * This property is automatically managed based on user interactions and initial operation state.\n * It serves as the single source of truth for the component's visibility state and is used\n * to coordinate between user actions and programmatic state changes. The value is automatically\n * set based on CRUD operations during initialization and updated through user interactions.\n *\n * @type {boolean}\n * @default false\n * @memberOf FieldsetComponent\n */\n isOpen: boolean = false;\n\n /**\n * @description Indicates whether the fieldset contains required form fields.\n * @summary Boolean flag that signals the presence of mandatory input fields within the fieldset.\n * This property is automatically set by the CollapsableDirective when required fields are detected,\n * and can be used to apply special styling, validation logic, or UI indicators to highlight\n * fieldsets that contain mandatory information. It helps with form validation feedback and\n * user experience by making required sections more prominent.\n *\n * @type {boolean}\n * @default false\n * @memberOf FieldsetComponent\n */\n isRequired: boolean = false;\n\n /**\n * @description Indicates whether the fieldset contains validation errors.\n * @summary Boolean flag that tracks if any form fields within the fieldset have validation errors.\n * This property is used to control accordion behavior when errors are present, preventing\n * users from collapsing the accordion when they need to see and address validation issues.\n * It's automatically updated when validation error events are received from child form fields.\n *\n * @type {boolean}\n * @default false\n * @memberOf FieldsetComponent\n */\n hasValidationErrors: boolean = false;\n\n /**\n * @description Validation error message for duplicate values.\n * @summary Stores the error message when a user attempts to add a duplicate value\n * to the fieldset. Used to display uniqueness validation feedback.\n *\n * @type {string | undefined}\n * @memberOf FieldsetComponent\n */\n isUniqueError: string | undefined = undefined;\n\n /**\n * @description Localized label text for action buttons.\n * @summary Dynamic button label that changes based on the current operation mode.\n * Shows \"Add\" for create operations and \"Update\" for edit operations.\n *\n * @type {string}\n * @memberOf FieldsetComponent\n */\n buttonLabel!: string;\n\n /**\n * @description Localized label text for action buttons.\n * @summary Dynamic button label that changes based on the current operation mode.\n * Shows \"Cancel\" for update operations\n *\n * @type {string}\n * @memberOf FieldsetComponent\n */\n buttonCancelLabel!: string;\n\n /**\n * @description Maximum allowed items in the fieldset.\n * @summary Numeric limit that controls how many items can be added when `multiple` is true.\n * When set to Infinity there is no limit.\n *\n * @type {number}\n * @default Infinity\n * @memberOf FieldsetComponent\n */\n @Input()\n max: number | undefined = undefined;\n\n /**\n * @description Maximum allowed items in the fieldset.\n * @summary Numeric limit that controls how many items can be added when `multiple` is true.\n * When set to Infinity there is no limit.\n *\n * @type {number}\n * @default Infinity\n * @memberOf FieldsetComponent\n */\n @Input()\n required: boolean = false;\n\n /**\n * @description Determines if the fieldset items can be reordered.\n * @summary Boolean flag that enables or disables the drag-and-drop reordering functionality\n * for the items within the fieldset. When set to true, users can rearrange the order\n * of items using drag-and-drop gestures. This is particularly useful for managing\n * lists where the order of items is significant.\n *\n * @type {boolean}\n * @default true\n * @memberOf FieldsetComponent\n */\n @Input()\n ordenable: boolean = true;\n\n /**\n * @description Determines if the fieldset items can be edited by the user.\n * @summary Boolean flag that enables or disables the editing functionality\n * for the items within the fieldset. When set to true, users can modify the items.\n *\n * @type {boolean}\n * @default true\n * @memberOf FieldsetComponent\n * @default true\n */\n @Input()\n editable: boolean = true;\n\n /**\n * @description Component constructor that initializes the fieldset with icons and component name.\n * @summary Calls the parent NgxFormDirective constructor with the component name and\n * required Ionic icons (alertCircleOutline for validation errors and createOutline for add actions).\n * Sets up the foundational component structure and icon registry.\n *\n * @memberOf FieldsetComponent\n */\n constructor() {\n super('FieldsetComponent');\n addIcons({ alertCircleOutline, addOutline, trashOutline, createOutline });\n }\n\n /**\n * @description Component initialization lifecycle method.\n * @summary Initializes the component by setting up repository relationships if a model exists,\n * and configures the initial button label for the add action based on the current locale.\n * This method ensures proper setup of translation services and component state.\n *\n * @returns {void}\n * @memberOf FieldsetComponent\n */\n override async ngOnInit(): Promise<void> {\n await super.ngOnInit(this.model);\n if (this.max && this.max === 1) this.multiple = false;\n this.buttonLabel = this.translateService.instant(this.locale + '.add');\n this.buttonCancelLabel = this.translateService.instant(\n this.locale + '.cancel'\n );\n\n if (!this.multiple) this.ordenable = false;\n\n if ([OperationKeys.CREATE, OperationKeys.UPDATE].includes(this.operation)) {\n if (!this.formGroup) {\n if (this.parentForm instanceof FormGroup) {\n // iterate on childOf path to get correct formGroup\n const parts = (this.childOf as string).split('.');\n let formGroup = this.parentForm as FormParent;\n for (const part of parts)\n formGroup = (formGroup as FormGroup).controls[part] as FormParent;\n this.formGroup = formGroup;\n if (this.formGroup instanceof FormGroup)\n this.formGroup = this.formGroup.parent as FormArray;\n }\n if (!this.formGroup && this.parentForm instanceof FormArray)\n this.formGroup = this.parentForm;\n if (\n !this.formGroup &&\n (this.children[0] as KeyValue)?.['formGroup'] instanceof FormGroup\n )\n this.formGroup = (this.children[0] as KeyValue)?.['formGroup']\n .parent as FormArray;\n if (this.formGroup && !(this.formGroup instanceof FormArray))\n this.formGroup = (this.formGroup as FormParent)?.parent as FormArray;\n }\n }\n if (this.multiple) {\n this.formGroup?.setErrors(null);\n this.formGroup?.disable();\n if (this.required) {\n this.collapsable = false;\n this.activePage = this.getActivePage();\n }\n } else {\n this.activePage = this.getActivePage();\n }\n this.initialized = true;\n }\n\n /**\n * @description Initializes the component state after view and child components are rendered.\n * @summary This lifecycle hook implements intelligent auto-state management based on the current\n * CRUD operation. For READ and DELETE operations, the fieldset automatically opens to provide\n * immediate access to information, while CREATE and UPDATE operations keep it closed to maintain\n * a clean initial interface. The method directly manipulates the DOM to ensure proper accordion\n * synchronization and triggers change detection to reflect the programmatic state changes.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant F as FieldsetComponent\n * participant D as DOM\n * participant C as ChangeDetector\n *\n * A->>F: ngAfterViewInit()\n * alt operation is READ or DELETE\n * F->>F: Set isOpen = true\n * F->>D: Query ion-accordion-group element\n * alt accordion element exists\n * F->>D: Set value attribute to 'open'\n * end\n * end\n * F->>C: detectChanges()\n * C->>F: Update view with new state\n *\n * @returns {Promise<void>}\n * @memberOf FieldsetComponent\n */\n override async ngAfterViewInit(): Promise<void> {\n await super.ngAfterViewInit();\n // if (!this.collapsable)\n // this.isOpen = true;\n // if (this.operation === OperationKeys.READ || this.operation === OperationKeys.DELETE) {\n // this.isOpen = true;\n // // hidden remove button\n // const accordionElement = this.component?.nativeElement.querySelector('ion-accordion-group');\n // if (accordionElement)\n // this.renderer.setAttribute(accordionElement, 'value', 'open');\n // } else {\n // const inputs = this.component?.nativeElement.querySelectorAll('.dcf-field-required');\n // this.isRequired = inputs?.length > 0;\n // if (this.isRequired) {\n // this.accordionComponent.value = 'open';\n // this.handleAccordionToggle();\n // }\n // }\n // if (!(this.formGroup instanceof FormArray))\n // this.formGroup = (this.formGroup as FormGroup)\n // this.changeDetectorRef.detectChanges();\n }\n\n /**\n * @description Handles removal of the fieldset with slide animation.\n * @summary Initiates the removal process for the fieldset with a smooth slide-up animation.\n * The method applies CSS classes for the slide animation and then safely removes the\n * element from the DOM using Renderer2. This provides a polished user experience\n * when removing fieldset instances from dynamic forms.\n *\n * @param {Event} event - DOM event from the remove button click\n * @returns {void}\n * @memberOf FieldsetComponent\n */\n handleClear(event?: Event): void {\n if (event) event.stopImmediatePropagation();\n this.formGroup?.disable();\n this.items = [];\n this.value = undefined as unknown as KeyValue[];\n this.activePage = undefined;\n this.activeFormGroupIndex = 0;\n this.accordionComponent.value = '';\n this.changeDetectorRef.detectChanges();\n\n // this.component.nativeElement.classList.add('dcf-animation', 'dcf-animation-slide-top-medium', 'dcf-animation-reverse', 'dcf-animation-fast');\n // setTimeout(() => {\n // // Use Renderer2 to safely remove the element\n // const parent = this.renderer.parentNode(this.component.nativeElement);\n // if (parent)\n // this.renderer.removeChild(parent, this.component.nativeElement);\n // }, 150);\n }\n\n /**\n * @description Handles creating new items or triggering group addition events.\n * @summary Processes form validation events for item creation or emits events to trigger\n * the addition of new fieldset groups. When called with validation event data, it validates\n * uniqueness and adds the item to the fieldset. When called without parameters, it triggers\n * a group addition event for parent components to handle.\n *\n * @param {CustomEvent<IFieldSetValidationEvent>} [event] - Optional validation event containing form data\n * @returns {Promise<void>}\n * @memberOf FieldsetComponent\n *\n * @example\n * ```typescript\n * // Called from form validation\n * handleCreateItem(validationEvent);\n *\n * // Called to trigger group addition\n * handleCreateItem();\n * ```\n */\n async handleCreateItem(\n event?: CustomEvent<IFieldSetValidationEvent>\n ): Promise<void | boolean> {\n if (event && event instanceof CustomEvent) event.stopImmediatePropagation();\n if (!this.activePage) {\n this.activePage = this.getActivePage();\n return;\n }\n const formGroup = this.activeFormGroup as FormGroup;\n const value = formGroup.value;\n const hasSomeValue = this.hasValue(value);\n\n if (hasSomeValue) {\n const action = this.updatingItem\n ? OperationKeys.UPDATE\n : OperationKeys.CREATE;\n const isValid = NgxFormService.validateFields(formGroup);\n\n // must pass correct pk here\n const isUnique = NgxFormService.isUniqueOnGroup(\n formGroup,\n action,\n action === OperationKeys.UPDATE ? this.updatingItem?.index : undefined\n );\n if (isValid) {\n this.mapper = this.getMapper(value as KeyValue);\n if (isUnique) {\n this.isUniqueError = this.updatingItem = undefined;\n this.setValue();\n NgxFormService.addGroupToParent(formGroup.parent as FormArray);\n this.activeFormGroupIndex =\n (formGroup.parent as FormArray).length - 1;\n this.activePage = this.getActivePage();\n } else {\n this.isUniqueError =\n typeof value === ReservedModels.OBJECT.name.toLowerCase()\n ? (value as KeyValue)?.[this.pk] || undefined\n : value;\n }\n }\n }\n }\n\n hasValue(value: KeyValue = {}): boolean {\n return Object.keys(value).some(\n (key) =>\n value[key] !== null && value[key] !== undefined && value[key] !== ''\n );\n }\n\n handleUpdateItem(index: number): void {\n const formGroup = this.getFormArrayIndex(index);\n if (formGroup) {\n this.updatingItem = Object.assign({}, formGroup.value || {}, { index });\n this.activeFormGroupIndex = index;\n this.activePage = this.getActivePage();\n }\n }\n\n /**\n * @description Cancels the update mode and resets the UI state.\n * @summary Exits the update mode by resetting the button label and clearing the updating item,\n * restoring the component to its default state for adding new items. Notifies parent components\n * that the update operation has been cancelled.\n *\n * @returns {void}\n * @memberOf FieldsetComponent\n */\n handleCancelUpdateItem(): void {\n this.buttonLabel = this.translateService.instant(this.locale + '.add');\n this.updatingItem = undefined;\n this.activeFormGroupIndex = (this.formGroup as FormArray)?.length - 1;\n this.getFormArrayIndex(this.activeFormGroupIndex);\n }\n\n /**\n * @description Handles item removal operations with form array management.\n * @summary Processes item removal by either handling validation events or removing specific\n * items from the form array. When called with a validation event, it triggers value updates.\n * When called with an identifier, it locates and removes the matching item from the form array.\n *\n * @param {string | undefined} value - The identifier of the item to remove\n * @param {CustomEvent} [event] - Optional validation event for form updates\n * @returns {void}\n * @memberOf FieldsetComponent\n */\n handleRemoveItem(index: number): void {\n const formArray = this.formGroup as FormArray;\n if (formArray.length === 1) {\n const currentGroup = formArray.at(0) as FormGroup;\n Object.keys(currentGroup?.controls).forEach((controlName) => {\n currentGroup.get(controlName)?.setValue(null);\n });\n } else {\n formArray.removeAt(index);\n }\n this.setValue();\n if (this.items.length > 0) {\n if (this.activeFormGroupIndex > 0)\n this.activeFormGroupIndex = this.activeFormGroupIndex - 1;\n } else {\n this.handleClear();\n }\n }\n\n /**\n * @description Handles reordering of items within the fieldset list.\n * @summary Processes drag-and-drop reorder events from the ion-reorder-group component.\n * Updates both the display items array and the underlying value array to maintain\n * consistency between UI state and data state. Preserves item indices after reordering.\n *\n * @param {CustomEvent<ItemReorderEventDetail>} event - Ionic reorder event containing source and target indices\n * @returns {void}\n * @memberOf FieldsetComponent\n *\n * @example\n * ```html\n * <ion-reorder-group (ionItemReorder)=\"handleReorder($event)\">\n * <!-- Reorderable items -->\n * </ion-reorder-group>\n * ```\n */\n handleReorderItems(event: CustomEvent<ItemReorderEventDetail>): void {\n const fromIndex = event.detail.from;\n const toIndex = event.detail.to;\n\n const items = [...this.items]; // visual data\n const formArray = this.formGroup as FormArray; // FormArray\n\n if (fromIndex !== toIndex) {\n this.items = [];\n // reorder visual data\n const itemToMove = items.splice(fromIndex, 1)[0];\n items.splice(toIndex, 0, itemToMove);\n items.forEach((item, index) => (item['index'] = index + 1));\n\n // reorder FormArray controls\n const controlToMove = formArray.at(fromIndex);\n formArray.removeAt(fromIndex);\n formArray.insert(toIndex, controlToMove);\n }\n this.items = [...items];\n event.detail.complete();\n }\n\n /**\n * @description Handles accordion state change events from user interactions.\n * @summary Processes CustomEvent objects triggered when users expand or collapse the accordion.\n * This method extracts the new state from the event details and updates the component's\n * internal state accordingly. It specifically listens for ION-ACCORDION-GROUP events to\n * ensure proper event source validation and prevent handling of unrelated events.\n *\n * @param {CustomEvent} event - The event object containing accordion state change details\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant I as Ion-Accordion\n * participant F as FieldsetComponent\n *\n * U->>I: Click accordion header\n * I->>F: handleChange(CustomEvent)\n * F->>F: Extract target and detail from event\n * F->>F: Validate target is ION-ACCORDION-GROUP\n * alt valid target\n * F->>F: Update isOpen = !!value\n * end\n * F->>I: Reflect updated state\n *\n * @memberOf FieldsetComponent\n */\n\n /**\n * @description Handles accordion toggle functionality with validation error consideration.\n * @summary Manages the expand/collapse state of the accordion while respecting validation error states.\n * When validation errors are present, the accordion cannot be collapsed to ensure users can see\n * and address the errors. When no errors exist, users can freely toggle the accordion state.\n * This method also stops event propagation to prevent unwanted side effects.\n *\n * @param {CustomEvent} [event] - Optional event object from user interaction\n * @returns {void}\n * @memberOf FieldsetComponent\n */\n handleAccordionToggle(event?: CustomEvent): void {\n if (event) event.stopImmediatePropagation();\n\n if (!this.collapsable || this.isRequired) {\n this.isOpen = true;\n } else {\n if (!this.hasValidationErrors) {\n this.accordionComponent.value = this.isOpen ? undefined : 'open';\n this.isOpen = !!this.accordionComponent.value;\n }\n }\n }\n\n /**\n * @description Handles validation error events from child form fields.\n * @summary Processes validation error events dispatched by form fields within the fieldset.\n * When errors are detected, the accordion is forced open and prevented from collapsing\n * to ensure users can see the validation messages. This method updates the component's\n * error state and accordion visibility accordingly.\n *\n * @param {CustomEvent} event - Custom event containing validation error details\n * @returns {UIModelMetadata[] | undefined}\n * @memberOf FieldsetComponent\n */\n // handleValidationError(event: CustomEvent): void {\n // event.stopImmediatePropagation();\n // const {hasErrors} = event.detail;\n // this.isOpen = this.hasValidationErrors = hasErrors;\n // if (hasErrors)\n // this.accordionComponent.value = 'open';\n // }\n\n protected override getActivePage(): UIModelMetadata[] | undefined {\n this.activePage = undefined;\n this.isOpen = true;\n this.accordionComponent.value = 'open';\n this.changeDetectorRef.detectChanges();\n this.timerSubscription = timer(10).subscribe(() => {\n this.children = this.children.map((child) => {\n if (!child.props) child.props = {};\n child.props = Object.assign(child.props, {\n activeFormGroup: this.activeFormGroupIndex,\n multiple: this.multiple,\n });\n return child;\n });\n });\n if (this.multiple) this.getFormArrayIndex(this.activeFormGroupIndex);\n return this.children as UIModelMetadata[];\n }\n\n /**\n * @description Processes and stores a new or updated value in the fieldset.\n * @summary Handles both create and update operations for fieldset items. Parses and cleans\n * the input value, determines the operation type based on the updating state, and either\n * adds a new item or updates an existing one. Maintains data integrity and UI consistency.\n *\n * @returns {void}\n * @private\n * @memberOf FieldsetComponent\n */\n private setValue(): void {\n this.value = (this.formGroup as FormArray).controls.map(\n ({ value }) => value\n );\n this.items = this.value\n .filter((v) => (v[this.pk] || '').trim().length)\n .map((v, index) => {\n return {\n ...itemMapper(Object.assign({}, v), this.mapper),\n index: index + 1,\n } as IFieldSetItem;\n });\n\n this.updatingItem = undefined;\n }\n\n /**\n * @description Automatically configures the field mapping based on the value structure.\n * @summary Analyzes the provided value object to automatically determine the primary key\n * and create appropriate field mappings for display purposes. Sets up the mapper object\n * with title, description, and index fields based on the available data structure.\n *\n * @param {KeyValue} value - Sample value object used to determine field mappings\n * @returns {KeyValue} The configured mapper object\n * @private\n * @memberOf FieldsetComponent\n */\n private getMapper(value: KeyValue): KeyValue {\n if (!this.pk) this.pk = Object.keys(value)[0];\n if (!Object.keys(this.mapper).length)\n (this.mapper as KeyValue)['title'] = this.pk;\n (this.mapper as KeyValue)['index'] = 'index';\n for (const key in value) {\n if (\n Object.keys(this.mapper).length >= 2 ||\n Object.keys(this.mapper).length === Object.keys(value).length\n )\n break;\n if (!(this.mapper as KeyValue)['title']) {\n (this.mapper as KeyValue)['title'] = key;\n } else {\n (this.mapper as KeyValue)['description'] = key;\n }\n }\n return this.mapper;\n }\n}\n","\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.open]=\"isOpen\"\n [class.dcf-not-collapsable]=\"!collapsable\"\n #component>\n <div class=\"dcf-width-1-1\">\n @if (!collapsable || required) {\n <legend class=\"dcf-title\">{{ (title ? title : name) | translate }}</legend>\n }\n <ion-accordion-group class=\"dcf-width-1-1\" [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" [value]=\"(operation === 'read' || !collapsable) ? 'open' : ''\" #accordionComponent>\n <ion-accordion\n value=\"open\"\n [class.dcf-disabled]=\"!activePage\"\n [class.dcf-empty]=\"!items?.length\"\n >\n @if (collapsable && !required) {\n <ion-item slot=\"header\" [button]=\"collapsable\" (click)=\"handleAccordionToggle($event)\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-width-1-1\">\n <div class=\"dcf-width-expand\">\n <legend>{{ (title ? title : name) | translate }}</legend>\n </div>\n @if (!isRequired && ['create', 'update'].includes(operation) && collapsable && multiple) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleClear($event)\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n </div>\n </ion-item>\n }\n\n <div slot=\"content\" [attr.aria-hidden]=\"!isOpen\">\n @if (activePage) {\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested'\"\n [flexMode]=\"props.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [children]=\"activePage || []\"\n [parentForm]=\"formGroup || parentForm\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [borders]=\"activePage?.borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [hidden]=\"items.length === max && !updatingItem\"\n />\n </div>\n }\n </div>\n </ion-accordion>\n </ion-accordion-group>\n\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group [formGroup]=\"formGroup.parent\" [disabled]=\"updatingItem\" (ionItemReorder)=\"handleReorderItems($any($event))\" #accordionComponent>\n @for(item of items; track item.index) {\n <ion-item [class.not-unique]=\"item.title === isUniqueError\" [class.updating]=\"updatingItem?.[pk] === item.title\" lines=\"full\" [button]=\"false\">\n @if(ordenable) {\n @if (items?.length > 1 && !updatingItem) {\n <ion-reorder slot=\"start\">\n <ion-icon aria-hidden=\"true\" name=\"swap-vertical-outline\"></ion-icon>\n </ion-reorder>\n } @else {\n <div slot=\"start\">\n <ion-icon aria-hidden=\"true\" class=\"dcf-reorder-disabled\" size=\"small\" name=\"swap-vertical-outline\" disabled></ion-icon>\n </div>\n }\n }\n\n <ion-label [color]=\"(item.title === isUniqueError && !updatingItem?.[pk] === item.title) ? 'danger' : ''\">{{ item.index }}. {{ item.title }}\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{item.description}}</ion-text>\n }\n </ion-label>\n\n @if(editable) {\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleUpdateItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"create-outline\" color=\"dark\" ></ion-icon>\n </ion-button>\n }\n }\n\n\n @if (!updatingItem) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleRemoveItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"close-outline\" color=\"dark\"></ion-icon>\n </ion-button>\n }\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (isUniqueError) {\n <div class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\">\n <div class=\" dcf-grid dcf-grid-collapse dcf-width-1-1 \">\n <div class=\"dcf-auto\" [attr.style]=\"'max-width: 50px'\">\n <ion-icon aria-hidden=\"true\" name=\"alert-circle-outline\"></ion-icon>\n </div>\n <div class=\"dcf-width-expand\">\n <ion-text color=\"danger\" class=\"dcf-text-small\">{{ locale + '.not_unique' | translate : { value: isUniqueError } }}</ion-text>\n </div>\n </div>\n </div>\n }\n @if(max) {\n <div class=\"dcf-width-1-1 dcf-max-message-container\">\n <ion-text class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{ locale + (items.length !== max ? '.max_items' : '.max_items_reached') | translate : { '0': max } }}\n </ion-text>\n </div>\n }\n\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\" [class.dcf-not-collapsable]=\"!collapsable\" [class.dcf-empty]=\"!activePage\" [class.dcf-blank]=\"!borders\">\n @if (updatingItem) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ locale + '.cancel' | translate }}\n </ion-button>\n </div>\n <div>\n <ion-button size=\"small\" fill=\"clear\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update' | translate }}\n </ion-button>\n </div>\n } @else {\n\n @if (items.length < max || !max) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" [color]=\"isDarkMode ? 'light' : 'dark'\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"add-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.add' | translate }}\n </ion-button>\n </div>\n }\n }\n </div>\n }\n </div>\n</fieldset>\n\n","/**\n * @module module:lib/components/searchbar/searchbar.component\n * @description Searchbar component module.\n * @summary Exposes `SearchbarComponent` providing a configurable search input with\n * debouncing, clear/cancel handling and optional global window events. Use this\n * component to add search UI across lists and pages.\n *\n * @link {@link SearchbarComponent}\n */\n\nimport { Component, EventEmitter, HostListener, Input, OnInit, Output } from '@angular/core';\nimport { IonSearchbar } from '@ionic/angular/standalone';\nimport * as allIcons from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { AutocompleteTypes, PredefinedColors} from '@ionic/core';\nimport { NgxComponentDirective } from '../../engine/NgxComponentDirective';\nimport { StringOrBoolean } from '../../engine/types';\nimport {windowEventEmitter} from '../../utils/helpers';\nimport { stringToBoolean } from '../../utils/helpers';\n\n\n/**\n * @description Searchbar component for Angular applications.\n * @summary The SearchbarComponent provides a highly customizable search input field with comprehensive\n * options for appearance, behavior, and interaction patterns. It extends NgxBaseComponentDirective to inherit\n * common functionality and implements OnInit for proper lifecycle management. This component features\n * debounced input handling, window event integration, visibility controls, and extensive styling options.\n * It's designed to be flexible and adaptable to different search requirements within modern web applications.\n *\n * @class SearchbarComponent\n * @extends {NgxBaseComponentDirective}\n * @implements {OnInit}\n * @memberOf SearchbarComponent\n */\n@Component({\n selector: 'ngx-decaf-searchbar',\n templateUrl: './searchbar.component.html',\n styleUrls: ['./searchbar.component.scss'],\n standalone: true,\n imports: [IonSearchbar],\n})\nexport class SearchbarComponent extends NgxComponentDirective implements OnInit {\n\n /**\n * @description The mode of the searchbar.\n * @summary Determines the visual style of the searchbar, either iOS or Material Design.\n * @type {\"ios\" | \"md\" | undefined}\n * @default \"ios\"\n */\n // @Input()\n // override mode: \"ios\" | \"md\" | undefined = \"md\";\n\n /**\n * @description The autocomplete attribute for the searchbar input.\n * @summary Specifies whether the browser should enable autocomplete for the input field.\n * This controls the browser's built-in autocomplete functionality, helping users by\n * suggesting previously entered values or common inputs. Setting to 'off' disables\n * this feature for privacy or security reasons.\n *\n * @type {AutocompleteTypes | undefined}\n * @default \"off\"\n * @memberOf SearchbarComponent\n */\n @Input()\n autocomplete: AutocompleteTypes | undefined = \"off\";\n\n /**\n * @description The autocorrect attribute for the searchbar input.\n * @summary Controls whether the browser should enable autocorrect functionality for the input field.\n * When enabled, the browser will automatically correct spelling mistakes as the user types.\n * This is typically disabled for search fields to preserve the user's exact search terms.\n *\n * @type {\"on\" | \"off\"}\n * @default \"off\"\n * @memberOf SearchbarComponent\n */\n @Input()\n autocorrect: \"on\" | \"off\" = \"off\";\n\n /**\n * @description Whether the searchbar should animate.\n * @summary Controls the animation behavior of the searchbar during appearance and disappearance transitions.\n * When enabled, the searchbar will use smooth animations for state changes, providing a more\n * polished user experience. This affects transitions like showing/hiding the component.\n *\n * @type {StringOrBoolean}\n * @default true\n * @memberOf SearchbarComponent\n */\n @Input()\n animated: StringOrBoolean = true;\n\n /**\n * @description The text for the cancel button.\n * @summary Specifies the localized text to be displayed on the cancel button of the searchbar.\n * This text appears when the cancel button is visible and provides users with a clear\n * indication of how to dismiss the search interface. The text can be customized for\n * different languages and cultural contexts.\n *\n * @type {string}\n * @default \"Cancel\"\n * @memberOf SearchbarComponent\n */\n @Input()\n buttonCancelText: string = \"Cancel\";\n\n /**\n * @description The icon to use for the clear button.\n * @summary Specifies the icon to be displayed for the clear button of the searchbar.\n * @type {string | undefined}\n * @default undefined\n * @memberOf SearchbarComponent\n */\n @Input()\n clearIcon: string | undefined = undefined;\n\n /**\n * @description The color of the searchbar.\n * @summary Specifies the color theme to be applied to the searchbar.\n * @type {string | undefined}\n * @default undefined\n * @memberOf SearchbarComponent\n */\n @Input()\n color: string | undefined = undefined;\n\n /**\n * @description The amount of time, in milliseconds, to wait to trigger the `ionChange` event after each keystroke.\n * @summary Controls the debounce time for the search input to reduce the frequency of event emissions.\n * @type {number}\n * @default 500\n * @memberOf SearchbarComponent\n */\n @Input()\n debounce: number = 500;\n\n /**\n * @description Whether the searchbar is disabled.\n * @summary Controls whether the searchbar is interactive or not.\n * @type {StringOrBoolean}\n * @default false\n * @memberOf SearchbarComponent\n */\n @Input()\n disabled: StringOrBoolean = false;\n\n /**\n * @description A hint to the browser for which enter key to display.\n * @summary Specifies the type of action that will be performed when the enter key is pressed.\n * @type {\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined}\n * @default \"enter\"\n * @memberOf SearchbarComponent\n */\n @Input()\n enterkeyhint: \"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined = \"enter\";\n\n /**\n * @description The input mode for the searchbar.\n * @summary Specifies the type of data that might be entered by the user while editing the element or its contents.\n * @type {\"text\" | \"search\" | \"none\" | \"email\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined}\n * @default 'search'\n * @memberOf SearchbarComponent\n */\n @Input()\n inputmode: \"text\" | \"search\" | \"none\" | \"email\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined = 'search';\n\n /**\n * @description The placeholder for the searchbar input.\n * @summary Specifies the placeholder text to be displayed in the searchbar when it's empty.\n * @type {string}\n * @default \"Search\"\n * @memberOf SearchbarComponent\n */\n @Input()\n placeholder = \"Search\";\n\n /**\n * @description The icon to use for the search button.\n * @summary Specifies the icon to be displayed for the search button of the searchbar.\n * @type {string | undefined}\n * @default \"search-outline\"\n * @memberOf SearchbarComponent\n */\n @Input()\n searchIcon: string | undefined = \"search-outline\";\n\n /**\n * @description When to show the cancel button.\n * @summary Controls the visibility of the cancel button in different states of the searchbar.\n * @type {\"always\" | \"focus\" | \"never\"}\n * @default \"never\"\n * @memberOf SearchbarComponent\n */\n @Input()\n showCancelButton: \"always\" | \"focus\" | \"never\" = \"never\";\n\n /**\n * @description When to show the clear button.\n * @summary Controls the visibility of the clear button in different states of the searchbar.\n * @type {\"always\" | \"focus\" | \"never\"}\n * @default \"focus\"\n * @memberOf SearchbarComponent\n */\n @Input()\n showClearButton: \"always\" | \"focus\" | \"never\" = \"focus\";\n\n /**\n * @description Whether to enable spellcheck on the searchbar input.\n * @summary Controls whether the browser's spellcheck feature is enabled for the searchbar input.\n * @type {boolean}\n * @default false\n * @memberOf SearchbarComponent\n */\n @Input()\n spellcheck: boolean = false;\n\n /**\n * @description The type of input to use for the searchbar.\n * @summary Specifies the type of control to display for the searchbar input.\n * @type {\"number\" | \"text\" | \"search\" | \"email\" | \"password\" | \"tel\" | \"url\" | undefined}\n * @default \"search\"\n * @memberOf SearchbarComponent\n */\n @Input()\n type: \"number\" | \"text\" | \"search\" | \"email\" | \"password\" | \"tel\" | \"url\" | undefined = \"search\";\n\n /**\n * @description The value of the searchbar input.\n * @summary Specifies the current value of the searchbar input.\n * @type {null | string | undefined}\n * @default \"\"\n * @memberOf SearchbarComponent\n */\n @Input()\n value: null | string | undefined = \"\";\n\n /**\n * @description The keys to use for querying.\n * @summary Specifies the keys to be used when performing a search query.\n * @type {string | string[]}\n * @default \"name\"\n * @memberOf SearchbarComponent\n */\n @Input()\n queryKeys: string | string[] = \"name\";\n\n /**\n * @description Whether the searchbar is visible.\n * @summary Controls the visibility of the searchbar component.\n * @type {StringOrBoolean}\n * @default false\n * @memberOf SearchbarComponent\n */\n @Input()\n isVisible: StringOrBoolean = false;\n\n /**\n * @description Whether to wrap the searchbar in a container.\n * @summary Controls whether the searchbar is wrapped in an additional container element.\n * @type {StringOrBoolean}\n * @default false\n * @memberOf SearchbarComponent\n */\n @Input()\n wrapper: StringOrBoolean = false;\n\n /**\n * @description The color of the wrapper.\n * @summary Specifies the color theme to be applied to the wrapper container, if present.\n * @type {PredefinedColors}\n * @default \"primary\"\n * @memberOf SearchbarComponent\n */\n @Input()\n wrapperColor: PredefinedColors = \"primary\";\n\n /**\n * @description Whether to emit events to the window.\n * @summary Controls whether search events should be emitted as window events.\n * @type {StringOrBoolean}\n * @default true\n * @memberOf SearchbarComponent\n */\n @Input()\n emitEventToWindow: StringOrBoolean = true;\n\n /**\n * @description The current value of the searchbar.\n * @summary Stores the current value of the searchbar input for internal state management and processing.\n * This property is used to track the search term throughout the component's lifecycle and\n * coordinate between different event handlers and methods.\n *\n * @type {string | undefined}\n * @memberOf SearchbarComponent\n */\n currentValue: string | undefined;\n\n /**\n * @description Event emitter for search events.\n * @summary Emits search events when the user interacts with the searchbar, providing a reactive\n * interface for parent components to respond to search actions. This event is triggered by\n * various user interactions including typing, clearing, and explicit search actions.\n *\n * @type {EventEmitter<string>}\n * @memberOf SearchbarComponent\n */\n @Output()\n searchEvent: EventEmitter<string> = new EventEmitter<string>();\n\n /**\n * @description Creates an instance of SearchbarComponent.\n * @summary Initializes the SearchbarComponent with all necessary dependencies and configurations.\n * During initialization, it adds all available Ionicons to the application's icon registry,\n * ensuring that search and clear icons are available for use throughout the component's lifecycle.\n *\n * @memberOf SearchbarComponent\n */\n constructor() {\n super('SearchbarComponent');\n addIcons(allIcons)\n }\n\n /**\n * @description Initializes the component after Angular first displays the data-bound properties.\n * @summary Performs essential component initialization by converting string-based boolean inputs\n * to proper boolean values using the stringToBoolean utility. This ensures that all boolean\n * properties work correctly regardless of how they were passed from parent components or templates.\n *\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant S as SearchbarComponent\n * participant U as Utility Functions\n *\n * A->>S: ngOnInit()\n * S->>U: stringToBoolean(emitEventToWindow)\n * U-->>S: boolean value\n * S->>U: stringToBoolean(wrapper)\n * U-->>S: boolean value\n * S->>U: stringToBoolean(isVisible)\n * U-->>S: boolean value\n * S->>U: stringToBoolean(disabled)\n * U-->>S: boolean value\n * S->>U: stringToBoolean(animated)\n * U-->>S: boolean value\n * Note over S: Component ready for interaction\n *\n * @memberOf SearchbarComponent\n */\n ngOnInit(): void {\n this.emitEventToWindow = stringToBoolean(this.emitEventToWindow);\n this.wrapper = stringToBoolean(this.wrapper);\n this.isVisible = stringToBoolean(this.isVisible);\n this.disabled = stringToBoolean(this.disabled);\n this.animated = stringToBoolean(this.animated);\n }\n\n /**\n * @description Handles the visibility toggle of the searchbar component.\n * @summary Listens for global window events to toggle the visibility state of the searchbar.\n * When the searchbar becomes visible, it automatically focuses on the input field after a brief\n * delay to ensure smooth animation completion. This provides a seamless user experience for\n * search activation through keyboard shortcuts or programmatic triggers.\n *\n * @param {CustomEvent} event - The custom event triggering the visibility toggle (unused but required by HostListener)\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant W as Window\n * participant S as SearchbarComponent\n * participant E as DOM Element\n *\n * W->>S: toggleSearchbarVisibility event\n * S->>S: handleToggleVisibility()\n * S->>S: Toggle isVisible state\n * alt isVisible is true AND component exists\n * S->>S: setTimeout(125ms)\n * S->>E: setFocus() on ion-searchbar\n * end\n *\n * @memberOf SearchbarComponent\n */\n @HostListener(\"window:toggleSearchbarVisibility\", ['$event'])\n handleToggleVisibility(): void {\n this.isVisible = !this.isVisible;\n if (this.isVisible && !!this.component.nativeElement) {\n setTimeout(() => {\n (this.component.nativeElement as HTMLIonSearchbarElement).setFocus();\n }, 125);\n }\n }\n\n /**\n * @description Triggers a manual search event with the current searchbar value.\n * @summary Retrieves the current value from the searchbar's native element and emits it as a search event.\n * This method provides a programmatic way to trigger search functionality, useful for external\n * components or keyboard shortcuts that need to execute search without user interaction with the searchbar itself.\n *\n * @return {void}\n * @memberOf SearchbarComponent\n */\n search(): void {\n const element = this.component.nativeElement as HTMLIonSearchbarElement;\n this.searchEvent.emit(element.value || undefined);\n }\n\n /**\n * @description Handles value changes in the searchbar input field.\n * @summary Processes change events from the Ionic searchbar component and extracts the new value\n * to emit as a search event. This method is triggered when the user finishes editing the searchbar\n * value, providing a way to react to completed input changes rather than real-time typing.\n *\n * @param {CustomEvent} event - The change event from the Ionic searchbar containing the new value\n * @return {void}\n * @memberOf SearchbarComponent\n */\n handleChange(event: CustomEvent): void {\n this.emitEvent(event?.detail?.value ?? undefined);\n }\n\n /**\n * @description Handles clearing of the searchbar input field.\n * @summary Emits an undefined value as a search event when the searchbar is cleared by the user.\n * This method is typically triggered when the user clicks the clear button or uses other\n * clear mechanisms, signaling that the search should be reset or cleared.\n *\n * @return {void}\n * @memberOf SearchbarComponent\n */\n handleClear(): void {\n this.emitEvent(undefined);\n }\n\n /**\n * @description Handles real-time input events on the searchbar.\n * @summary Processes input events as the user types, providing immediate feedback for search functionality.\n * This method implements smart clearing behavior - if the input becomes empty, it automatically\n * triggers the clear handler. Otherwise, it emits the current value for real-time search suggestions\n * or filtering. This enables responsive search experiences with debounced event handling.\n *\n * @param {CustomEvent} event - The input event from the Ionic searchbar containing the current value\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant S as SearchbarComponent\n * participant E as Event System\n *\n * U->>S: Type in searchbar\n * S->>S: handleInput(event)\n * S->>S: Extract value from event\n * alt value is empty or null\n * S->>S: handleClear()\n * S->>E: Emit undefined\n * else value has content\n * S->>S: emitEvent(value)\n * S->>E: Emit search value\n * end\n *\n * @memberOf SearchbarComponent\n */\n handleInput(event: CustomEvent): void {\n const value = event?.detail?.value;\n if (!value || !value?.length)\n return this.handleClear();\n this.emitEvent(value);\n }\n\n /**\n * @description Handles blur events on the searchbar.\n * @summary Currently an empty method, can be implemented for specific blur behavior.\n * @param {CustomEvent} event - The blur event from the searchbar\n * @return {void}\n */\n // handleBlur(event: CustomEvent): void {}\n\n /**\n * @description Emits search events through multiple channels.\n * @summary Orchestrates the emission of search events both as component output events and optionally\n * as global window events. This dual-channel approach enables both direct parent-child communication\n * and application-wide event broadcasting, supporting flexible integration patterns and loose coupling\n * between components that need to respond to search actions.\n *\n * @param {string | undefined} value - The search value to emit across all configured channels\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant S as SearchbarComponent\n * participant P as Parent Component\n * participant W as Window Event System\n *\n * S->>S: emitEvent(value)\n * S->>P: searchEvent.emit(value)\n * alt emitEventToWindow is true\n * S->>W: windowEventEmitter('searchbarEvent', {value})\n * end\n *\n * @memberOf SearchbarComponent\n */\n emitEvent(value: string | undefined): void {\n this.searchEvent.emit(value);\n if (this.emitEventToWindow)\n windowEventEmitter('searchbarEvent', {value: value})\n }\n\n /**\n * @description Prevents default behavior of DOM events.\n * @summary Utility method to prevent unwanted default actions on DOM events, such as form submissions\n * or navigation triggers. This is commonly used in event handlers where the default browser behavior\n * would interfere with the component's custom logic or user experience design.\n *\n * @param {Event} event - The DOM event whose default behavior should be prevented\n * @return {void}\n * @memberOf SearchbarComponent\n */\n preventChange(event: Event): void {\n event.preventDefault();\n }\n}\n","<ion-searchbar\n [id]=\"uid\"\n ngClass=\"dcf-searchbar\"\n name=\"search\"\n mode=\"ios\"\n (keyup.enter)=\"preventChange($event)\"\n (ionChange)=\"handleChange($event)\"\n (ionInput)=\"handleInput($event)\"\n (ionClear)=\"handleClear()\"\n [autocomplete]=\"autocomplete\"\n [showCancelButton]=\"showCancelButton\"\n [cancelButtonText]=\"buttonCancelText\"\n [clearIcon]=\"clearIcon\"\n [color]=\"color\"\n [debounce]=\"debounce\"\n [disabled]=\"disabled\"\n [enterkeyhint]=\"enterkeyhint\"\n [inputmode]=\"inputmode\"\n [placeholder]=\"placeholder\"\n [searchIcon]=\"searchIcon\"\n [showClearButton]=\"showClearButton\"\n [spellcheck]=\"spellcheck\"\n [type]=\"type\"\n #component\n />\n","/**\n * @module module:lib/components/filter/filter.component\n * @description Filter component module.\n * @summary Provides `FilterComponent` which builds advanced, multi-step filter\n * queries (index → condition → value) and emits filter events for data querying.\n * It supports responsive behavior, suggestions and integration with `SearchbarComponent`.\n *\n * @link {@link FilterComponent}\n */\n\nimport { Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { FormsModule } from '@angular/forms';\nimport { debounceTime, fromEvent, Subscription } from 'rxjs';\nimport { IonButton, IonChip, IonIcon, IonSelect, IonSelectOption} from '@ionic/angular/standalone';\nimport { chevronDownOutline, trashOutline, closeOutline, searchOutline, arrowDownOutline, arrowUpOutline, chevronUpOutline } from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { Model } from '@decaf-ts/decorator-validation';\nimport { OrderDirection, Repository } from '@decaf-ts/core';\nimport { NgxComponentDirective } from '../../engine/NgxComponentDirective';\nimport { Dynamic } from '../../engine/decorators';\nimport { IFilterQuery, IFilterQueryItem } from '../../engine/interfaces';\nimport { getWindowWidth } from '../../utils/helpers';\nimport { SearchbarComponent } from '../searchbar/searchbar.component';\n\n\n/**\n * @description Advanced filter component for creating dynamic search filters with step-by-step construction.\n * @summary This component provides a comprehensive filtering interface that allows users to build\n * complex search criteria using a three-step approach: select index → select condition → enter value.\n * It supports filtering by multiple field indexes, comparison conditions, and values, displaying\n * selected filters as removable chips. The component is responsive and includes auto-suggestions\n * with keyboard navigation support.\n *\n * @example\n * ```html\n * <ngx-decaf-filter\n * [indexes]=\"['name', 'email', 'department', 'status']\"\n * [conditions]=\"['Equal', 'Contains', 'Greater Than', 'Less Than']\"\n * [sort]=\"['createdAt', 'updatedAt']\"\n * [disableSort]=\"false\"\n * (filterEvent)=\"onFiltersChanged($event)\">\n * </ngx-decaf-filter>\n * ```\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant F as FilterComponent\n * participant P as Parent Component\n *\n * U->>F: Focus input field\n * F->>F: handleFocus() - Show available indexes\n * U->>F: Select index (e.g., \"name\")\n * F->>F: addFilter() - Step 1 completed\n * F->>F: Show available conditions\n * U->>F: Select condition (e.g., \"Contains\")\n * F->>F: addFilter() - Step 2 completed\n * F->>F: Show value input prompt\n * U->>F: Enter value and press Enter\n * F->>F: addFilter() - Step 3 completed\n * F->>F: Create complete filter object\n * F->>P: Emit filterEvent with new filter array\n * F->>F: Reset to step 1 for next filter\n *\n * @memberOf ForAngularCommonModule\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-filter',\n templateUrl: './filter.component.html',\n styleUrls: ['./filter.component.scss'],\n imports: [\n FormsModule,\n TranslatePipe,\n IonChip,\n IonIcon,\n IonButton,\n IonSelect,\n IonSelectOption,\n IonIcon,\n SearchbarComponent\n ],\n standalone: true,\n host: {'[attr.id]': 'uid'},\n})\nexport class FilterComponent extends NgxComponentDirective implements OnInit, OnDestroy {\n\n /**\n * @description Reference to the dropdown options container element.\n * @summary ViewChild reference used to access and manipulate the dropdown options element\n * for highlighting filtered items and managing visual feedback during option selection.\n * This element contains the filterable suggestions that users can interact with.\n *\n * @type {ElementRef}\n * @memberOf FilterComponent\n */\n @ViewChild('optionsFilterElement', { read: ElementRef, static: false })\n optionsFilterElement!: ElementRef;\n\n /**\n * @description Available field indexes for filtering operations.\n * @summary Defines the list of field names that users can filter by. These represent\n * the data properties available for filtering operations. Each index corresponds to\n * a field in the data model that supports comparison operations.\n *\n * @type {string[]}\n * @default []\n * @memberOf FilterComponent\n */\n @Input()\n indexes: string[] = [];\n\n\n @Input()\n multiple: boolean = false;\n\n\n /**\n * @description Available comparison conditions for filters.\n * @summary Defines the list of comparison operators that can be used when creating filters.\n * These conditions determine how the filter value is compared against the field value.\n * Common conditions include equality, containment, and numerical comparison operations.\n *\n * @type {string[]}\n * @default []\n * @memberOf FilterComponent\n */\n @Input()\n conditions: string[] = ['Equal', 'Contains', 'Not Contains', 'Greater Than', 'Less Than', 'Not Equal'];\n\n /**\n * @description Available sorting options for the filtered data.\n * @summary Defines the list of field names that can be used for sorting the filtered results.\n * When disableSort is false, this array is automatically merged with the indexes array\n * to provide comprehensive sorting capabilities.\n *\n * @type {string[]}\n * @default []\n * @memberOf FilterComponent\n */\n @Input()\n sortBy: string[] = [];\n\n /**\n * @description Controls whether sorting functionality is disabled.\n * @summary When set to true, prevents the automatic merging of sort and indexes arrays,\n * effectively disabling sorting capabilities. This is useful when you want to provide\n * filtering without sorting options.\n *\n * @type {boolean}\n * @default false\n * @memberOf FilterComponent\n */\n @Input()\n disableSort: boolean = false;\n\n /**\n * @description Current window width for responsive behavior.\n * @summary Stores the current browser window width in pixels. This value is updated\n * on window resize events to enable responsive filtering behavior and layout adjustments\n * based on available screen space.\n *\n * @type {number}\n * @memberOf FilterComponent\n */\n windowWidth!: number;\n\n /**\n * @description Available options for the current filter step.\n * @summary Contains the list of options available for selection in the current step.\n * This array changes dynamically based on the current step: indexes → conditions → empty for value input.\n *\n * @type {string[]}\n * @default []\n * @memberOf FilterComponent\n */\n options: string[] = [];\n\n /**\n * @description Filtered options based on user input.\n * @summary Contains the subset of options that match the current user input for real-time\n * filtering. This array is updated as the user types to show only relevant suggestions\n * in the dropdown menu.\n *\n * @type {string[]}\n * @default []\n * @memberOf FilterComponent\n */\n filteredOptions: string[] = [];\n\n /**\n * @description Complete filter objects created by the user.\n * @summary Array of complete filter objects, each containing index, condition, and value properties.\n * These represent the active filters that can be applied to data operations.\n *\n * @type {KeyValue[]}\n * @default []\n * @memberOf FilterComponent\n */\n filterValue: IFilterQueryItem[] = [];\n\n /**\n * @description Current filter being constructed.\n * @summary Temporary object that accumulates filter properties (index, condition, value)\n * during the three-step filter creation process. Gets added to filterValue when complete.\n *\n * @type {KeyValue}\n * @default {}\n * @memberOf FilterComponent\n */\n lastFilter: IFilterQueryItem = {};\n\n /**\n * @description Current step in the filter creation process.\n * @summary Tracks the current step of filter creation: 1 = index selection, 2 = condition selection,\n * 3 = value input. Automatically resets to 1 after completing a filter.\n *\n * @type {number}\n * @default 1\n * @memberOf FilterComponent\n */\n step: number = 1;\n\n /**\n * @description Controls dropdown visibility state.\n * @summary Boolean flag that determines whether the options dropdown is currently visible.\n * Used to manage the dropdown's open/close state and coordinate with focus/blur events.\n *\n * @type {boolean}\n * @default false\n * @memberOf FilterComponent\n */\n dropdownOpen: boolean = false;\n\n /**\n * @description Current input field value.\n * @summary Stores the current text input value that the user is typing. This value is\n * bound to the input field and is cleared after each successful filter step completion.\n *\n * @type {string}\n * @default ''\n * @memberOf FilterComponent\n */\n value: string = '';\n\n /**\n * @description Current sorting field value.\n * @summary Stores the field name currently selected for sorting operations.\n * This value determines which field is used to order the filtered results.\n * Defaults to 'id' and can be changed through the sort dropdown selection.\n *\n * @type {string}\n * @default 'id'\n * @memberOf FilterComponent\n */\n sortValue: string = 'id';\n\n /**\n * @description Current sorting direction.\n * @summary Defines the direction of the sort operation - ascending or descending.\n * This value works in conjunction with sortValue to determine the complete\n * sorting configuration for filtered results.\n *\n * @type {OrderDirection}\n * @default OrderDirection.DSC\n * @memberOf FilterComponent\n */\n sortDirection: OrderDirection = OrderDirection.DSC;\n\n /**\n * @description Subscription for window resize events.\n * @summary RxJS subscription that listens for window resize events with debouncing\n * to update the windowWidth property. This enables responsive behavior and prevents\n * excessive updates during resize operations.\n *\n * @type {Subscription}\n * @memberOf FilterComponent\n */\n windowResizeSubscription!: Subscription;\n\n /**\n * @description Event emitter for filter changes.\n * @summary Emits filter events when the user creates, modifies, or clears filters.\n * The emitted value contains an array of complete filter objects or undefined when\n * filters are cleared. Parent components listen to this event to update their data display.\n *\n * @type {EventEmitter<KeyValue[] | undefined>}\n * @memberOf FilterComponent\n */\n @Output()\n filterEvent: EventEmitter<IFilterQuery | undefined> = new EventEmitter<IFilterQuery | undefined>();\n\n /**\n * @description Event emitter for search events.\n * @summary Emits search events when the user interacts with the searchbar.\n * @type {EventEmitter<string>}\n * @memberOf FilterComponent\n */\n @Output()\n searchEvent: EventEmitter<string> = new EventEmitter<string>();\n\n\n /**\n * @description Constructor for FilterComponent.\n * @summary Initializes a new instance of the FilterComponent.\n * Calls the parent constructor with the component name to establish base locale string generation\n * and internationalization support.\n *\n * @memberOf FilterComponent\n */\n constructor() {\n super(\"FilterComponent\");\n addIcons({chevronDownOutline, trashOutline, closeOutline, searchOutline, arrowDownOutline, arrowUpOutline, chevronUpOutline});\n }\n\n /**\n * @description Initializes the component after Angular first displays the data-bound properties.\n * @summary Sets up the component by initializing window width tracking, setting up resize event\n * subscriptions with debouncing, configuring sorting options, and calling the base initialization.\n * This method prepares the component for user interaction and responsive behavior.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant F as FilterComponent\n * participant W as Window\n * participant R as RxJS\n *\n * A->>F: ngOnInit()\n * F->>W: getWindowWidth()\n * W-->>F: Return current width\n * F->>R: Setup resize subscription with debounce\n * R-->>F: Subscription created\n * alt disableSort is false\n * F->>F: Merge sort and indexes arrays\n * end\n * F->>F: Call initialize()\n *\n * @returns {Promise<void>}\n * @memberOf FilterComponent\n */\n async ngOnInit(): Promise<void> {\n\n this.windowWidth = getWindowWidth() as number;\n this.windowResizeSubscription = fromEvent(window, 'resize')\n .pipe(debounceTime(300))\n .subscribe(() => {\n this.windowWidth = getWindowWidth() as number;\n });\n\n this.getIndexes();\n this.initialize();\n }\n\n /**\n * @description Retrieves and configures available indexes for filtering and sorting.\n * @summary Extracts field indexes from the model if available and merges them with\n * sorting options when sorting is enabled. This method sets up the available field\n * options for both filtering and sorting operations based on the model structure.\n *\n * @returns {void}\n * @memberOf FilterComponent\n */\n getIndexes(): void {\n if (this.model)\n this.indexes = Object.keys(Repository.indexes(this.model as Model) || {});\n if (!this.disableSort) {\n this.sortBy = [... this.sortBy, ...this.indexes];\n if (this.repository)\n this.sortValue = this.repository.pk || this.sortValue;\n }\n }\n\n\n /**\n * @description Cleanup method called when the component is destroyed.\n * @summary Unsubscribes from window resize events to prevent memory leaks.\n * This is essential for proper cleanup of RxJS subscriptions when the component\n * is removed from the DOM.\n *\n * @returns {void}\n * @memberOf FilterComponent\n */\n override async ngOnDestroy(): Promise<void> {\n super.ngOnDestroy();\n if(this.windowResizeSubscription)\n this.windowResizeSubscription.unsubscribe();\n this.clear();\n }\n\n /**\n * @description Handles input events from the text field.\n * @summary Processes user input and filters the available options based on the typed value.\n * This method provides real-time filtering of suggestions as the user types in the input field.\n *\n * @param {InputEvent} event - The input event containing the new value\n * @returns {void}\n * @memberOf FilterComponent\n */\n handleInput(event: InputEvent): void {\n const {value} = event.target as HTMLInputElement;\n this.filteredOptions = this.filterOptions(value);\n }\n\n /**\n * @description Handles focus events on the input field.\n * @summary Sets up the available options when the input field receives focus and opens the dropdown.\n * If no options are provided, automatically determines the appropriate options based on current step.\n * This method initializes the dropdown with contextually relevant suggestions.\n *\n * @param {string[]} options - Optional array of options to display\n * @returns {void}\n * @memberOf FilterComponent\n */\n handleFocus(options: string[] = []): void {\n if (!options.length)\n options = this.getOptions();\n this.filteredOptions = this.options = options;\n this.dropdownOpen = true;\n }\n\n /**\n * @description Handles blur events on the input field with delayed closing.\n * @summary Manages the dropdown closing behavior with a delay to allow for option selection.\n * Uses a two-phase approach to prevent premature closing when users click on dropdown options.\n *\n * @param {boolean} close - Internal flag to control the closing phase\n * @returns {void}\n * @memberOf FilterComponent\n */\n handleBlur(close: boolean = false): void {\n if (!close) {\n this.dropdownOpen = false;\n setTimeout(() => {\n this.handleBlur(true);\n }, 100);\n } else {\n if (!this.dropdownOpen && this.options.length) {\n setTimeout(() => {\n this.options = [];\n this.dropdownOpen = false;\n }, 50);\n }\n }\n }\n\n /**\n * @description Determines the appropriate options based on the current filter step.\n * @summary Returns the contextually relevant options for the current step in the filter creation process.\n * Step 1 shows indexes, Step 2 shows conditions, Step 3 shows no options (value input).\n *\n * @returns {string[]} Array of options appropriate for the current step\n * @memberOf FilterComponent\n */\n getOptions(): string[] {\n switch (this.step) {\n case 1:\n this.options = this.indexes;\n break;\n case 2:\n this.options = this.conditions;\n break;\n case 3:\n this.options = [];\n break;\n }\n return this.options\n }\n\n /**\n * @description Adds a filter step or completes filter creation through a three-step process.\n * @summary Core method for building filters step by step: Step 1 (Index) → Step 2 (Condition) → Step 3 (Value).\n * When all steps are complete, creates a complete filter object and adds it to the filter collection.\n * Handles both keyboard events (Enter to submit) and programmatic calls.\n *\n * @param {string} value - The value to add for the current step\n * @param {CustomEvent} event - Optional event (KeyboardEvent triggers submission when value is empty)\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant F as FilterComponent\n *\n * U->>F: addFilter(value, event)\n * F->>F: Trim and validate value\n * alt KeyboardEvent && empty value\n * F->>F: submit() - Send current filters\n * else Valid value or step 3\n * alt Step 1 (Index)\n * F->>F: lastFilter.index = value\n * F->>F: options = conditions\n * else Step 2 (Condition)\n * F->>F: lastFilter.condition = value\n * F->>F: options = []\n * else Step 3 (Value)\n * F->>F: lastFilter.value = value\n * F->>F: Add complete filter to filterValue\n * F->>F: Reset step to 1\n * end\n * F->>F: Increment step\n * F->>F: Clear input & focus\n * F->>F: Show next options\n * end\n *\n * @memberOf FilterComponent\n */\n addFilter(value: string, event?: CustomEvent): void {\n value = value.trim();\n if (event instanceof KeyboardEvent && !value) {\n this.submit();\n } else {\n if ((value && (!(event instanceof KeyboardEvent)) || this.step === 3)) {\n const filter = this.lastFilter;\n switch (this.step) {\n case 1:\n filter['index'] = value;\n this.options = this.conditions;\n break;\n case 2:\n filter['condition'] = value;\n this.options = [];\n break;\n case 3:\n filter['value'] = value;\n this.options = this.indexes;\n break;\n }\n if (!this.filterValue.length) {\n this.filterValue.push(filter);\n } else {\n if (this.step === 1)\n this.filterValue.push(filter);\n }\n if (this.step === 3) {\n this.step = 0;\n this.filterValue[this.filterValue.length - 1] = filter;\n this.lastFilter = {};\n if(!this.multiple)\n return this.submit();\n }\n\n this.step++;\n this.value = '';\n if (this.options.length)\n this.handleFocus(this.options);\n this.component.nativeElement.querySelector('#dcf-filter-field').focus();\n }\n }\n }\n\n /**\n * @description Selects an option from the dropdown suggestions.\n * @summary Handles option selection when a user clicks on a suggestion in the dropdown.\n * This method acts as a bridge between dropdown clicks and the main addFilter logic.\n *\n * @param {CustomEvent} event - The click event from the dropdown option\n * @param {string} value - The selected option value\n * @returns {void}\n * @memberOf FilterComponent\n */\n selectOption(value: string): void {\n this.addFilter(value);\n }\n\n /**\n * @description Determines if a filter option can be individually removed.\n * @summary Checks whether a filter component should display a close icon for removal.\n * Only value options can be removed individually; index and condition options are part\n * of the complete filter structure and cannot be removed separately.\n *\n * @param {string} option - The filter option text to check\n * @returns {boolean} True if the option can be cleared individually, false otherwise\n * @memberOf FilterComponent\n */\n allowClear(option: string): boolean {\n return this.indexes.indexOf(option) === -1 && this.conditions.indexOf(option) === -1;\n }\n\n /**\n * @description Removes a complete filter from the collection based on filter value.\n * @summary Removes a complete filter by matching the provided value against filter values\n * in the collection. Uses string normalization to handle accents and case differences.\n * After removal, resets the interface to show available indexes for new filter creation.\n *\n * @param {string} filter - The filter value to remove (matches against filter.value property)\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant F as FilterComponent\n *\n * U->>F: removeFilter(filterValue)\n * F->>F: cleanString(filterValue)\n * F->>F: Filter out matching filter objects\n * F->>F: Clear input value\n * F->>F: handleFocus(indexes) - Reset to index selection\n * Note over F: Filter removed and UI reset\n *\n * @memberOf FilterComponent\n */\n removeFilter(filter: string): void {\n function cleanString(filter: string): string {\n return filter\n .toLowerCase() // convert all characters to lowercase\n .normalize(\"NFD\") // separate accent marks from characters\n .replace(/[\\u0300-\\u036f]/g, \"\") // remove accent marks\n .replace(/\\s+/g, \"\"); // remove all whitespace\n }\n this.value = \"\";\n this.filterValue = this.filterValue.filter((item) => item?.['value'] && cleanString(item?.['value']) !== cleanString(filter));\n if (this.filterValue.length === 0) {\n this.step = 1;\n this.lastFilter = {};\n }\n this.handleFocus(this.indexes);\n }\n\n /**\n * @description Resets the component to its initial state.\n * @summary Clears all filter data, options, and resets the step counter to 1.\n * This method provides a clean slate for new filter creation without emitting events.\n *\n * @returns {void}\n * @memberOf FilterComponent\n */\n reset(submit: boolean = true): void {\n this.options = this.filteredOptions = this.filterValue = [];\n this.step = 1;\n this.lastFilter = {};\n this.value = '';\n if (submit) {\n setTimeout(() => {\n this.submit();\n }, 100);\n }\n }\n\n /**\n * @description Clears all filters and notifies parent components.\n * @summary Resets the component state and emits undefined to notify parent components\n * that all filters have been cleared. This triggers any connected data refresh logic.\n *\n * @param {string} value - Optional parameter (currently unused)\n * @returns {void}\n * @memberOf FilterComponent\n */\n clear(value?: string): void {\n if (!value)\n this.reset();\n }\n\n /**\n * @description Submits the current filter collection to parent components.\n * @summary Emits the current filter array to parent components when filters are ready\n * to be applied. Only emits if there are active filters. Clears options after submission.\n *\n * @returns {void}\n * @memberOf FilterComponent\n */\n submit(): void {\n this.filterEvent.emit({\n query: this.filterValue.length > 0 ? this.filterValue : undefined,\n sort: {\n value: this.sortValue,\n direction: this.sortDirection\n }\n } as IFilterQuery);\n if (this.filterValue.length === 0)\n this.options = [];\n }\n\n /**\n * @description Toggles the sort direction between ascending and descending.\n * @summary Handles sort direction changes by toggling between ASC and DSC values.\n * When the direction changes, automatically triggers a submit to apply the new\n * sorting configuration to the filtered results.\n *\n * @returns {void}\n * @memberOf FilterComponent\n */\n handleSortDirectionChange(): void {\n const direction = this.sortDirection === OrderDirection.ASC ? OrderDirection.DSC : OrderDirection.ASC;\n if (direction !== this.sortDirection) {\n this.sortDirection = direction;\n this.submit();\n }\n }\n\n /**\n * @description Handles sort field selection changes from the dropdown.\n * @summary Processes sort field changes when users select a different field\n * from the sort dropdown. Updates the sortValue property and triggers\n * a submit to apply the new sorting configuration if the value has changed.\n *\n * @param {CustomEvent} event - The select change event containing the new sort field value\n * @returns {void}\n * @memberOf FilterComponent\n */\n handleSortChange(event: CustomEvent): void {\n const target = event.target as HTMLIonSelectElement;\n const value = target.value;\n if (value !== this.sortValue) {\n this.sortValue = value as string;\n this.submit();\n }\n }\n\n /**\n * @description Filters available options based on user input with visual highlighting.\n * @summary Performs real-time filtering of available options based on user input.\n * Also handles visual highlighting of matching options in the dropdown. Returns all\n * options if input is less than 2 characters for performance optimization.\n *\n * @param {string | null | undefined} value - The search value to filter by\n * @returns {string[]} Array of filtered options that match the input\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant F as FilterComponent\n * participant D as DOM\n *\n * U->>F: filterOptions(inputValue)\n * alt inputValue < 2 characters\n * F->>D: Remove existing highlights\n * F-->>U: Return all options\n * else inputValue >= 2 characters\n * F->>D: Query all option elements\n * F->>D: Add highlight to first matching option\n * F->>F: Filter options by substring match\n * F-->>U: Return filtered options\n * end\n *\n * @memberOf FilterComponent\n */\n filterOptions(value: string | null | undefined): string[] {\n const optionsElement = this.optionsFilterElement.nativeElement;\n\n if (!value?.length || !value || value.length < 2) {\n const filteredOption = optionsElement.querySelector('.dcf-filtering-item');\n if (filteredOption)\n filteredOption.classList.remove('dcf-filtering-item');\n return this.options;\n }\n const options = optionsElement.querySelectorAll('.dcf-item');\n for (const option of options) {\n const isActive = option.textContent?.toLowerCase().includes(value.toLowerCase());\n if (isActive) {\n option.classList.add('dcf-filtering-item');\n break;\n }\n }\n return this.options.filter((option: string) => option.toLowerCase().includes(value.toLowerCase() as string));\n }\n\n /**\n * @description Handles search events from the integrated searchbar component.\n * @summary Processes search input from the searchbar and emits search events\n * to parent components. This method acts as a bridge between the internal\n * searchbar component and external search event listeners.\n *\n * @param {string | undefined} value - The search value entered by the user\n * @returns {void}\n * @memberOf FilterComponent\n */\n handleSearch(value: string | undefined): void {\n this.searchEvent.emit(value);\n }\n\n}\n","\n@if (!indexes.length) {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n}\n\n<div [id]=\"uid\" class=\"dcf-grid dcf-grid-small dcf-grid-match dcf-filter-component\" [class.dcf-hidden]=\"!indexes.length\" #component>\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-filter\">\n <div class=\"dcf-input\">\n @for(filter of filterValue; track trackItemFn($index, filter?.['index'])) {\n @if (filter?.['index']) {\n <ion-chip [outline]=\"true\">{{ filter?.['index'] }}</ion-chip>\n }\n @if (filter?.['condition']) {\n <ion-chip [outline]=\"true\">{{ filter?.['condition'] }}</ion-chip>\n }\n @if (filter?.['value']) {\n <ion-chip [outline]=\"true\" class=\"dcf-filter-value\">\n {{ filter?.['value'] }}\n <ion-icon tabindex=\"0\" name=\"close-outline\" (click)=\"removeFilter(filter?.['value'])\" size=\"small\"></ion-icon>\n </ion-chip>\n }\n }\n <div class=\"dcf-width-1-1\">\n <!-- [readonly]=\"step !== 3\" -->\n <input\n fill=\"none\"\n [(ngModel)]=\"value\"\n (keydown.enter)=\"addFilter(value, $event)\"\n (keydown.backspace)=\"clear(value)\"\n (input)=\"handleInput($event)\"\n (click)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n type=\"text\"\n id=\"dcf-filter-field\"\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n\n />\n @if (windowWidth >= 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n @if (filterValue.length > 0) {\n <div class=\"dcf-icon-clear\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"clear()\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n <div class=\"dcf-icon-search\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"submit()\">\n <ion-icon aria-hidden=\"true\" name=\"search-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n </div>\n @if (windowWidth < 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n @if (!disableSort) {\n <div class=\"dcf-width-1-5@m dcf-width-1-1 dcf-sort-container\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-grid-match\">\n <div class=\"dcf-width-expand\">\n <ion-select\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n class=\"dcf-sort-select\"\n (ionChange)=\"handleSortChange($event)\"\n interface=\"popover\"\n [value]=\"sortValue\"\n label-placement=\"floating\"\n fill=\"outline\"\n [label]=\"locale + '.sort' | translate\"\n >\n @for(sort of sortBy; track sort) {\n\n <ion-select-option [value]=\"sort\">{{ sort | translate }}</ion-select-option>\n }\n </ion-select>\n </div>\n <div class=\"dcf-width-auto\">\n <ion-button (click)=\"handleSortDirectionChange()\" fill=\"clear\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" [color]=\"!isDarkMode ? 'primary' : 'light'\" [name]=\"sortDirection === 'desc' ? 'arrow-down-outline' : 'arrow-up-outline'\"></ion-icon>\n </ion-button>\n </div>\n </div>\n </div>\n }\n</div>\n\n\n","/**\n * @module module:lib/components/pagination/pagination.component\n * @description Pagination component module.\n * @summary Provides `PaginationComponent` for displaying page navigation controls\n * and emitting pagination events. Use this component to navigate paginated data\n * in lists and other collections.\n *\n * @link {@link PaginationComponent}\n */\n\nimport { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { IonIcon } from '@ionic/angular/standalone';\nimport { addIcons } from 'ionicons';\nimport { chevronBackOutline, chevronForwardOutline } from 'ionicons/icons';\nimport { NgxComponentDirective } from '../../engine/NgxComponentDirective';\nimport { KeyValue } from '../../engine/types';\nimport { ComponentEventNames } from '../../engine/constants';\nimport { IPaginationCustomEvent } from '../../engine/interfaces';\n\n/**\n * @description A pagination component for navigating through multiple pages of content.\n * @summary This component provides a user interface for paginated content navigation,\n * displaying page numbers and navigation controls. It supports customizable page counts,\n * current page tracking, and emits events when users navigate between pages.\n *\n * The component intelligently handles large numbers of pages by showing a subset of page\n * numbers with ellipses to indicate skipped pages, ensuring the UI remains clean and usable\n * even with many pages.\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant P as PaginationComponent\n * participant E as External Component\n *\n * U->>P: Click page number\n * P->>P: navigate(page)\n * P->>P: handleClick(direction, page)\n * P->>E: Emit clickEvent with IPaginationCustomEvent\n *\n * U->>P: Click next button\n * P->>P: next()\n * P->>P: handleClick('next')\n * P->>E: Emit clickEvent with IPaginationCustomEvent\n *\n * U->>P: Click previous button\n * P->>P: previous()\n * P->>P: handleClick('previous')\n * P->>E: Emit clickEvent with IPaginationCustomEvent\n *\n * @example\n * <ngx-decaf-pagination\n * [pages]=\"10\"\n * [current]=\"3\"\n * (clickEvent)=\"handlePageChange($event)\">\n * </ngx-decaf-pagination>\n *\n * @extends {NgxBaseComponentDirective}\n * @implements {OnInit}\n */\n@Component({\n selector: 'ngx-decaf-pagination',\n templateUrl: './pagination.component.html',\n styleUrls: ['./pagination.component.scss'],\n imports: [\n TranslatePipe,\n IonIcon\n ],\n standalone: true,\n host: {'[attr.id]': 'uid'}\n})\nexport class PaginationComponent extends NgxComponentDirective implements OnInit {\n\n /**\n * @description The total number of pages to display in the pagination component.\n * @summary Specifies the total number of pages available for navigation. This is a required\n * input that determines how many page numbers will be generated and displayed.\n *\n * @type {number}\n * @required\n * @memberOf PaginationComponent\n */\n @Input({ required: true })\n totalPages!: number;\n\n /**\n * @description The currently active page number.\n * @summary Specifies which page is currently active or selected. This value is used\n * to highlight the current page in the UI and as a reference point for navigation.\n *\n * @type {number}\n * @default 1\n * @memberOf PaginationComponent\n */\n @Input()\n current = 1;\n\n /**\n * @description Array of page objects for rendering in the template.\n * @summary Contains the processed page data used for rendering the pagination UI.\n * Each object includes an index (page number) and text representation.\n *\n * @type {KeyValue[]}\n * @memberOf PaginationComponent\n */\n pages!: KeyValue[];\n\n /**\n * @description The last page number in the pagination.\n * @summary Stores the number of the last page for boundary checking during navigation.\n *\n * @type {number}\n * @memberOf PaginationComponent\n */\n last!: number;\n\n /**\n * @description Event emitter for pagination navigation events.\n * @summary Emits a custom event when users navigate between pages, either by clicking\n * on page numbers or using the next/previous buttons. The event contains information\n * about the navigation direction and the target page number.\n *\n * @type {EventEmitter<IPaginationCustomEvent>}\n * @memberOf PaginationComponent\n */\n @Output()\n clickEvent: EventEmitter<IPaginationCustomEvent> = new EventEmitter<IPaginationCustomEvent>();\n\n /**\n * @constructor\n * @description Initializes a new instance of the PaginationComponent.\n * Calls the parent constructor with the component name for generate base locale string.\n */\n constructor() {\n super(\"PaginationComponent\");\n addIcons({chevronBackOutline, chevronForwardOutline});\n }\n\n /**\n * @description Initializes the component after Angular sets the input properties.\n * @summary Sets up the component by initializing the locale settings based on the\n * translatable property, generating the page numbers based on the total pages and\n * current page, and storing the last page number for boundary checking.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant P as PaginationComponent\n *\n * A->>P: ngOnInit()\n * P->>P: getLocale(translatable)\n * P->>P: Set locale\n * P->>P: getPages(data, current)\n * P->>P: Set pages array\n * P->>P: Set last page number\n *\n * @returns {void}\n * @memberOf PaginationComponent\n */\n ngOnInit(): void {\n // this.locale = this.getLocale(this.translatable);\n this.pages = this.getPages(this.totalPages, this.current) as KeyValue[];\n this.last = this.totalPages;\n }\n\n /**\n * @description Handles click events on pagination controls.\n * @summary Processes user interactions with the pagination component, updating the\n * current page if specified and emitting an event with navigation details. This method\n * is called when users click on page numbers or navigation buttons.\n *\n * @param {('next' | 'previous')} direction - The direction of navigation\n * @param {number} [page] - Optional page number to navigate to directly\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant P as PaginationComponent\n * participant E as External Component\n *\n * U->>P: Click pagination control\n * P->>P: handleClick(direction, page?)\n * alt page is provided\n * P->>P: Update current page\n * end\n * P->>E: Emit clickEvent with direction and page\n *\n * @memberOf PaginationComponent\n */\n handleClick(direction: 'next' | 'previous', page?: number): void {\n if (page)\n this.current = page;\n this.clickEvent.emit({\n name: ComponentEventNames.CLICK,\n data: {\n direction,\n page: this.current\n },\n component: this.componentName\n } as IPaginationCustomEvent);\n }\n\n /**\n * @description Generates the array of page objects for display.\n * @summary Creates an array of page objects based on the total number of pages and\n * the current page. For small page counts (≤5), all pages are shown. For larger page\n * counts, a subset is shown with ellipses to indicate skipped pages. This ensures\n * the pagination UI remains clean and usable even with many pages.\n *\n * @param {number} total - The total number of pages\n * @param {number} [current] - The current active page (defaults to this.current)\n * @returns {KeyValue[]} Array of page objects with index and text properties\n *\n * @mermaid\n * flowchart TD\n * A[Start] --> B{total <= 5?}\n * B -->|Yes| C[Show all pages]\n * B -->|No| D[Show first page]\n * D --> E[Show last pages]\n * E --> F[Add ellipses for skipped pages]\n * C --> G[Return pages array]\n * F --> G\n *\n * @memberOf PaginationComponent\n */\n getPages(total: number, current?: number): KeyValue[] {\n if (!current) current = this.current;\n\n const pages: KeyValue[] = [];\n\n function getPage(index: number | null, text = '', clazz = 'button'): void {\n if (pages.some(item => item['index'] === index)) return;\n pages.push({ index, text: index != null ? index.toString().padStart(2, '0') : text, class: clazz });\n }\n\n if (total <= 5) {\n for (let i = 1; i <= total; i++) getPage(i);\n } else {\n // Adiciona os dois primeiros\n getPage(1);\n getPage(2);\n\n // Adiciona \"...\" entre os blocos\n if (current && current > 3) getPage(null, '...');\n\n // Adiciona a página atual (se estiver no meio)\n if (current && current > 2 && current < total - 1) getPage(current);\n\n // Adiciona \"...\" entre os blocos\n if (current && current < total - 2) getPage(null, '...' , 'separator');\n\n // Adiciona os dois últimos\n getPage(total - 1);\n getPage(total);\n }\n\n return pages;\n }\n\n /**\n * @description Gets the current active page number.\n * @summary Returns the current page number that is active in the pagination component.\n * This method provides a way to access the current page state from outside the component.\n *\n * @returns {number} The current page number\n * @memberOf PaginationComponent\n */\n getCurrent(): number {\n return this.current;\n }\n\n /**\n * @description Navigates to the next page.\n * @summary Increments the current page number if not at the last page and triggers\n * the click event handler with 'next' direction. This method is typically called\n * when the user clicks on the \"next\" button in the pagination UI.\n *\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant P as PaginationComponent\n *\n * U->>P: Click next button\n * P->>P: next()\n * alt page <= max pages\n * P->>P: Increment current page\n * P->>P: handleClick('next')\n * end\n *\n * @memberOf PaginationComponent\n */\n next(): void {\n const page = this.current + 1;\n if (page <= Object.keys(this.pages)?.length || 0) {\n this.current = page;\n this.handleClick('next');\n }\n }\n\n /**\n * @description Navigates to the previous page.\n * @summary Decrements the current page number if not at the first page and triggers\n * the click event handler with 'previous' direction. This method is typically called\n * when the user clicks on the \"previous\" button in the pagination UI.\n *\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant P as PaginationComponent\n *\n * U->>P: Click previous button\n * P->>P: previous()\n * alt page > 0\n * P->>P: Decrement current page\n * P->>P: handleClick('previous')\n * end\n *\n * @memberOf PaginationComponent\n */\n previous(): void {\n const page = this.current - 1;\n if (page > 0) {\n this.current = page;\n this.handleClick('previous');\n }\n }\n\n /**\n * @description Navigates to a specific page number.\n * @summary Updates the current page to the specified page number and triggers\n * the click event handler with the appropriate direction. This method is typically\n * called when the user clicks directly on a page number in the pagination UI.\n *\n * @param {number | null} page - The page number to navigate to\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant P as PaginationComponent\n *\n * U->>P: Click page number\n * P->>P: navigate(page)\n * alt page is not null and different from current\n * P->>P: Determine direction (next/previous)\n * P->>P: handleClick(direction, page)\n * end\n *\n * @memberOf PaginationComponent\n */\n navigate(page: number | null): void {\n if (page !== null && this.current !== page as number)\n this.handleClick(page > this.current ? 'next' : 'previous', page);\n }\n}\n"," <div [id]=\"uid\" class=\"dcf-paginator-container dcf-flex dcf-flex-center\" #component>\n <div class=\"dcf-width-1-1\">\n <div class=\"dcf-pagination-resume\" [innerHTML]=\"locale + '.resume' | translate:{'0': current, '1': last}\"></div>\n <div #paginationComponent class=\"dcf-pagination dcf-flex-center\">\n <div\n aria-label=\"previous\"\n tabindex=\"0\"\n (click)=\"previous()\"\n (keydown.enter)=\"previous()\" [class.dcf-disabled]=\"current === 1\">\n <ion-icon name=\"chevron-back-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n @for(page of pages; track page) {\n <div tabindex=\"0\" [class]=\"page['class']\" (click)=\"navigate(page['index'])\"\n (keydown.enter)=\"navigate(page['index'])\"\n [class.dcf-active]=\"current === page['index']\">\n <span class=\"page-item\">{{ page['text'] }}</span>\n </div>\n }\n <div\n tabindex=\"0\" (click)=\"next()\"\n (keydown.enter)=\"next()\"\n [class.dcf-disabled]=\"current === last\">\n <ion-icon name=\"chevron-forward-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n </div>\n </div>\n</div>\n","/**\n * @module module:lib/components/list/list.component\n * @description List component module.\n * @summary Provides the `ListComponent` which renders collections of data with\n * support for infinite scroll, pagination, searching, filtering, custom item\n * rendering and refresh events. Use this module's `ListComponent` to display\n * lists sourced from models, functions or direct data arrays.\n *\n * @link {@link ListComponent}\n */\n\nimport { Component, OnInit, EventEmitter, Output, Input, HostListener, OnDestroy } from '@angular/core';\nimport { InfiniteScrollCustomEvent, RefresherCustomEvent, SpinnerTypes } from '@ionic/angular';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n IonButton,\n IonInfiniteScroll,\n IonInfiniteScrollContent,\n IonItem,\n IonLabel,\n IonList,\n IonRefresher,\n IonRefresherContent,\n IonSkeletonText,\n IonText,\n IonThumbnail\n} from '@ionic/angular/standalone';\nimport { OperationKeys } from '@decaf-ts/db-decorators';\nimport { Model, Primitives } from '@decaf-ts/decorator-validation';\nimport { Condition, Observer, OrderDirection, Paginator } from '@decaf-ts/core';\nimport { debounceTime, Subject } from 'rxjs';\nimport { NgxComponentDirective } from '../../engine/NgxComponentDirective';\nimport { Dynamic } from '../../engine/decorators';\nimport {\n KeyValue,\n FunctionLike,\n DecafRepository\n} from '../../engine/types';\nimport {\n ComponentEventNames,\n ComponentsTagNames,\n DefaultListEmptyOptions,\n ListComponentsTypes\n} from '../../engine/constants';\nimport {\n IBaseCustomEvent,\n ListItemCustomEvent,\n IPaginationCustomEvent, IFilterQuery, IFilterQueryItem, IListEmptyOptions\n} from '../../engine/interfaces';\nimport {\n stringToBoolean,\n formatDate,\n isValidDate\n} from '../../utils/helpers';\nimport { SearchbarComponent } from '../searchbar/searchbar.component';\nimport { EmptyStateComponent } from '../empty-state/empty-state.component';\nimport { ComponentRendererComponent } from '../component-renderer/component-renderer.component';\nimport { PaginationComponent } from '../pagination/pagination.component';\nimport { FilterComponent } from '../filter/filter.component';\n\n/**\n * @description A versatile list component that supports various data display modes.\n * @summary This component provides a flexible way to display lists of data with support\n * for infinite scrolling, pagination, searching, and custom item rendering. It can fetch\n * data from various sources including models, functions, or direct data input.\n *\n * The component supports two main display types:\n * 1. Infinite scrolling - Loads more data as the user scrolls\n * 2. Pagination - Displays data in pages with navigation controls\n *\n * Additional features include:\n * - Pull-to-refresh functionality\n * - Search filtering\n * - Empty state customization\n * - Custom item rendering\n * - Event emission for interactions\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant L as ListComponent\n * participant D as Data Source\n * participant E as External Components\n *\n * U->>L: Initialize component\n * L->>L: ngOnInit()\n * L->>D: Request initial data\n * D-->>L: Return data\n * L->>L: Process and display data\n *\n * alt User scrolls (Infinite mode)\n * U->>L: Scroll to bottom\n * L->>D: Request more data\n * D-->>L: Return additional data\n * L->>L: Append to existing data\n * else User changes page (Paginated mode)\n * U->>L: Click page number\n * L->>L: handlePaginate()\n * L->>D: Request data for page\n * D-->>L: Return page data\n * L->>L: Replace displayed data\n * end\n *\n * alt User searches\n * U->>L: Enter search term\n * L->>L: handleSearch()\n * L->>D: Filter data by search term\n * D-->>L: Return filtered data\n * L->>L: Update displayed data\n * end\n *\n * alt User clicks item\n * U->>L: Click list item\n * L->>L: handleClick()\n * L->>E: Emit clickEvent\n * end\n *\n * @example\n * <ngx-decaf-list\n * [source]=\"dataSource\"\n * [limit]=\"10\"\n * [type]=\"'infinite'\"\n * [showSearchbar]=\"true\"\n * (clickEvent)=\"handleItemClick($event)\"\n * (refreshEvent)=\"handleRefresh($event)\">\n * </ngx-decaf-list>\n *\n * @extends {NgxBaseComponentDirective}\n * @implements {OnInit}\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-list',\n templateUrl: './list.component.html',\n styleUrls: ['./list.component.scss'],\n standalone: true,\n imports: [\n TranslatePipe,\n IonRefresher,\n IonButton,\n PaginationComponent,\n IonList,\n IonItem,\n IonThumbnail,\n IonSkeletonText,\n IonLabel,\n IonText,\n IonRefresherContent,\n IonInfiniteScroll,\n IonInfiniteScrollContent,\n IonThumbnail,\n IonSkeletonText,\n SearchbarComponent,\n EmptyStateComponent,\n FilterComponent,\n ComponentRendererComponent\n ],\n host: {'[attr.id]': 'uid'},\n})\nexport class ListComponent extends NgxComponentDirective implements OnInit, OnDestroy {\n\n /**\n * @description The display mode for the list component.\n * @summary Determines how the list data is loaded and displayed. Options include:\n * - INFINITE: Loads more data as the user scrolls (infinite scrolling)\n * - PAGINATED: Displays data in pages with navigation controls\n *\n * @type {ListComponentsTypes}\n * @default ListComponentsTypes.INFINITE\n * @memberOf ListComponent\n */\n @Input()\n type: ListComponentsTypes = ListComponentsTypes.INFINITE;\n\n /**\n * @description Controls the visibility of the search bar.\n * @summary When set to true, displays a search bar at the top of the list that allows\n * users to filter the list items. The search functionality works by filtering the\n * existing data or by triggering a new data fetch with search parameters.\n *\n * @type {boolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n showSearchbar: boolean = true;\n\n /**\n * @description Direct data input for the list component.\n * @summary Provides a way to directly pass data to the list component instead of\n * fetching it from a source. When both data and source are provided, the component\n * will use the source to fetch data only if the data array is empty.\n *\n * @type {KeyValue[] | undefined}\n * @default undefined\n * @memberOf ListComponent\n */\n @Input()\n data?: KeyValue[] | undefined = undefined;\n\n /**\n * @description The data source for the list component.\n * @summary Specifies where the list should fetch its data from. This can be either:\n * - A string URL or endpoint identifier\n * - A function that returns data when called\n * The component will call this source when it needs to load or refresh data.\n *\n * @type {string | FunctionLike}\n * @required\n * @memberOf ListComponent\n */\n @Input()\n source!: string | FunctionLike;\n\n /**\n * @description The starting index for data fetching.\n * @summary Specifies the index from which to start fetching data. This is used\n * for pagination and infinite scrolling to determine which subset of data to load.\n *\n * @type {number}\n * @default 0\n * @memberOf ListComponent\n */\n @Input()\n start: number = 0;\n\n /**\n * @description The number of items to fetch per page or load operation.\n * @summary Determines how many items are loaded at once during pagination or\n * infinite scrolling. This affects the size of data chunks requested from the source.\n *\n * @type {number}\n * @default 10\n * @memberOf ListComponent\n */\n @Input()\n limit: number = 10;\n\n /**\n * @description Controls whether more data can be loaded.\n * @summary When set to true, the component will allow loading additional data\n * through infinite scrolling or pagination. When false, the component will not\n * attempt to load more data beyond what is initially displayed.\n *\n * @type {boolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n loadMoreData: boolean = true\n\n /**\n * @description The style of dividing lines between list items.\n * @summary Determines how dividing lines appear between list items. Options include:\n * - \"inset\": Lines are inset from the edges\n * - \"full\": Lines extend the full width\n * - \"none\": No dividing lines\n *\n * @type {\"inset\" | \"full\" | \"none\"}\n * @default \"full\"\n * @memberOf ListComponent\n */\n @Input()\n lines: \"inset\" | \"full\" | \"none\" = \"full\";\n\n /**\n * @description Controls whether the list has inset styling.\n * @summary When set to true, the list will have inset styling with rounded corners\n * and margin around the edges. This creates a card-like appearance for the list.\n *\n * @type {boolean}\n * @default false\n * @memberOf ListComponent\n */\n @Input()\n inset: boolean = false;\n\n /**\n * @description The threshold for triggering infinite scroll loading.\n * @summary Specifies how close to the bottom of the list the user must scroll\n * before the component triggers loading of additional data. This is expressed\n * as a percentage of the list height.\n *\n * @type {string}\n * @default \"15%\"\n * @memberOf ListComponent\n */\n @Input()\n scrollThreshold: string = \"15%\";\n\n /**\n * @description The position where new items are added during infinite scrolling.\n * @summary Determines whether new items are added to the top or bottom of the list\n * when loading more data through infinite scrolling.\n *\n * @type {\"bottom\" | \"top\"}\n * @default \"bottom\"\n * @memberOf ListComponent\n */\n @Input()\n scrollPosition: \"bottom\" | \"top\" = \"bottom\";\n\n /**\n * @description Custom text to display during loading operations.\n * @summary Specifies the text shown in the loading indicator when the component\n * is fetching data. If not provided, a default loading message will be used.\n *\n * @type {string | undefined}\n * @memberOf ListComponent\n */\n @Input()\n loadingText?: string;\n\n /**\n * @description Controls the visibility of the pull-to-refresh feature.\n * @summary When set to true, enables the pull-to-refresh functionality that allows\n * users to refresh the list data by pulling down from the top of the list.\n *\n * @type {boolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n showRefresher: boolean = true;\n\n\n /**\n * @description Controls the visibility of the create button.\n * @summary When set to true, displays a button to create new items in the list.\n *\n * @type {boolean}\n * @default false\n * @memberOf ListComponent\n */\n @Input()\n createButton: boolean = false;\n\n /**\n * @description The type of spinner to display during loading operations.\n * @summary Specifies the visual style of the loading spinner shown during data\n * fetching operations. Uses Ionic's predefined spinner types.\n *\n * @type {SpinnerTypes}\n * @default \"circular\"\n * @memberOf ListComponent\n */\n @Input()\n loadingSpinner: SpinnerTypes = \"circular\";\n\n // /**\n // * @description Query parameters for data fetching.\n // * @summary Specifies additional query parameters to use when fetching data from\n // * the source. This can be provided as a string (JSON) or a direct object.\n // *\n // * @type {string | KeyValue | undefined}\n // * @memberOf ListComponent\n // */\n // @Input()\n // query?: string | KeyValue;\n\n /**\n * @description Controls whether the filtering functionality is enabled.\n * @summary When set to true, enables the filter component that allows users to create\n * complex search criteria with multiple field filters, conditions, and values.\n * When false, disables the filter interface entirely.\n *\n * @type {boolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n enableFilter: boolean = true;\n\n /**\n * @description Sorting parameters for data fetching.\n * @summary Specifies how the fetched data should be sorted. This can be provided\n * as a string (field name with optional direction) or a direct object.\n *\n * @type {string | KeyValue | undefined}\n * @memberOf ListComponent\n */\n @Input()\n sortDirection: OrderDirection = OrderDirection.DSC;\n\n\n /**\n * @description Sorting parameters for data fetching.\n * @summary Specifies how the fetched data should be sorted. This can be provided\n * as a string (field name with optional direction) or a direct object.\n *\n * @type {string | KeyValue | undefined}\n * @memberOf ListComponent\n */\n @Input()\n sortBy!: string;\n\n\n /**\n * @description Controls whether sorting functionality is disabled.\n * @summary When set to true, disables the sort controls and prevents users from\n * changing the sort order or field. The list will maintain its default or\n * programmatically set sort configuration without user interaction.\n *\n * @type {boolean}\n * @default false\n * @memberOf ListComponent\n */\n @Input()\n disableSort: boolean = false;\n\n\n /**\n * @description Configuration for the empty state display.\n * @summary Customizes how the empty state is displayed when no data is available.\n * This includes the title, subtitle, button text, icon, and navigation link.\n *\n * @type {Partial<IListEmptyOptions>}\n * @default {\n * title: 'empty.title',\n * subtitle: 'empty.subtitle',\n * showButton: false,\n * icon: 'alert-circle-outline',\n * buttonText: 'locale.empty.button',\n * link: ''\n * }\n * @memberOf ListComponent\n */\n @Input()\n empty: Partial<IListEmptyOptions> = {};\n\n /**\n * @description The current page number in paginated mode.\n * @summary Tracks which page is currently being displayed when the component\n * is in paginated mode. This is used for pagination controls and data fetching.\n *\n * @type {number}\n * @default 1\n * @memberOf ListComponent\n */\n page: number = 1;\n\n /**\n * @description The total number of pages available.\n * @summary Stores the calculated total number of pages based on the data size\n * and limit. This is used for pagination controls and boundary checking.\n *\n * @type {number}\n * @memberOf ListComponent\n */\n pages!: number;\n\n /**\n * @description Indicates whether a refresh operation is in progress.\n * @summary When true, the component is currently fetching new data. This is used\n * to control loading indicators and prevent duplicate refresh operations from\n * being triggered simultaneously.\n *\n * @type {boolean}\n * @default false\n * @memberOf ListComponent\n */\n refreshing: boolean = false;\n\n /**\n * @description Array used for rendering skeleton loading placeholders.\n * @summary Contains placeholder items that are displayed during data loading.\n * The length of this array determines how many skeleton items are shown.\n *\n * @type {string[]}\n * @default new Array(2)\n * @memberOf ListComponent\n */\n skeletonData: string[] = new Array(2);\n\n /**\n * @description The processed list items ready for display.\n * @summary Stores the current set of items being displayed in the list after\n * processing from the raw data source. This may be a subset of the full data\n * when using pagination or infinite scrolling.\n *\n * @type {KeyValue[]}\n * @memberOf ListComponent\n */\n items!: KeyValue[];\n\n /**\n * @description The current search query value.\n * @summary Stores the text entered in the search bar. This is used to filter\n * the list data or to send as a search parameter when fetching new data.\n *\n * @type {string | undefined}\n * @memberOf ListComponent\n */\n searchValue?: string | IFilterQuery | undefined;\n\n\n searching: boolean = false;\n\n /**\n * @description A paginator object for handling pagination operations.\n * @summary Provides a paginator object that can be used to retrieve and navigate\n * through data in chunks, reducing memory usage and improving performance.\n *\n * The paginator object is initialized in the `ngOnInit` lifecycle hook and is\n * used to fetch and display data in the pagination component. It is an instance\n * of the `Paginator` class from the `@decaf-ts/core` package, which provides\n * methods for querying and manipulating paginated data.\n *\n * @type {Paginator<Model>}\n * @memberOf PaginationComponent\n */\n paginator!: Paginator<Model> | undefined;\n\n /**\n * @description The last page number that was displayed.\n * @summary Keeps track of the previously displayed page number, which is useful\n * for handling navigation and search operations in paginated mode.\n *\n * @type {number}\n * @default 1\n * @memberOf ListComponent\n */\n lastPage: number = 1\n\n /**\n * @description Event emitter for refresh operations.\n * @summary Emits an event when the list data is refreshed, either through pull-to-refresh\n * or programmatic refresh. The event includes the refreshed data and component information.\n *\n * @type {EventEmitter<IBaseCustomEvent>}\n * @memberOf ListComponent\n */\n @Output()\n refreshEvent: EventEmitter<IBaseCustomEvent> = new EventEmitter<IBaseCustomEvent>();\n\n /**\n * @description Event emitter for item click interactions.\n * @summary Emits an event when a list item is clicked. The event includes the data\n * of the clicked item, allowing parent components to respond to the interaction.\n *\n * @type {EventEmitter<KeyValue>}\n * @memberOf ListComponent\n */\n @Output()\n clickEvent: EventEmitter<ListItemCustomEvent|IBaseCustomEvent> = new EventEmitter<ListItemCustomEvent|IBaseCustomEvent>();\n\n /**\n * @description Subject for debouncing click events.\n * @summary Uses RxJS Subject to collect click events and emit them after a debounce\n * period. This prevents multiple rapid clicks from triggering multiple events.\n *\n * @private\n * @type {Subject<CustomEvent | ListItemCustomEvent | IBaseCustomEvent>}\n * @memberOf ListComponent\n */\n private clickItemSubject: Subject<CustomEvent | ListItemCustomEvent | IBaseCustomEvent> = new Subject<CustomEvent | ListItemCustomEvent | IBaseCustomEvent>();\n\n\n /**\n * @description Subject for debouncing repository observation events.\n * @summary RxJS Subject that collects repository change events and emits them after\n * a debounce period. This prevents multiple rapid repository changes from triggering\n * multiple list refresh operations, improving performance and user experience.\n *\n * @private\n * @type {Subject<any>}\n * @memberOf ListComponent\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private observerSubjet: Subject<any> = new Subject<any>();\n\n /**\n * @description Observer object for repository change notifications.\n * @summary Implements the Observer interface to receive notifications when the\n * underlying data repository changes. This enables automatic list updates when\n * data is created, updated, or deleted through the repository.\n *\n * @private\n * @type {Observer}\n * @memberOf ListComponent\n */\n private observer!: Observer;\n\n /**\n * @description List of available indexes for data querying and filtering.\n * @summary Provides a list of index names that can be used to optimize data querying and filtering\n * operations, especially in scenarios with large datasets.\n *\n * Indexes can significantly improve the performance of data retrieval by allowing the database\n * to quickly locate and retrieve relevant data based on indexed fields.\n *\n * @type {string[]}\n * @default []\n * @memberOf ListComponent\n */\n indexes!: string[];\n\n /**\n * @description Initializes a new instance of the ListComponent.\n * @summary Creates a new ListComponent and sets up the base component with the appropriate\n * component name. This constructor is called when Angular instantiates the component and\n * before any input properties are set. It passes the component name to the parent class\n * constructor to enable proper localization and component identification.\n *\n * The constructor is intentionally minimal, with most initialization logic deferred to\n * the ngOnInit lifecycle hook. This follows Angular best practices by keeping the constructor\n * focused on dependency injection and basic setup, while complex initialization that depends\n * on input properties is handled in ngOnInit.\n *\n * @memberOf ListComponent\n */\n constructor() {\n super(\"ListComponent\");\n }\n\n\n /**\n * @description Initializes the component after Angular sets the input properties.\n * @summary Sets up the component by initializing event subscriptions, processing boolean\n * inputs, and loading the initial data. This method prepares the component for user\n * interaction by ensuring all properties are properly initialized and data is loaded.\n *\n * @returns {Promise<void>}\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant L as ListComponent\n * participant D as Data Source\n *\n * A->>L: ngOnInit()\n * L->>L: Set up click event debouncing\n * L->>L: Process boolean inputs\n * L->>L: Configure component based on inputs\n * L->>L: refresh()\n * L->>D: Request initial data\n * D-->>L: Return data\n * L->>L: Process and display data\n * L->>L: Configure empty state if needed\n * L->>L: initialize()\n *\n * @memberOf ListComponent\n */\n async ngOnInit(): Promise<void> {\n this.observer = { refresh: async (... args: unknown[]): Promise<void> => this.observeRepository(...args)}\n\n this.clickItemSubject.pipe(debounceTime(100)).subscribe(event => this.clickEventEmit(event as ListItemCustomEvent | IBaseCustomEvent));\n this.observerSubjet.pipe(debounceTime(100)).subscribe(args => this.handleObserveEvent(args[0], args[1], args[2]));\n this.limit = Number(this.limit);\n this.start = Number(this.start);\n\n this.enableFilter = stringToBoolean(this.enableFilter);\n this.inset = stringToBoolean(this.inset);\n this.showRefresher = stringToBoolean(this.showRefresher);\n this.loadMoreData = stringToBoolean(this.loadMoreData);\n this.showSearchbar = stringToBoolean(this.showSearchbar);\n this.disableSort = stringToBoolean(this.disableSort);\n\n if(!this.operations || !this.operations.includes(OperationKeys.CREATE))\n this.createButton = false;\n\n if (typeof this.item?.['tag'] === 'boolean' && this.item?.['tag'] === true)\n this.item['tag'] = ComponentsTagNames.LIST_ITEM as string;\n this.empty = Object.assign({}, DefaultListEmptyOptions, this.empty);\n await this.refresh();\n if (!this.initialized)\n this.parseProps(this);\n this.initialized = true;\n if(this.isModalChild)\n this.changeDetectorRef.detectChanges();\n }\n\n /**\n * @description Cleans up resources when the component is destroyed.\n * @summary Performs cleanup operations when the component is being removed from the DOM.\n * This includes clearing references to models and data to prevent memory leaks.\n *\n * @returns {void}\n * @memberOf ListComponent\n */\n override ngOnDestroy(): void {\n super.ngOnDestroy();\n if (this._repository)\n (this._repository as DecafRepository<Model>).unObserve(this.observer);\n this.data = this.model = this._repository = this.paginator = undefined;\n }\n\n /**\n * @description Handles repository observation events with debouncing.\n * @summary Processes repository change notifications and routes them appropriately.\n * For CREATE events with a UID, handles them immediately. For other events,\n * passes them to the debounced observer subject to prevent excessive updates.\n *\n * @param {...unknown[]} args - The repository event arguments including table, event type, and UID\n * @returns {Promise<void>}\n * @memberOf ListComponent\n */\n async observeRepository(...args: unknown[]): Promise<void> {\n const [table, event, uid] = args;\n if (event === OperationKeys.CREATE && !!uid)\n return this.handleObserveEvent(table as string, event, uid as string | number);\n return this.observerSubjet.next(args);\n }\n\n /**\n * @description Handles specific repository events and updates the list accordingly.\n * @summary Processes repository change events (CREATE, UPDATE, DELETE) and performs\n * the appropriate list operations. This includes adding new items, updating existing\n * ones, or removing deleted items from the list display.\n *\n * @param {string} table - The table/model name that changed\n * @param {OperationKeys} event - The type of operation (CREATE, UPDATE, DELETE)\n * @param {string | number} uid - The unique identifier of the affected item\n * @returns {Promise<void>}\n * @memberOf ListComponent\n */\n async handleObserveEvent(table: string, event: OperationKeys, uid: string | number): Promise<void> {\n if (event === OperationKeys.CREATE) {\n if (uid) {\n await this.handleCreate(uid);\n } else {\n await this.refresh(true);\n }\n } else {\n if (event === OperationKeys.UPDATE)\n await this.handleUpdate(uid);\n if (event === OperationKeys.DELETE)\n this.handleDelete(uid);\n this.refreshEventEmit();\n }\n }\n\n\n /**\n * @description Function for tracking items in the list.\n * @summary Provides a tracking function for the `*ngFor` directive in the component template.\n * This function is used to identify and control the rendering of items in the list,\n * preventing duplicate or unnecessary rendering.\n *\n * The `trackItemFn` function takes two parameters: `index` (the index of the item in the list)\n * and `item` (the actual item from the list). It returns the tracking key, which in this case\n * is the union of the `uid` of the item with the model name.\n *\n * @param {number} index - The index of the item in the list.\n\n * @param {KeyValue | string | number} item - The actual item from the list.\n * @returns {string | number} The tracking key for the item.\n * @memberOf ListComponent\n */\n override trackItemFn(index: number, item: KeyValue | string | number): string | number {\n return `${ (item as KeyValue)?.['uid'] || (item as KeyValue)?.[this.pk]}-${index}`;\n }\n\n\n /**\n * Handles the create event from the repository.\n *\n * @param {string | number} uid - The ID of the item to create.\n * @returns {Promise<void>} A promise that resolves when the item is created and added to the list.\n */\n async handleCreate(uid: string | number): Promise<void> {\n const result = await this._repository?.read(uid);\n const item = this.mapResults([result as KeyValue])[0];\n this.items = this.data = [item, ...this.items || []];\n }\n\n\n /**\n * @description Handles the update event from the repository.\n * @summary Updates the list item with the specified ID based on the new data.\n *\n * @param {string | number} uid - The ID of the item to update\n * @returns {Promise<void>}\n * @private\n * @memberOf ListComponent\n */\n async handleUpdate(uid: string | number): Promise<void> {\n const item: KeyValue = this.itemMapper(await this._repository?.read(uid) || {}, this.mapper);\n this.data = [];\n for(const key in this.items as KeyValue[]) {\n const child = this.items[key] as KeyValue;\n if (child['uid'] === item['uid']) {\n this.items[key] = Object.assign({}, child, item);\n break;\n }\n }\n setTimeout(() => {\n this.data = [ ...this.items];\n }, 0);\n }\n\n /**\n * @description Removes an item from the list by ID.\n * @summary Filters out an item with the specified ID from the data array and\n * refreshes the list display. This is typically used after a delete operation.\n *\n * @param {string} uid - The ID of the item to delete\n * @param {string} pk - The primary key field name\n * @returns {Promise<void>}\n *\n * @memberOf ListComponent\n */\n handleDelete(uid: string | number, pk?: string): void {\n if (!pk)\n pk = this.pk;\n this.items = this.data?.filter((item: KeyValue) => item['uid'] !== uid) || [];\n }\n\n\n /**\n * @description Handles click events from list items.\n * @summary Listens for global ListItemClickEvent events and passes them to the\n * debounced click subject. This allows the component to respond to clicks on\n * list items regardless of where they originate from.\n *\n * @param {ListItemCustomEvent | IBaseCustomEvent} event - The click event\n * @returns {void}\n *\n * @memberOf ListComponent\n */\n @HostListener('window:ListItemClickEvent', ['$event'])\n handleClick(event: ListItemCustomEvent | IBaseCustomEvent): void {\n this.clickItemSubject.next(event);\n }\n\n /**\n * @description Handles search events from the search bar.\n * @summary Processes search queries from the search bar component, updating the\n * displayed data based on the search term. The behavior differs between infinite\n * and paginated modes to provide the best user experience for each mode.\n *\n * @param {string | undefined} value - The search term or undefined to clear search\n * @returns {Promise<void>}\n *\n * @mermaid\n * flowchart TD\n * A[Search Event] --> B{Type is Infinite?}\n * B -->|Yes| C[Disable loadMoreData]\n * B -->|No| D[Enable loadMoreData]\n * C --> E{Search value undefined?}\n * E -->|Yes| F[Enable loadMoreData]\n * E -->|No| G[Store search value]\n * D --> G\n * F --> H[Reset page to 1]\n * G --> I[Refresh data]\n * H --> I\n *\n * @memberOf ListComponent\n */\n @HostListener('window:searchbarEvent', ['$event'])\n async handleSearch(value: string | IFilterQuery | undefined): Promise<void> {\n this.searching = value !== undefined;\n\n if (this.type === ListComponentsTypes.INFINITE) {\n this.loadMoreData = false;\n if (value === undefined) {\n this.loadMoreData = true;\n this.page = 1;\n }\n this.searchValue = value;\n if(this.isModalChild)\n this.changeDetectorRef.detectChanges();\n await this.refresh(true);\n\n } else {\n this.loadMoreData = true;\n this.searchValue = value;\n if (value === undefined)\n this.page = this.lastPage;\n await this.refresh(true);\n }\n }\n\n\n /**\n * @description Handles filter events from the filter component.\n * @summary Processes filter queries from the filter component and applies them\n * to the list data. This method acts as a bridge between the filter component\n * and the search functionality, converting filter queries into search operations.\n *\n * @param {IFilterQuery | undefined} value - The filter query object or undefined to clear filters\n * @returns {Promise<void>}\n * @memberOf ListComponent\n */\n async handleFilter(value: IFilterQuery | undefined): Promise<void> {\n await this.handleSearch(value);\n }\n\n /**\n * @description Clears the current search and resets the list.\n * @summary Convenience method that clears the search by calling handleSearch\n * with undefined. This resets the list to show all data without filtering.\n *\n * @returns {Promise<void>}\n * @memberOf ListComponent\n */\n async clearSearch(): Promise<void> {\n await this.handleSearch(undefined);\n if(this.isModalChild)\n this.changeDetectorRef.detectChanges();\n }\n\n /**\n * @description Emits a refresh event with the current data.\n * @summary Creates and emits a refresh event containing the current list data.\n * This notifies parent components that the list data has been refreshed.\n *\n * @param {KeyValue[]} [data] - Optional data to include in the event\n * @returns {void}\n *\n * @memberOf ListComponent\n */\n refreshEventEmit(data?: KeyValue[]): void {\n if (!data)\n data = this.items;\n this.skeletonData = new Array(1);\n this.refreshEvent.emit({\n name: ComponentEventNames.REFRESH,\n data: data || [],\n component: this.componentName\n });\n }\n\n /**\n * @description Emits a click event for a list item.\n * @summary Processes and emits a click event when a list item is clicked.\n * This extracts the relevant data from the event and passes it to parent components.\n *\n * @private\n * @param {ListItemCustomEvent | IBaseCustomEvent} event - The click event\n * @returns {void}\n *\n * @memberOf ListComponent\n */\n private clickEventEmit(event: ListItemCustomEvent | IBaseCustomEvent): void {\n this.clickEvent.emit(event);\n }\n\n /**\n * @description Refreshes the list data from the configured source.\n * @summary This method handles both initial data loading and subsequent refresh operations,\n * including pull-to-refresh and infinite scrolling. It manages the data fetching process,\n * updates the component's state, and handles pagination or infinite scrolling logic based\n * on the component's configuration.\n *\n * The method performs the following steps:\n * 1. Sets the refreshing flag to indicate a data fetch is in progress\n * 2. Calculates the appropriate start and limit values based on pagination settings\n * 3. Fetches data from the appropriate source (model or request)\n * 4. Updates the component's data and emits a refresh event\n * 5. Handles pagination or infinite scrolling state updates\n * 6. Completes any provided event (like InfiniteScrollCustomEvent)\n *\n * @param {InfiniteScrollCustomEvent | RefresherCustomEvent | boolean} event - The event that triggered the refresh,\n * or a boolean flag indicating if this is a forced refresh\n * @returns {Promise<void>} A promise that resolves when the refresh operation is complete\n *\n * @mermaid\n * sequenceDiagram\n * participant L as ListComponent\n * participant D as Data Source\n * participant E as Event System\n *\n * L->>L: refresh(event)\n * L->>L: Set refreshing flag\n * L->>L: Calculate start and limit\n * alt Using model\n * L->>D: getFromModel(force, start, limit)\n * D-->>L: Return data\n * else Using request\n * L->>D: getFromRequest(force, start, limit)\n * D-->>L: Return data\n * end\n * L->>E: refreshEventEmit()\n * alt Infinite scrolling mode\n * L->>L: Check if reached last page\n * alt Last page reached\n * L->>L: Complete scroll event\n * L->>L: Disable loadMoreData\n * else More pages available\n * L->>L: Increment page number\n * L->>L: Complete scroll event after delay\n * end\n * else Paginated mode\n * L->>L: Clear refreshing flag after delay\n * end\n *\n * @memberOf ListComponent\n */\n @HostListener('window:BackButtonNavigationEndEvent', ['$event'])\n async refresh(event: InfiniteScrollCustomEvent | RefresherCustomEvent | boolean = false): Promise<void> {\n // if (typeof force !== 'boolean' && force.type === ComponentEventNames.BACK_BUTTON_NAVIGATION) {\n // const {refresh} = (force as CustomEvent).detail;\n // if (!refresh)\n // return false;\n // }\n this.refreshing = true;\n const start: number = this.page > 1 ? (this.page - 1) * this.limit : this.start;\n const limit: number = (this.page * (this.limit > 12 ? 12 : this.limit));\n\n this.data = !this.model ?\n await this.getFromRequest(!!event, start, limit)\n : await this.getFromModel(!!event) as KeyValue[];\n\n\n if (this.type === ListComponentsTypes.INFINITE) {\n if (this.page === this.pages) {\n if ((event as InfiniteScrollCustomEvent)?.target)\n (event as InfiniteScrollCustomEvent).target.complete();\n this.loadMoreData = false;\n } else {\n this.page += 1;\n this.refreshing = false;\n setTimeout(() => {\n if ((event as InfiniteScrollCustomEvent)?.target && (event as CustomEvent)?.type !== ComponentEventNames.BACK_BUTTON_NAVIGATION)\n (event as InfiniteScrollCustomEvent).target.complete();\n }, 200);\n }\n } else {\n setTimeout(() => {\n this.refreshing = false;\n }, 200)\n }\n }\n\n /**\n * @description Handles pagination events from the pagination component.\n * @summary Processes pagination events by updating the current page number and\n * refreshing the list data to display the selected page. This method is called\n * when a user interacts with the pagination controls to navigate between pages.\n *\n * @param {IPaginationCustomEvent} event - The pagination event containing page information\n * @returns {void}\n *\n * @memberOf ListComponent\n */\nhandlePaginate(event: IPaginationCustomEvent): void {\n const { page} = event.data;\n this.page = page;\n this.refresh(true);\n}\n\n/**\n * @description Handles pull-to-refresh events from the refresher component.\n * @summary Processes refresh events triggered by the user pulling down on the list\n * or by programmatic refresh requests. This method refreshes the list data and\n * completes the refresher animation when the data is loaded.\n *\n * @param {InfiniteScrollCustomEvent | CustomEvent} [event] - The refresh event\n * @returns {Promise<void>} A promise that resolves when the refresh operation is complete\n *\n * @memberOf ListComponent\n */\nasync handleRefresh(event?: InfiniteScrollCustomEvent | CustomEvent): Promise<void> {\n await this.refresh(event as InfiniteScrollCustomEvent || true);\n if (event instanceof CustomEvent)\n setTimeout(() => {\n // Any calls to load data go here\n (event.target as HTMLIonRefresherElement).complete();\n }, 400);\n}\n\n/**\n * @description Filters data based on a search string.\n * @summary Processes the current data array to find items that match the provided\n * search string. This uses the arrayQueryByString utility to perform the filtering\n * across all properties of the items.\n *\n * @param {KeyValue[]} results - The array of items to search through\n * @param {string} search - The search string to filter by\n * @returns {KeyValue[]} A promise that resolves to the filtered array of items\n *\n * @memberOf ListComponent\n */\n parseSearchResults(results: KeyValue[], search: string): KeyValue[] {\n const filtered = results.filter((item: KeyValue) =>\n Object.values(item).some(v => {\n if(v.toString().toLowerCase().includes((search as string)?.toLowerCase()))\n return v;\n })\n );\n return filtered;\n }\n\n/**\n * @description Fetches data from a request source.\n * @summary Retrieves data from the configured source function or URL, processes it,\n * and updates the component's data state. This method handles both initial data loading\n * and subsequent refresh operations when using an external data source rather than a model.\n *\n * @param {boolean} force - Whether to force a refresh even if data already exists\n * @param {number} start - The starting index for pagination\n * @param {number} limit - The maximum number of items to retrieve\n * @returns {Promise<KeyValue[]>} A promise that resolves to the fetched data\n *\n * @memberOf ListComponent\n */\nasync getFromRequest(force: boolean = false, start: number, limit: number): Promise<KeyValue[]> {\n let data: KeyValue[] = [...this.data || []];\n\n if (!this.data?.length || force || (this.searchValue as string)?.length || !!(this.searchValue as IFilterQuery)) {\n // (self.data as ListItem[]) = [];\n if (!(this.searchValue as string)?.length && !(this.searchValue as IFilterQuery)) {\n if (!this.source && !this.data?.length) {\n this.log.info('No data and source passed to infinite list');\n return [];\n }\n if (this.source instanceof Function) {\n data = await this.source() as KeyValue[];\n if (!Array.isArray(data))\n data = data?.['response']?.['data'] || data?.['results'] || [];\n }\n\n if(!data?.length && this.data?.length)\n data = this.data as KeyValue[];\n this.data = [... await this.parseResult(data)];\n if (this.data?.length)\n this.items = this.type === ListComponentsTypes.INFINITE ?\n (this.items || []).concat([...this.data.slice(start, limit)]) : [...data.slice(start, limit) as KeyValue[]];\n } else {\n const data = await this.parseResult(this.parseSearchResults(this.data as [], this.searchValue as string));\n this.items = [...data];\n if(this.isModalChild)\n this.changeDetectorRef.detectChanges();\n }\n } else {\n const data = [... await this.parseResult(this.data as [])];\n this.items = this.type === ListComponentsTypes.INFINITE ? [...(this.items || []), ...(data || [])] : [...(data || [])];\n if(this.isModalChild)\n this.changeDetectorRef.detectChanges();\n }\n\n if (this.loadMoreData && this.type === ListComponentsTypes.PAGINATED)\n this.getMoreData(this.data?.length || 0);\n return this.data || [] as KeyValue[];\n}\n\n/**\n * @description Fetches data from a model source.\n * @summary Retrieves data from the configured model using its pagination or find methods,\n * processes it, and updates the component's data state. This method handles both initial\n * data loading and subsequent refresh operations when using a model as the data source.\n *\n * @param {boolean} force - Whether to force a refresh even if data already exists\n * @param {number} start - The starting index for pagination\n * @param {number} limit - The maximum number of items to retrieve\n * @returns {Promise<KeyValue[]>} A promise that resolves to the fetched data\n *\n * @memberOf ListComponent\n */\nasync getFromModel(force: boolean = false): Promise<KeyValue[]> {\n let data = [ ... this.data || []];\n let request: KeyValue[] = [];\n\n // getting model repository\n if (!this._repository) {\n this._repository = this.repository;\n if (this.model instanceof Model && this._repository)\n (this._repository as DecafRepository<Model>).observe(this.observer);\n }\n\n const repo = this._repository as DecafRepository<Model>;\n if (!this.data?.length || force || (this.searchValue as string)?.length || !!(this.searchValue as IFilterQuery)) {\n try {\n if (!(this.searchValue as string)?.length && !(this.searchValue as IFilterQuery)) {\n (this.data as KeyValue[]) = [];\n // const rawQuery = this.parseQuery(self.model as Repository<Model>, start, limit);\n // request = this.parseResult(await (this.model as any)?.paginate(start, limit));\n if (!this.paginator) {\n this.paginator = await repo\n .select()\n .orderBy([this.pk as keyof Model, this.sortDirection])\n .paginate(this.limit);\n }\n request = await this.parseResult(this.paginator);\n } else {\n\n if (!this.indexes)\n this.indexes = (Object.values(this.mapper) || [this.pk]);\n\n const condition = this.parseConditions(this.searchValue as string | number | IFilterQuery);\n this.changeDetectorRef.detectChanges();\n request = await this.parseResult(await repo.query(condition, (this.sortBy || this.pk) as keyof Model, this.sortDirection));\n data = [];\n this.changeDetectorRef.detectChanges();\n }\n data = this.type === ListComponentsTypes.INFINITE ? [... (data).concat(request)] : [...request];\n } catch(error: unknown) {\n this.log.error((error as Error)?.message || `Unable to find ${this.model} on registry. Return empty array from component`);\n }\n }\n\n if (data?.length) {\n if (this.searchValue) {\n this.items = [...data];\n if (this.items?.length <= this.limit)\n this.loadMoreData = false;\n } else {\n this.items = [...data];\n }\n }\n if (this.type === ListComponentsTypes.PAGINATED && this.paginator)\n this.getMoreData(this.paginator.total);\n return data || [] as KeyValue[];\n}\n\n/**\n * @description Converts search values or filter queries into database conditions.\n * @summary Transforms search input or complex filter queries into Condition objects\n * that can be used for database querying. Handles both simple string/number searches\n * across indexed fields and complex filter queries with multiple criteria.\n *\n * For simple searches (string/number):\n * - Creates conditions that search across all indexed fields\n * - Uses equality for numeric values and regex for string values\n * - Combines conditions with OR logic to search multiple fields\n *\n * For complex filter queries:\n * - Processes each filter item with its specific condition type\n * - Supports Equal, Not Equal, Contains, Not Contains, Greater Than, Less Than\n * - Updates sort configuration based on the filter query\n * - Combines multiple filter conditions with OR logic\n *\n * @param {string | number | IFilterQuery} value - The search value or filter query object\n * @returns {Condition<Model>} A Condition object for database querying\n * @memberOf ListComponent\n */\nparseConditions(value: string | number | IFilterQuery): Condition<Model> {\n let _condition: Condition<Model>;\n if (typeof value === Primitives.STRING || typeof value === Primitives.NUMBER) {\n _condition = Condition.attribute<Model>(this.pk as keyof Model).eq(!isNaN(value as number) ? Number(value) : value);\n for (const index of this.indexes) {\n if (index === this.pk)\n continue;\n let orCondition;\n if (!isNaN(value as number)) {\n orCondition = Condition.attribute<Model>(index as keyof Model).eq(Number(value));\n } else {\n orCondition = Condition.attribute<Model>(index as keyof Model).regexp(value as string);\n }\n _condition = _condition.or(orCondition);\n }\n } else {\n const {query, sort} = value as IFilterQuery;\n _condition = Condition.attribute<Model>(this.pk as keyof Model).dif ('null');\n\n if (query?.length)\n _condition = undefined as unknown as Condition<Model>;\n\n (query || []).forEach((item: IFilterQueryItem) => {\n const {value, condition, index} = item;\n let val = value as string | number;\n if (index === this.pk || !isNaN(val as number))\n val = Number(val);\n let orCondition;\n switch (condition) {\n case \"Equal\":\n orCondition = Condition.attribute<Model>(index as keyof Model).eq(val);\n break;\n case \"Not Equal\":\n orCondition = Condition.attribute<Model>(index as keyof Model).dif (val);\n break;\n case \"Not Contains\":\n orCondition = !Condition.attribute<Model>(index as keyof Model).regexp(new RegExp(`^(?!.*${val}).*$`));\n break;\n case \"Contains\":\n orCondition = Condition.attribute<Model>(index as keyof Model).regexp(val as string);\n break;\n case \"Greater Than\":\n orCondition = Condition.attribute<Model>(index as keyof Model).gte(val);\n break;\n case \"Less Than\":\n orCondition = Condition.attribute<Model>(index as keyof Model).lte(val);\n break;\n }\n _condition = (!_condition ?\n orCondition : _condition.and(orCondition as unknown as Condition<Model>)) as Condition<Model>;\n });\n\n this.sortBy = sort?.value as keyof Model || this.pk;\n this.sortDirection = sort?.direction || this.sortDirection;\n }\n return _condition as Condition<Model>;\n\n}\n\n/**\n * @description Processes query results into a standardized format.\n * @summary Handles different result formats from various data sources, extracting\n * pagination information when available and applying any configured data mapping.\n * This ensures consistent data structure regardless of the source.\n *\n * @protected\n * @param {KeyValue[] | Paginator} result - The raw query result\n * @returns {KeyValue[]} The processed array of items\n *\n * @memberOf ListComponent\n */\nprotected async parseResult(result: KeyValue[] | Paginator<Model>): Promise<KeyValue[]> {\n if (!Array.isArray(result) && ('page' in result && 'total' in result)) {\n const paginator = result as Paginator<Model>;\n try {\n result = await paginator.page(this.page);\n this.getMoreData(paginator.total);\n } catch(error: unknown) {\n this.log.info((error as Error)?.message || 'Unable to get page from paginator. Return empty array from component');\n result = [];\n }\n\n } else {\n this.getMoreData((result as KeyValue[])?.length || 0);\n }\n return (Object.keys(this.mapper || {}).length) ?\n this.mapResults(result) : result;\n}\n\n/**\n * @description Updates pagination state based on data length.\n * @summary Calculates whether more data is available and how many pages exist\n * based on the total number of items and the configured limit per page.\n * This information is used to control pagination UI and infinite scrolling behavior.\n *\n * @param {number} length - The total number of items available\n * @returns {void}\n *\n * @memberOf ListComponent\n */\ngetMoreData(length: number): void {\n if (this.type === ListComponentsTypes.INFINITE) {\n if (this.paginator)\n length = length * this.limit;\n if (length <= this.limit) {\n this.loadMoreData = false;\n } else {\n this.pages = Math.floor(length / this.limit);\n if ((this.pages * this.limit) < length)\n this.pages += 1;\n if (this.pages === 1)\n this.loadMoreData = false;\n }\n } else {\n this.pages = length;\n if (this.pages === 1)\n this.loadMoreData = false;\n }\n}\n\n/**\n * @description Maps a single item using the configured mapper.\n * @summary Transforms a data item according to the mapping configuration,\n * extracting nested properties and formatting values as needed. This allows\n * the component to display data in a format different from how it's stored.\n *\n * @protected\n * @param {KeyValue} item - The item to map\n * @param {KeyValue} mapper - The mapping configuration\n * @param {KeyValue} [props] - Additional properties to include\n * @returns {KeyValue} The mapped item\n *\n * @memberOf ListComponent\n */\nprotected itemMapper(item: KeyValue, mapper: KeyValue, props?: KeyValue): KeyValue {\n return Object.entries(mapper).reduce((accum: KeyValue, [key, value]) => {\n const arrayValue = value.split('.');\n if (!value) {\n accum[key] = value;\n } else {\n if (arrayValue.length === 1) {\n value = item?.[value] ? item[value] : \"\";\n // value = item?.[value] ? item[value] : value !== key ? value : \"\";\n if (isValidDate(value))\n value = `${formatDate(value)}`;\n accum[key] = value;\n } else {\n let val;\n\n for (const _value of arrayValue)\n val = !val\n ? item[_value]\n : (typeof val === 'string' ? JSON.parse(val) : val)[_value];\n\n\n if (isValidDate(new Date(val)))\n val = `${formatDate(val)}`;\n\n accum[key] = val === null || val === undefined ? value : val;\n }\n }\n return Object.assign({}, props || {}, accum);\n }, {});\n}\n\n/**\n * @description Maps all result items using the configured mapper.\n * @summary Applies the itemMapper to each item in the result set, adding\n * common properties like operations and route information. This transforms\n * the raw data into the format expected by the list item components.\n *\n * @param {KeyValue[]} data - The array of items to map\n * @returns {KeyValue[]} The array of mapped items\n *\n * @memberOf ListComponent\n */\n mapResults(data: KeyValue[]): KeyValue[] {\n if (!data || !data.length)\n return [];\n // passing uid as prop to mapper\n this.mapper = {... this.mapper, ... {uid: this.pk}};\n const props = Object.assign({\n operations: this.operations,\n route: this.route,\n ... Object.keys(this.item).reduce((acc: KeyValue, key: string) => {\n acc[key] = this.item[key];\n return acc;\n }, {}),\n // ... (!this.item.render ? {} : Object.keys(this.item).reduce((acc: KeyValue, key: string) => {\n // acc[key] = this.item[key as keyof IListItemProp];\n // return acc;\n // }, {}))\n });\n return data.reduce((accum: KeyValue[], curr) => {\n accum.push({... this.itemMapper(curr, this.mapper as KeyValue, props), ... {pk: this.pk}});\n return accum;\n }, []);\n }\n\n\n parseSearchValue() {\n if (typeof this.searchValue === Primitives.STRING)\n return this.searchValue || \"\";\n const searchValue = this.searchValue as IFilterQuery;\n return (searchValue?.query as IFilterQueryItem[]).map(item => `${item.index} ${item.condition} ${item.value}`).join(\", \");\n }\n}\n\n","\n@if (showRefresher) {\n <ion-refresher slot=\"fixed\" [pullFactor]=\"1\" [pullMin]=\"100\" [pullMax]=\"200\" (ionRefresh)=\"handleRefresh($event)\">\n <ion-refresher-content />\n </ion-refresher>\n}\n\n\n@if (showSearchbar) {\n <div [hidden]=\"!data?.length\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-grid-actions\">\n <div class=\"dcf-width-expand@m dcf-width-1-1\">\n @if (model && enableFilter) {\n @if (data?.length || searching) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n } @else {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n }\n </div>\n @if(createButton) {\n <div class=\"dcf-width-auto@m dcf-button-container dcf-width-1-1 dcf-flex-middle dcf-flex dcf-flex-center dcf-flex-right@m\">\n <div>\n <ion-button expand=\"block\" (click)=\"changeOperation(OperationKeys.CREATE)\">Create</ion-button>\n </div>\n </div>\n }\n </div>\n </div>\n}\n\n@if (initialized && data?.length) {\n <ion-list [id]=\"uid\" [inset]=\"inset\" [lines]=\"lines\">\n @if (item?.tag) {\n @for(child of items; track trackItemFn($index, child)) {\n <ngx-decaf-component-renderer\n [tag]=\"item.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]='{\n item: child,\n mapper: mapper,\n route: route\n }'>\n </ngx-decaf-component-renderer>\n }\n } @else {\n <ng-content></ng-content>\n }\n </ion-list>\n\n @if (loadMoreData) {\n @if (pages > 0 && type === 'paginated' && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n\n } @else {\n <ion-infinite-scroll\n [class]=\"searchValue?.length ? 'dcf-hidden' : ''\"\n\n [position]=\"scrollPosition\"\n [threshold]=\"scrollThreshold\"\n (ionInfinite)=\"handleRefresh($event)\">\n <ion-infinite-scroll-content [loadingSpinner]=\"loadingSpinner\" [loadingText]=\"loadingText\" />\n </ion-infinite-scroll>\n }\n }\n} @else {\n @if (refreshing) {\n @for(skl of skeletonData; track $index) {\n <ion-item>\n <ion-thumbnail slot=\"start\">\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n </ion-thumbnail>\n <ion-label>\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%;\"><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text></ion-text>\n </ion-label>\n </ion-item>\n }\n\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [model]=\"model\"\n [route]=\"route\"\n [borders]=\"borders\"\n [icon]=\"empty.icon\"\n className=\"dcf-empty-data\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\" />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"model\"\n [route]=\"route\"\n [borders]=\"borders\"\n className=\"empty-search\"\n [translatable]=\"true\"\n className=\"dcf-empty-data\"\n [title]=\"locale + '.search.title' | translate\"\n [subtitle]=\"locale + '.search.subtitle' | translate: {'0': parseSearchValue()}\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n}\n\n","/**\n * @module module:lib/components/list-item/list-item.component\n * @description List item component module.\n * @summary Exposes `ListItemComponent` which renders a single list item with\n * configurable icon, title, description, actions and navigation. The component\n * supports slide actions, popover menus and emits click events for parent\n * components to handle.\n *\n * @link {@link ListItemComponent}\n */\n\nimport { AfterViewInit, Component, ElementRef, EventEmitter, HostListener,Input, OnInit, Output, ViewChild } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport {\n IonButton,\n IonItem,\n IonLabel,\n IonList,\n IonContent,\n IonIcon,\n IonListHeader,\n IonPopover,\n IonItemSliding,\n IonItemOptions,\n IonItemOption\n} from '@ionic/angular/standalone';\nimport * as AllIcons from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { StringOrBoolean } from '../../engine/types';\nimport { getWindowWidth, windowEventEmitter, removeFocusTrap, stringToBoolean } from '../../utils/helpers';\nimport { ComponentEventNames } from '../../engine/constants';\nimport {ListItemCustomEvent} from '../../engine/interfaces';\nimport { Dynamic } from '../../engine/decorators';\nimport { NgxComponentDirective } from '../../engine/NgxComponentDirective';\n\n\n\n/**\n * @description A component for displaying a list item with various customization options.\n * @summary The ListItemComponent is an Angular component that extends NgxBaseComponentDirective. It provides a flexible and customizable list item interface with support for icons, buttons, and various text elements. The component also handles actions and navigation based on user interactions.\n *\n * @class\n * @extends NgxBaseComponentDirective\n *\n * @param {string} [lines='none'] - Determines the line style of the item. Can be 'inset', 'inseet', or 'none'.\n * @param {Record<string, any>} item - The data item to be displayed in the list item.\n * @param {string} icon - The name of the icon to be displayed.\n * @param {'start' | 'end'} [iconSlot='start'] - The position of the icon within the item.\n * @param {StringOrBoolean} [button=true] - Determines if the item should behave as a button.\n * @param {string} [title] - The main title of the list item.\n * @param {string} [description] - A description for the list item.\n * @param {string} [info] - Additional information for the list item.\n * @param {string} [subinfo] - Sub-information for the list item.\n *\n * @example\n * <ngx-decaf-list-item\n * [item]=\"dataItem\"\n * icon=\"star\"\n * title=\"Item Title\"\n * description=\"Item Description\"\n * (clickEvent)=\"handleItemClick($event)\">\n * </ngx-decaf-list-item>\n *\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant V as View\n * participant U as User\n * C->>V: Initialize component\n * V->>U: Display list item\n * U->>V: Click on item or action\n * V->>C: Trigger handleAction()\n * C->>C: Process action\n * C->>V: Update view or navigate\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-list-item',\n templateUrl: './list-item.component.html',\n styleUrls: ['./list-item.component.scss'],\n standalone: true,\n imports: [\n TranslatePipe,\n IonList,\n IonListHeader,\n IonItem,\n IonItemSliding,\n IonItemOptions,\n IonItemOption,\n IonIcon,\n IonLabel,\n IonButton,\n IonContent,\n IonPopover\n ],\n host: {'[attr.id]': 'uid'},\n})\nexport class ListItemComponent extends NgxComponentDirective implements OnInit, AfterViewInit {\n\n @ViewChild('component', { read: ElementRef, static: false })\n override component!: ElementRef;\n\n /**\n * @description Reference to the action menu popover component.\n * @summary ViewChild reference that provides access to the HTMLIonPopoverElement\n * used for displaying action menus. This reference is used to programmatically\n * control the popover, such as dismissing it when necessary.\n *\n * @type {HTMLIonPopoverElement}\n * @memberOf ListItemComponent\n */\n @ViewChild('actionMenuComponent')\n actionMenuComponent!: HTMLIonPopoverElement;\n\n /**\n * @description Controls the display of lines around the list item.\n * @summary Determines how lines are displayed around the list item borders.\n * 'inset' shows lines with padding, 'full' shows full-width lines, and 'none'\n * removes all lines. This affects the visual separation between list items.\n *\n * @type {'inset' | 'full' | 'none'}\n * @default 'inset'\n * @memberOf ListItemComponent\n */\n @Input()\n lines: 'inset' | 'full' | 'none' = 'full';\n\n /**\n * @description The data object associated with this list item.\n * @summary Contains the raw data that this list item represents. This object\n * is used to extract display information and for passing to event handlers\n * when the item is interacted with. It overrides the base item property.\n *\n * @type {Record<string, unknown>}\n * @memberOf ListItemComponent\n */\n @Input()\n override item!: Record<string, unknown>;\n\n /**\n * @description The name of the icon to display in the list item.\n * @summary Specifies which icon to display using Ionic's icon system.\n * The icon name should correspond to an available Ionic icon or a custom\n * icon that has been registered with the icon registry.\n *\n * @type {string}\n * @memberOf ListItemComponent\n */\n @Input()\n icon!: string;\n\n /**\n * @description Position of the icon within the list item.\n * @summary Determines whether the icon appears at the start (left in LTR languages)\n * or end (right in LTR languages) of the list item. This affects the overall\n * layout and visual hierarchy of the item content.\n *\n * @type {'start' | 'end'}\n * @default 'start'\n * @memberOf ListItemComponent\n */\n @Input()\n iconSlot: 'start' | 'end' ='start';\n\n /**\n * @description Controls whether the list item behaves as a clickable button.\n * @summary When set to true, the list item will have button-like behavior including\n * hover effects, click handling, and appropriate accessibility attributes.\n * When false, the item is displayed as static content without interactive behavior.\n *\n * @type {StringOrBoolean}\n * @default true\n * @memberOf ListItemComponent\n */\n @Input()\n button: StringOrBoolean = true;\n\n /**\n * @description The main title text displayed in the list item.\n * @summary Sets the primary text content that appears prominently in the list item.\n * This is typically the most important information about the item and is displayed\n * with emphasis in the component's visual hierarchy.\n *\n * @type {string}\n * @memberOf ListItemComponent\n */\n @Input()\n title?: string;\n\n /**\n * @description Secondary descriptive text for the list item.\n * @summary Provides additional context or details about the item. This text\n * is typically displayed below the title with less visual emphasis.\n * Useful for providing context without cluttering the main title.\n *\n * @type {string}\n * @memberOf ListItemComponent\n */\n @Input()\n description?: string;\n\n /**\n * @description Additional information text for the list item.\n * @summary Displays supplementary information that provides extra context\n * about the item. This could include metadata, status information, or\n * other relevant details that don't fit in the title or description.\n *\n * @type {string}\n * @memberOf ListItemComponent\n */\n @Input()\n info?: string;\n\n /**\n * @description Sub-information text displayed in the list item.\n * @summary Provides tertiary level information that complements the info field.\n * This is typically used for additional metadata or contextual details\n * that are useful but not critical for understanding the item.\n *\n * @type {string}\n * @memberOf ListItemComponent\n */\n @Input()\n subinfo?: string;\n\n /**\n * @description Event emitter for list item click interactions.\n * @summary Emits custom events when the list item is clicked or when actions\n * are performed on it. The emitted event contains information about the action,\n * the item data, and other relevant context for parent components to handle.\n *\n * @type {EventEmitter<ListItemCustomEvent>}\n * @memberOf ListItemComponent\n */\n @Output()\n clickEvent: EventEmitter<ListItemCustomEvent> = new EventEmitter<ListItemCustomEvent>();\n\n /**\n * @description Flag indicating whether slide items are currently enabled.\n * @summary Controls the visibility of slide actions based on screen size and\n * available operations. When true, users can swipe on the item to reveal\n * action buttons for operations like edit and delete.\n *\n * @type {boolean}\n * @default false\n * @memberOf ListItemComponent\n */\n showSlideItems: boolean = false;\n\n /**\n * @description Current window width in pixels.\n * @summary Stores the current browser window width which is used to determine\n * responsive behavior, such as when to show or hide slide items based on\n * screen size. Updated automatically on window resize events.\n *\n * @type {number}\n * @memberOf ListItemComponent\n */\n windowWidth!: number;\n\n /**\n * @description Flag indicating whether the action menu popover is currently open.\n * @summary Tracks the state of the action menu to prevent multiple instances\n * from being opened simultaneously and to ensure proper cleanup when actions\n * are performed. Used for managing the popover lifecycle.\n *\n * @type {boolean}\n * @default false\n * @memberOf ListItemComponent\n */\n actionMenuOpen: boolean = false;\n\n\n\n /**\n * @description Creates an instance of ListItemComponent.\n * @summary Initializes a new ListItemComponent by calling the parent class constructor\n * with the component name for logging and identification purposes. Also registers\n * all available Ionic icons to ensure they can be displayed in the component.\n *\n * @memberOf ListItemComponent\n */\n constructor() {\n super(\"ListItemComponent\");\n addIcons(AllIcons);\n this.enableDarkMode = true;\n }\n\n /**\n * @description Initializes the component after Angular first displays the data-bound properties.\n * @summary Sets up the component by determining slide item visibility, processing boolean inputs,\n * building CSS class names based on properties, and capturing the current window width.\n * This method prepares the component for user interaction by ensuring all properties are\n * properly initialized and responsive behavior is configured.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant L as ListItemComponent\n * participant W as Window\n *\n * A->>L: ngOnInit()\n * L->>L: enableSlideItems()\n * L->>L: Process button boolean\n * L->>L: Build className with flex classes\n * alt operations exist\n * L->>L: Add 'action' class\n * end\n * L->>W: getWindowWidth()\n * W-->>L: Return current width\n * L->>L: Store windowWidth\n *\n * @return {Promise<void>}\n * @memberOf ListItemComponent\n */\n async ngOnInit(): Promise<void> {\n this.showSlideItems = this.enableSlideItems();\n this.button = stringToBoolean(this.button);\n this.className = `${this.className} dcf-flex dcf-flex-middle grid-item`;\n if (this.operations?.length)\n this.className += ` action`;\n this.windowWidth = getWindowWidth() as number;\n }\n\n async ngAfterViewInit(): Promise<void> {\n this.checkDarkMode();\n }\n\n /**\n * @description Handles user interactions and actions performed on the list item.\n * @summary This method is the central action handler for list item interactions. It manages\n * event propagation, dismisses open action menus, removes focus traps, and either emits\n * events for parent components to handle or performs navigation based on the component's\n * route configuration. This method supports both event-driven and navigation-driven architectures.\n *\n * @param {CrudOperations} action - The type of CRUD operation being performed\n * @param {Event} event - The browser event that triggered the action\n * @param {HTMLElement} [target] - Optional target element for the event\n * @return {Promise<boolean|void>} A promise that resolves to navigation success or void for events\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant L as ListItemComponent\n * participant P as Parent Component\n * participant N as Router\n * participant E as Event System\n *\n * U->>L: Perform action (click/swipe)\n * L->>L: stopImmediatePropagation()\n * alt actionMenuOpen\n * L->>L: Dismiss action menu\n * end\n * L->>L: removeFocusTrap()\n * alt No route configured\n * L->>E: windowEventEmitter()\n * L->>P: clickEvent.emit()\n * else Route configured\n * L->>N: redirect(action, uid)\n * N-->>L: Return navigation result\n * end\n *\n * @memberOf ListItemComponent\n */\n async handleAction(action: CrudOperations, event: Event, target?: HTMLElement): Promise<boolean|void> {\n event.stopImmediatePropagation();\n if (this.actionMenuOpen)\n await this.actionMenuComponent.dismiss();\n // forcing trap focus\n removeFocusTrap();\n if (!this.route) {\n const event = {target: target, action, pk: this.pk, data: this.uid, name: ComponentEventNames.CLICK, component: this.componentName } as ListItemCustomEvent;\n windowEventEmitter(`ListItem${ComponentEventNames.CLICK}`, event);\n return this.clickEvent.emit(event);\n }\n return await this.redirect(action, (typeof this.uid === 'number' ? `${this.uid}`: this.uid));\n }\n\n /**\n * @description Responsive handler that enables or disables slide items based on screen size and operations.\n * @summary This method is automatically called when the window is resized and also during component\n * initialization. It determines whether slide actions should be available based on the current\n * window width and the presence of UPDATE or DELETE operations. Slide items are typically hidden\n * on larger screens where there's space for dedicated action buttons.\n *\n * @return {boolean} True if slide items should be shown, false otherwise\n *\n * @mermaid\n * sequenceDiagram\n * participant W as Window\n * participant L as ListItemComponent\n * participant U as UI\n *\n * W->>L: resize event\n * L->>W: getWindowWidth()\n * W-->>L: Return current width\n * L->>L: Store windowWidth\n * alt No operations OR width > 639px\n * L->>U: showSlideItems = false\n * else Operations include UPDATE/DELETE\n * L->>U: showSlideItems = true\n * end\n * L-->>U: Return showSlideItems value\n *\n * @memberOf ListItemComponent\n */\n @HostListener('window:resize', ['$event'])\n enableSlideItems(): boolean {\n this.windowWidth = getWindowWidth() as number;\n if (!this.operations?.length || this.windowWidth > 639)\n return this.showSlideItems = false;\n this.showSlideItems = this.operations.includes(OperationKeys.UPDATE) || this.operations.includes(OperationKeys.DELETE);\n return this.showSlideItems;\n }\n\n /**\n * @description Animates and removes an element from the DOM.\n * @summary This method applies CSS animation classes to create a smooth fade-out effect\n * before removing the element from the DOM. The animation enhances user experience by\n * providing visual feedback when items are deleted or removed from lists. The timing\n * is coordinated with the CSS animation duration to ensure the element is removed\n * after the animation completes.\n *\n * @param {HTMLElement} element - The DOM element to animate and remove\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant L as ListItemComponent\n * participant E as HTMLElement\n * participant D as DOM\n *\n * L->>E: Add animation classes\n * Note over E: uk-animation-fade, uk-animation-medium, uk-animation-reverse\n * E->>E: Start fade animation\n * L->>L: setTimeout(600ms)\n * Note over L: Wait for animation to complete\n * L->>D: element.remove()\n * D->>D: Remove element from DOM\n *\n * @memberOf ListItemComponent\n */\n removeElement(element: HTMLElement): void {\n element.classList.add('uk-animation-fade', 'uk-animation-medium', 'uk-animation-reverse');\n setTimeout(() => {element.remove()}, 600)\n }\n\n /**\n * @description Navigates to a new route based on the specified action and item ID.\n * @summary This method constructs a navigation URL using the component's route configuration,\n * the specified action, and an item identifier. It uses Ionic's Router to perform\n * forward navigation with appropriate animations. This method is typically used for\n * CRUD operations where each action (create, read, update, delete) has its own route.\n *\n * @param {string} action - The action to be performed (e.g., 'edit', 'view', 'delete')\n * @param {string} [id] - The unique identifier of the item to be acted upon\n * @return {Promise<boolean>} A promise that resolves to true if navigation was successful\n *\n * @mermaid\n * sequenceDiagram\n * participant L as ListItemComponent\n * participant N as Router\n * participant R as Router\n *\n * L->>L: redirect(action, id)\n * L->>L: Construct URL: /{route}/{action}/{id}\n * L->>N: navigateForward(url)\n * N->>R: Navigate to constructed URL\n * R-->>N: Return navigation result\n * N-->>L: Return boolean success\n *\n * @memberOf ListItemComponent\n */\n async redirect(action: string, id?: string): Promise<boolean> {\n return await this.router.navigateByUrl(`/${this.route}/${action}/${id || this.uid}`);\n }\n\n /**\n * @description Presents the actions menu popover for the list item.\n * @summary This method handles the display of a contextual action menu when triggered by user\n * interaction (typically a long press or right-click). It stops event propagation to prevent\n * unwanted side effects, removes any existing focus traps for accessibility, configures the\n * popover with the triggering event, and opens the action menu. The menu typically contains\n * available CRUD operations for the item.\n *\n * @param {Event} event - The event that triggered the action menu request\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant L as ListItemComponent\n * participant P as Popover\n * participant A as Accessibility\n *\n * U->>L: Trigger action menu (long press/right-click)\n * L->>L: stopImmediatePropagation()\n * L->>A: removeFocusTrap()\n * L->>P: Set event reference\n * L->>L: actionMenuOpen = true\n * L->>P: Display popover with actions\n *\n * @memberOf ListItemComponent\n */\n presentActionsMenu(event: Event): void {\n event.stopImmediatePropagation();\n // forcing trap focus\n removeFocusTrap();\n this.actionMenuComponent.event = event;\n this.actionMenuOpen = true;\n }\n}\n","\n@if (title || description) {\n <ion-item-sliding>\n <ion-item\n [id]=\"uid\"\n [lines]=\"lines\"\n [button]=\"button\"\n [class]=\"className\"\n (click)=\"operations?.includes('read') ? handleAction('read', $event, component) : ''\"\n #component\n >\n @if (icon && lines !== 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\" />\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-flex dcf-flex-middle dcf-grid-collapse\" dcf-grid>\n @if (icon && lines === 'inset') {\n <div class=\"dcf-icon dcf-grid-icon\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\" />\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n @if (title) {\n <ion-label class=\"dcf-item-title\">\n {{ uid !== title ? (uid + ' - ' + title) : title }}\n </ion-label>\n }\n @if (description) {\n <div class=\"dcf-description\" [innerHTML]=\"description\"></div>\n }\n </div>\n @if (info || subinfo) {\n <div class=\"dcf-width-auto@s dcf-width-expand dcf-info dcf-flex dcf-flex-right@s\">\n <div>\n @if (info) {\n <span [innerHTML]=\"info\"></span>\n }\n @if (subinfo) {\n <div class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\" ></div>\n }\n </div>\n </div>\n }\n\n <div class=\"dcf-width-auto dcf-flex dcf-flex-middle dcf-flex-right\">\n @if ((operations.includes('delete') || operations.includes('update')) && uid) {\n\n <div class=\"dcf-visible@s\" id=\"dcf-actions\">\n <ion-button class=\"\" shape=\"round\" fill=\"clear\" color=\"primary\" (click)=\"presentActionsMenu($event)\">\n <ion-icon slot=\"icon-only\" aria-hidden=\"true\" name=\"ellipsis-vertical-outline\" />\n </ion-button>\n <ion-popover\n #actionMenuComponent\n side=\"bottom\"\n alignment=\"left\"\n\n [isOpen]=\"actionMenuOpen\"\n (didDismiss)=\"actionMenuOpen = false\">\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-list lines=\"none\">\n <ion-list-header>\n <h4 class=\"dcf-text-capitalize\" [innerHTML]=\"'actions' | translate\"></h4>\n </ion-list-header>\n @for (operation of ['update', 'delete']; track operation) {\n @if (operations.includes(operation)) {\n <ion-item [button]=\"true\" (click)=\"handleAction(operation, $event, component)\">\n <ion-avatar class=\"dcf-flex dcf-flex-middle\" aria-hidden=\"true\" slot=\"start\">\n @if (operation === 'update') {\n <ion-icon color=\"primary\" aria-hidden=\"true\" name=\"create-outline\" />\n } @else {\n <ion-icon color=\"danger\" aria-hidden=\"true\" name=\"trash\" />\n }\n </ion-avatar>\n <ion-label class=\"dcf-text-capitalize\">{{ operation | translate }}</ion-label>\n </ion-item>\n }\n }\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n </div>\n }\n @if (windowWidth > 639) {\n <div id=\"end\">\n <ng-content select=\"[slot='end']\"></ng-content>\n </div>\n }\n </div>\n </div>\n </div>\n </ion-item>\n @if (showSlideItems && uid) {\n <ion-item-options side=\"end\" (ionSwipe)=\"operations.length === 1 ? handleAction(operations[0], $event, component) : ''\">\n @if (operations?.includes('update')) {\n <ion-item-option class=\"dcf-update\" (click)=\"handleAction('update', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\" />\n </ion-item-option>\n }\n @if (operations?.includes('delete')) {\n <ion-item-option class=\"dcf-delete\" (click)=\"handleAction('delete', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\" />\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n","/**\n * @module module:lib/components/stepped-form/stepped-form.component\n * @description Stepped form component module.\n * @summary Provides `SteppedFormComponent` which implements a multi-page form\n * UI with navigation, validation and submission support. Useful for forms that\n * need to be split into logical steps/pages.\n *\n * @link {@link SteppedFormComponent}\n */\n\nimport { Component, Input, OnInit, OnDestroy } from '@angular/core';\nimport { FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { IonButton, IonSkeletonText, IonText } from '@ionic/angular/standalone';\nimport { arrowForwardOutline, arrowBackOutline } from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { UIElementMetadata, UIModelMetadata} from '@decaf-ts/ui-decorators';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport { ComponentEventNames } from '../../engine/constants';\nimport { Dynamic } from '../../engine/decorators';\nimport { NgxFormService } from '../../services/NgxFormService';\nimport { getLocaleContext } from '../../i18n/Loader';\nimport { LayoutComponent } from '../layout/layout.component';\nimport { NgxFormDirective } from '../../engine/NgxFormDirective';\nimport { FormParent } from '../../engine/types';\n\n\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-stepped-form',\n templateUrl: './stepped-form.component.html',\n styleUrls: ['./stepped-form.component.scss'],\n imports: [\n TranslatePipe,\n ReactiveFormsModule,\n IonSkeletonText,\n IonText,\n IonButton,\n LayoutComponent\n ],\n standalone: true,\n host: {'[attr.id]': 'uid'},\n})\nexport class SteppedFormComponent extends NgxFormDirective implements OnInit, OnDestroy {\n\n /**\n * @description Array of UI model metadata for all form fields.\n * @summary Contains the complete collection of UI model metadata that defines\n * the structure, validation, and presentation of form fields across all pages.\n * Each metadata object contains information about field type, validation rules,\n * page assignment, and display properties.\n *\n * @type {UIModelMetadata[]}\n * @memberOf SteppedFormComponent\n */\n @Input()\n override children!: UIModelMetadata[] | { title: string; description: string; items?: UIModelMetadata[] }[];\n\n\n /**\n * @description The locale to be used for translations.\n * @summary Specifies the locale identifier to use when translating component text.\n * This can be set explicitly via input property to override the automatically derived\n * locale from the component name. The locale is typically a language code (e.g., 'en', 'fr')\n * or a language-region code (e.g., 'en-US', 'fr-CA') that determines which translation\n * set to use for the component's text content.\n *\n * @type {string}\n * @memberOf SteppedFormComponent\n */\n @Input()\n paginated: boolean = true;\n\n\n // /**\n // * @description Optional action identifier for form submission context.\n // * @summary Specifies a custom action name that will be included in the submit event.\n // * If not provided, defaults to the standard submit event constant. Used to\n // * distinguish between different types of form submissions within the same component.\n // *\n // * @type {string | undefined}\n // */\n // @Input()\n // action?: string;\n\n\n\n /**\n * @description Number of pages in the stepped form.\n * @summary Represents the total number of steps/pages in the multi-step form.\n * This value is automatically calculated based on the page properties of the children\n * or can be explicitly set. Each page represents a logical group of form fields.\n *\n * @type {number}\n * @default 1\n * @memberOf SteppedFormComponent\n */\n @Input()\n override pages: number | {title: string; description: string}[] = 1;\n\n /**\n * List of titles and descriptions for each page of the stepped form.\n * Each object in the array represents a page, containing a title and a description.\n *\n * @example\n * pageTitles = [\n * { title: 'Personal Information', description: 'Fill in your personal details.' },\n * { title: 'Address', description: 'Provide your residential address.' }\n * ];\n */\n @Input()\n pageTitles: { title: string; description: string}[] = [];\n\n\n /**\n * @description The CRUD operation type for this form.\n * @summary Defines the type of operation being performed (CREATE, READ, UPDATE, DELETE).\n * This affects form behavior, validation rules, and field accessibility. For example,\n * READ operations might disable form fields, while CREATE operations enable all fields.\n *\n * @type {CrudOperations}\n * @default OperationKeys.CREATE\n * @memberOf SteppedFormComponent\n */\n @Input()\n override operation: CrudOperations = OperationKeys.CREATE;\n\n /**\n * @description The initial page to display when the form loads.\n * @summary Specifies which page of the multi-step form should be shown first.\n * This allows starting the form at any step, useful for scenarios like editing\n * existing data where you might want to jump to a specific section.\n *\n * @type {number}\n * @default 1\n * @memberOf SteppedFormComponent\n */\n @Input()\n startPage: number = 1;\n\n // /**\n // * @description Angular reactive FormGroup or FormArray for form state management.\n // * @summary The form instance that manages all form controls, validation, and form state.\n // * When using FormArray, each array element represents a page's FormGroup. When using\n // * FormGroup, it contains all form controls for the entire stepped form.\n // *\n // * @type {FormGroup | FormArray | undefined}\n // * @memberOf SteppedFormComponent\n // */\n // @Input()\n // formGroup!: FormGroup | FormArray | undefined;\n\n /**\n * @description Array representing the structure of pages.\n * @summary Contains metadata about each page, including page numbers and indices.\n * This array is built during initialization to organize the form fields into\n * logical pages and provide navigation structure.\n *\n * @type {UIModelMetadata[]}\n * @memberOf SteppedFormComponent\n */\n pagesArray: UIModelMetadata[] = [];\n\n\n // /**\n // * @description Custom event handlers for form actions.\n // * @summary A record of event handler functions keyed by event names that can be\n // * triggered during form operations. These handlers provide extensibility for\n // * custom business logic and can be invoked for various form events and actions.\n // *\n // * @type {HandlerLike}\n // */\n // @Input()\n // handlers!: HandlerLike;\n\n\n\n /**\n * @description Event emitter for form submission.\n * @summary Emits events when the form is submitted, typically on the last page\n * when all validation passes. The emitted event contains the form data and\n * event type information for parent components to handle.\n *\n * @type {EventEmitter<IBaseCustomEvent>}\n * @memberOf SteppedFormComponent\n */\n // @Output()\n // submitEvent: EventEmitter<ICrudFormEvent> = new EventEmitter<ICrudFormEvent>();\n\n /**\n * @description Creates an instance of SteppedFormComponent.\n * @summary Initializes a new SteppedFormComponent instance and registers the required\n * Ionic icons for navigation buttons (forward and back arrows).\n *\n * @memberOf SteppedFormComponent\n */\n constructor() {\n super(\"SteppedFormComponent\");\n addIcons({arrowForwardOutline, arrowBackOutline});\n this.enableDarkMode = true;\n }\n\n /**\n * @description Initializes the component after Angular first displays the data-bound properties.\n * @summary Sets up the stepped form by organizing children into pages, calculating the total\n * number of pages, and initializing the active page. This method processes the UI model metadata\n * to create a logical page structure and ensures proper page assignments for all form fields.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant S as SteppedFormComponent\n * participant F as Form Service\n *\n * A->>S: ngOnInit()\n * S->>S: Set activeIndex = startPage\n * S->>S: Calculate total pages\n * S->>S: Assign page props to children\n * S->>S: getCurrentFormGroup(activeIndex)\n * S->>F: Extract FormGroup for active page\n * F-->>S: Return activeFormGroup\n *\n * @memberOf SteppedFormComponent\n */\n override async ngOnInit(): Promise<void> {\n if (!this.locale)\n this.locale = getLocaleContext(\"SteppedFormComponent\")\n this.activeIndex = this.startPage;\n if (typeof this.pages === 'object') {\n this.pageTitles = this.pages;\n } else {\n if (!this.pageTitles.length)\n this.pageTitles = Array.from({ length: this.pages }, () => ({ title: '', description: ''}));\n }\n\n this.pages = this.pageTitles.length;\n\n if (this.paginated) {\n if (!this.parentForm)\n this.parentForm = (this.formGroup?.root || this.formGroup) as FormParent;\n this.children = [... (this.children as UIModelMetadata[]).map((c) => {\n if (!c.props)\n c.props = {};\n const page = c.props['page'] || 1;\n // prevent page overflow\n c.props['page'] = page > this.pages ? this.pages : page;\n return c;\n })];\n this.getActivePage(this.activeIndex);\n } else {\n this.children = this.pageTitles.map((page, index) => {\n const pageNumber = index + 1;\n const items = (this.children as UIModelMetadata[]).filter(({ props }: UIElementMetadata) => props?.['page'] === pageNumber);\n return {\n page: pageNumber,\n title: page.title,\n description: page.description,\n items\n };\n });\n // this.formGroup = new FormGroup(\n // (this.formGroup as FormArray).controls.reduce((acc, control, index) => {\n // acc[index] = control as FormGroup;\n // return acc;\n // }, {} as Record<string, FormGroup>)\n // );\n }\n this.initialized = true;\n }\n\n /**\n * @description Cleanup method called when the component is destroyed.\n * @summary Unsubscribes from any active timer subscriptions to prevent memory leaks.\n * This is part of Angular's component lifecycle and ensures proper resource cleanup.\n *\n * @memberOf SteppedFormComponent\n */\n override ngOnDestroy(): void {\n super.ngOnDestroy();\n if (this.timerSubscription)\n this.timerSubscription.unsubscribe();\n }\n\n /**\n * @description Handles navigation to the next page or form submission.\n * @summary Validates the current page's form fields and either navigates to the next page\n * or submits the entire form if on the last page. Form validation must pass before\n * proceeding. On successful submission, emits a submit event with form data.\n *\n * @param {boolean} lastPage - Whether this is the last page of the form\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant S as SteppedFormComponent\n * participant F as Form Service\n * participant P as Parent Component\n *\n * U->>S: Click Next/Submit\n * S->>F: validateFields(activeFormGroup)\n * F-->>S: Return validation result\n * alt Not last page and valid\n * S->>S: activeIndex++\n * S->>S: getCurrentFormGroup(activeIndex)\n * else Last page and valid\n * S->>F: getFormData(formGroup)\n * F-->>S: Return form data\n * S->>P: submitEvent.emit({data, name: SUBMIT})\n * end\n *\n * @memberOf SteppedFormComponent\n */\n handleNext(lastPage: boolean = false): void {\n const isValid = NgxFormService.validateFields(this.formGroup as FormGroup);\n // const isValid = this.paginated ?\n // NgxFormService.validateFields(this.formGroup as FormGroup) :\n // (this.formGroup as FormArray)?.controls.every(control => NgxFormService.validateFields(control as FormGroup));\n if (!lastPage) {\n if (isValid) {\n this.activeIndex = this.activeIndex + 1;\n this.getActivePage(this.activeIndex);\n }\n } else {\n if (isValid) {\n const rootForm = this.formGroup?.root || this.formGroup;\n const data = Object.assign({}, ...Object.values(NgxFormService.getFormData(rootForm as FormGroup)));\n this.submitEvent.emit({\n data,\n component: this.componentName,\n name: this.action || ComponentEventNames.SUBMIT,\n handlers: this.handlers,\n });\n }\n }\n }\n\n /**\n * @description Handles navigation to the previous page.\n * @summary Moves the user back to the previous page in the stepped form.\n * This method decrements the active page number and updates the form\n * group and children to display the previous page's content.\n *\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant S as SteppedFormComponent\n *\n * U->>S: Click Back\n * S->>S: activeIndex--\n * S->>S: getCurrentFormGroup(activeIndex)\n * Note over S: Update active form and children\n *\n * @memberOf SteppedFormComponent\n */\n handleBack(): void {\n if (!this.paginated)\n return this.location.back();\n this.activeIndex = this.activeIndex - 1;\n this.getActivePage(this.activeIndex);\n }\n\n\n\n // async handleSubmit(event?: SubmitEvent, eventName?: string, componentName?: string): Promise<boolean | void> {\n // if (event) {\n // event.preventDefault();\n // event.stopImmediatePropagation();\n // }\n\n // if (!NgxFormService.validateFields(this.formGroup as FormGroup))\n // return false;\n // const data = NgxFormService.getFormData(this.formGroup as FormGroup);\n // this.submitEvent.emit({\n // data,\n // component: componentName || this.componentName,\n // name: eventName || this.action || ComponentEventNames.SUBMIT,\n // handlers: this.handlers,\n // });\n // }\n}\n","<form\n class=\"dcf-steped-form\"\n [class.paginated]=\"paginated\"\n novalidate\n #component\n>\n @if (paginated) {\n <div class=\"dcf-page-steps\">\n <div class=\"dcf-grid dcf-grid-collapse skip\">\n @for (page of pageTitles; track $index) {\n <div class=\"dcf-flex dcf-flex-middle\">\n <div\n class=\"dcf-step\"\n [class.dcf-active]=\"activeIndex === $index + 1\"\n [class.dcf-passed]=\"$index + 1 < activeIndex\"\n >\n {{ $index + 1 }}\n </div>\n @if (page?.title || page?.description) {\n <div class=\"dcf-information dcf-visible@s\">\n @if (page?.title) {\n <div class=\"dcf-title\">{{ page?.title | translate }}</div>\n }\n @if (page?.description) {\n <div class=\"dcf-description\">\n {{ page?.description | translate }}\n </div>\n }\n <div class=\"dcf-separator\"></div>\n </div>\n }\n @if ($index < pageTitles.length - 1) {\n <div class=\"dcf-arrow-container\">\n <svg\n width=\"8\"\n height=\"12\"\n viewBox=\"0 0 8 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M1.5 1L6.5 6L1.5 11\" />\n </svg>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (\n pageTitles[activeIndex - 1]?.title ||\n pageTitles[activeIndex - 1]?.description\n ) {\n <div class=\"dcf-current-step\">\n <div>\n @if (pageTitles[activeIndex - 1]?.title) {\n <div class=\"dcf-title\">\n {{ pageTitles[activeIndex - 1]?.title | translate }}\n </div>\n }\n @if (pageTitles[activeIndex - 1]?.description) {\n <div class=\"dcf-description\">\n {{ pageTitles[activeIndex - 1]?.description | translate }}\n </div>\n }\n </div>\n </div>\n }\n\n @if (initialized && activePage?.length) {\n <ngx-decaf-layout\n [className]=\"'dcf-stepped-form-grid paginated dcf-grid-nested'\"\n [children]=\"activePage || []\"\n [parentForm]=\"formGroup || parentForm\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [match]=\"false\"\n [cardBody]=\"cardBody\"\n [cardType]=\"cardType\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [match]=\"false\"\n />\n } @else {\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%\"\n ><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text\n ></ion-text>\n <br />\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%\"\n ><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text\n ></ion-text>\n }\n <div\n class=\"dcf-buttons-container dcf-grid dcf-grid-collapse dcf-flex dcf-flex-left\"\n >\n <div class=\"dcf-width-1-2@s\">\n <ion-button color=\"light\" (click)=\"handleBack()\" [disabled]=\"activeIndex <= 1\">{{ locale + \".previous\" | translate }}</ion-button>\n </div>\n\n <div class=\"dcf-width-1-2@s\">\n <ion-button fill=\"solid\" (click)=\"handleNext(activeIndex === pages ? true : false)\">\n @if (activeIndex === pages) {\n {{ locale + \".submit\" | translate }}\n } @else {\n {{ locale + \".next\" | translate }}\n }\n </ion-button>\n </div>\n </div>\n } @else {\n <div class=\"dcf-single-step\">\n @for (item of children; track $index) {\n <ngx-decaf-card\n [className]=\"className\"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <div>\n @if (item.title || item.description) {\n <div class=\"dcf-information\">\n <div>\n @if (item.title) {\n <div class=\"dcf-title\">{{ item.title | translate }}</div>\n }\n @if (item.description) {\n <div class=\"dcf-description\">\n {{ item.description | translate }}\n </div>\n }\n </div>\n </div>\n }\n <div [class.dcf-margin-bottom]=\"cardType === 'blank'\">\n @if (initialized && item.items?.length) {\n <ngx-decaf-layout\n [className]=\"'dcf-stepped-form-grid dcf-grid-nested'\"\n [children]=\"item.items || []\"\n [parentForm]=\"formGroup || parentForm\"\n [flexMode]=\"props.flexMode || false\"\n [gap]=\"'small'\"\n [cardBody]=\"cardBody\"\n [cardType]=\"cardType\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [match]=\"false\"\n />\n }\n </div>\n </div>\n </ngx-decaf-card>\n }\n <div\n class=\"dcf-buttons-container dcf-grid dcf-grid-small dcf-flex dcf-flex-right\"\n >\n <div class=\"dcf-width-auto@s dcf-width-1-1\">\n <ion-button color=\"light\" (click)=\"handleBack()\">\n {{ locale + \".cancel\" | translate }}\n </ion-button>\n </div>\n\n <div class=\"dcf-width-auto@s dcf-width-1-1\">\n <ion-button fill=\"solid\" (click)=\"handleNext(true)\">\n {{ locale + \".submit\" | translate }}\n </ion-button>\n </div>\n </div>\n </div>\n }\n</form>\n","import { CommonModule } from '@angular/common';\nimport { Component, ElementRef, EventEmitter, Input, Output, ViewChild, OnInit, OnDestroy } from '@angular/core';\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport {\n IonItem, IonLabel, IonList,\n IonButton\n } from '@ionic/angular/standalone';\n import { TranslatePipe } from '@ngx-translate/core';\nimport { HTML5InputTypes } from '@decaf-ts/ui-decorators';\nimport { Dynamic } from '../../engine/decorators';\nimport { NgxFormFieldDirective } from '../../engine/NgxFormFieldDirective';\nimport { ElementSize, FlexPosition, PossibleInputTypes } from '../../engine/types';\nimport { ElementSizes, ComponentEventNames } from '../../engine/constants';\nimport { IBaseCustomEvent, IFileUploadError } from '../../engine/interfaces';\nimport { presentNgxLightBoxModal } from '../modal/modal.component';\nimport { CardComponent } from '../card/card.component';\nimport { IconComponent } from '../icon/icon.component';\n\n\nconst FileErrors = {\n notAllowed: 'not_allowed',\n maxSize: 'max_size',\n} as const;\n\n/**\n * @description File upload component for Angular applications.\n * @summary This component provides a user interface for uploading files with support for drag-and-drop,\n * file validation, and preview functionality. It integrates seamlessly with Angular reactive forms\n * and supports multiple file uploads, directory mode, and custom file size limits.\n *\n * @class FileUploadComponent\n * @example\n * ```typescript\n * <ngx-decaf-file-upload [formGroup]=\"formGroup\" [name]=\"'fileInput'\" [multiple]=\"true\"></ngx-decaf-file-upload>\n * ```\n * @mermaid\n * sequenceDiagram\n * participant User\n * participant FileUploadComponent\n * User->>FileUploadComponent: Select or drag files\n * FileUploadComponent->>FileUploadComponent: Validate files\n * FileUploadComponent->>FileUploadComponent: Emit change event\n * User->>FileUploadComponent: Remove file\n * FileUploadComponent->>FileUploadComponent: Update file list\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-file-upload',\n templateUrl: './file-upload.component.html',\n styleUrls: ['./file-upload.component.scss'],\n standalone: true,\n imports: [CommonModule, ReactiveFormsModule, CardComponent, IconComponent, IonList, IonLabel, IonItem, TranslatePipe, IonButton],\n})\nexport class FileUploadComponent extends NgxFormFieldDirective implements OnInit, OnDestroy {\n\n @ViewChild('component', { static: true })\n override component!: ElementRef<HTMLInputElement>;\n\n /**\n * @description Parent form group.\n * @summary References the parent form group to which this field belongs.\n * This is necessary for integrating the field with Angular's reactive forms.\n *\n * @type {FormGroup}\n */\n @Input()\n override formGroup: FormGroup | undefined;\n\n /**\n * @summary The flat field name used as the form control identifier in immediate parent FormGroup.\n * @description Specifies the name of the field, which is used as the FormControl identifier in immediate parent FormGroup.\n * This value must be unique within the immediate parent FormGroup context and should not contain dots or nesting.\n *\n * @type {string}\n */\n @Input()\n override name!: string;\n\n /**\n * @description Angular FormControl instance for this field.\n * @summary The specific FormControl instance that manages this field's state, validation,\n * and value. This provides direct access to Angular's reactive forms functionality\n * for this individual field within the broader form structure.\n *\n * @type {FormControl}\n */\n @Input()\n override formControl!: FormControl;\n\n /**\n * @description Whether the field is required.\n * @summary When true, the field must have a value for the form to be valid.\n * Required fields are typically marked with an indicator in the UI.\n *\n * @type {boolean}\n */\n @Input()\n override required?: boolean;\n\n /**\n * @description Allows multiple file selection.\n * @summary When true, the user can select multiple files for upload.\n *\n * @type {boolean}\n * @default false\n */\n @Input()\n override multiple: boolean = false;\n\n /**\n * @description Specifies the input type for the file upload field.\n * @summary Defines the type of input element used for file uploads, such as file or directory.\n *\n * @type {PossibleInputTypes}\n * @default HTML5InputTypes.FILE\n */\n @Input()\n override type: PossibleInputTypes = HTML5InputTypes.FILE;\n\n /**\n * @description Label for the file upload field.\n * @summary Provides a user-friendly label for the file upload input.\n *\n * @type {string | undefined}\n */\n @Input()\n label?: string;\n\n /**\n * @description Label for the upload button.\n * @summary Specifies the text displayed on the file upload button.\n *\n * @type {string | undefined}\n */\n @Input()\n buttonLabel?: string;\n\n /**\n * @description Size of the file upload component.\n * @summary Determines the visual size of the file upload component, such as large, small, or default.\n *\n * @type {Extract<ElementSize, 'large' | 'small' | 'default'>}\n * @default ElementSizes.large\n */\n @Input()\n size: Extract<ElementSize, 'large' | 'small' | 'default'> = ElementSizes.large;\n\n /**\n * @description Flex positioning of the container's content.\n * @summary Controls how child elements are positioned within the container when flex layout\n * is enabled. Options include 'center', 'top', 'bottom', 'left', 'right', and combinations\n * like 'top-left'. This property is only applied when the flex property is true.\n *\n * @type {FlexPosition}\n * @default 'center'\n */\n @Input()\n position: FlexPosition = 'center';\n\n\n /**\n * @description Accepted file types for upload.\n * @summary Specifies the file types that are allowed for upload, such as images or documents.\n *\n * @type {string | string[]}\n * @default ['image/*']\n */\n @Input()\n accept: string | string[] = ['image/*'];\n\n /**\n * @description Whether to show an icon in the file upload field.\n * @summary When true, an icon is displayed alongside the file upload input.\n *\n * @type {boolean}\n * @default true\n */\n @Input()\n showIcon: boolean = true;\n\n /**\n * @description Enables directory mode for file uploads.\n * @summary When true, the user can upload entire directories instead of individual files.\n *\n * @type {boolean}\n * @default false\n */\n @Input()\n enableDirectoryMode: boolean = false;\n\n /**\n * @description Maximum file size allowed for upload.\n * @summary Specifies the maximum size (in MB) for files that can be uploaded.\n *\n * @type {number}\n * @default 1\n */\n @Input()\n maxFileSize: number = 1;\n\n /**\n * @description Event emitted when the file upload field changes.\n * @summary Emits an event containing details about the change in the file upload field.\n *\n * @type {EventEmitter<IBaseCustomEvent>}\n */\n @Output()\n changeEvent: EventEmitter<IBaseCustomEvent> = new EventEmitter<IBaseCustomEvent>();\n\n /**\n * @description Preview of the first file in the upload list.\n * @summary Stores the data URL of the first file in the upload list for preview purposes.\n * This is typically used to display a thumbnail or preview image.\n *\n * @type {string | undefined}\n */\n preview: string | undefined = undefined;\n\n /**\n * @description List of files selected for upload.\n * @summary Contains the files selected by the user for upload. This array is updated\n * whenever files are added or removed from the upload list.\n *\n * @type {File[]}\n */\n files: File[] = [];\n\n /**\n * @description List of errors encountered during file validation.\n * @summary Stores validation errors for files that do not meet the specified criteria,\n * such as file type or size restrictions. Each error includes the file name, size, and error message.\n *\n * @type {IFileUploadError[]}\n */\n errors: IFileUploadError[] = [];\n\n /**\n * @description Indicates whether a drag operation is in progress.\n * @summary This flag is set to true when a file is being dragged over the upload area.\n * It is used to provide visual feedback to the user during drag-and-drop operations.\n *\n * @type {boolean}\n * @default false\n */\n dragging: boolean = false;\n\n /**\n * @description Counter for drag events.\n * @summary Tracks the number of drag events to ensure proper handling of drag-and-drop\n * operations. The counter is incremented on drag enter and decremented on drag leave.\n *\n * @type {number}\n * @default 0\n */\n private dragCounter: number = 0;\n\n constructor() {\n super(\"FileUploadComponent\");\n }\n\n /**\n * @description Lifecycle hook that is called after Angular has initialized all data-bound properties of a directive.\n * @summary Sets up the component by enabling directory mode if specified, formatting the accepted file types,\n * and converting the maximum file size from megabytes to bytes.\n *\n * @returns {void}\n */\n ngOnInit(): void {\n if (this.enableDirectoryMode) {\n this.multiple = true;\n }\n if (Array.isArray(this.accept)) {\n this.accept = this.accept.join(',');\n }\n // Convert maxFileSize from MB to bytes\n this.maxFileSize = this.maxFileSize * 1024 * 1024;\n }\n\n /**\n * @description Lifecycle hook that is called when a directive, pipe, or service is destroyed.\n * @summary Cleans up the component by calling the parent ngOnDestroy method and clearing the file upload state.\n *\n * @returns {Promise<void> | void}\n */\n override ngOnDestroy(): Promise<void> | void {\n super.ngOnDestroy();\n this.handleClear();\n }\n\n /**\n * @description Handles the click event to trigger file selection.\n * @summary Simulates a click on the hidden file input element to open the file selection dialog.\n * This method is used to allow users to select files programmatically.\n *\n * @returns {void}\n */\n handleClickToSelect(): void {\n const element = this.component.nativeElement;\n if (element)\n (element.querySelector('#dcf-file-input') as HTMLButtonElement)?.click();\n }\n\n /**\n * @description Handles the file selection event.\n * @summary Processes the files selected by the user, validates them, and updates the file list.\n * This method is triggered when the user selects files using the file input element.\n *\n * @param {Event} event - The file selection event.\n * @returns {void}\n */\n handleSelection(event: Event): void {\n this.clearErrors();\n const input = event.target as HTMLInputElement;\n if (input.files) {\n const fileList = Array.from(input.files);\n this.handleSelectionConfirm(fileList);\n input.value = '';\n }\n }\n\n /**\n * @description Handles the drop event for drag-and-drop file uploads.\n * @summary Processes the files dropped by the user, validates them, and updates the file list.\n * This method is triggered when the user drops files onto the upload area.\n *\n * @param {DragEvent} event - The drag-and-drop event.\n * @returns {void}\n */\n handleDrop(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this.dragCounter = 0;\n this.dragging = false;\n this.clearErrors();\n if (!event.dataTransfer) return;\n const fileList = Array.from(event.dataTransfer.files);\n this.handleSelectionConfirm(fileList);\n }\n\n /**\n * @description Handles the drag over event for drag-and-drop file uploads.\n * @summary Sets the dragging flag to true to provide visual feedback during drag-and-drop operations.\n * This method is triggered when the user drags files over the upload area.\n *\n * @param {DragEvent} event - The drag over event.\n * @returns {void}\n */\n handleDragOver(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this.dragging = true;\n }\n\n /**\n * @description Handles the drag leave event for drag-and-drop file uploads.\n * @summary Decrements the drag counter and clears the dragging flag when the counter reaches zero.\n * This method is triggered when the user drags files out of the upload area.\n *\n * @param {DragEvent} event - The drag leave event.\n * @returns {void}\n */\n handleDragLeave(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this.dragCounter = Math.max(0, this.dragCounter - 1);\n if (this.dragCounter === 0) {\n this.dragging = false;\n }\n }\n\n /**\n * @description Clears the file list and validation errors.\n * @summary Resets the file upload component by clearing the selected files, preview, and errors.\n * This method is used to reset the component state.\n *\n * @returns {void}\n */\n handleClear(): void {\n this.clearErrors();\n this.preview = undefined;\n this.files = [];\n }\n\n /**\n * @description Confirms the file selection and updates the component state.\n * @summary Validates each file in the selection, updates the file list, and emits\n * the change event. If multiple or directory mode is enabled, adds files to the existing list.\n * Otherwise, replaces the existing files with the new selection.\n *\n * @param {File[]} files - The array of files selected by the user.\n * @returns {Promise<void>}\n */\n private async handleSelectionConfirm(files: File[]): Promise<void> {\n const validFiles: File[] = [];\n for (const file of files) {\n const isValid = this.validateFile(file);\n if (isValid === true) {\n validFiles.push(file);\n } else {\n this.errors.push({\n name: file.name,\n error: isValid,\n size: file.size\n });\n }\n }\n if (this.multiple || this.enableDirectoryMode) {\n this.files = this.files.concat(validFiles);\n } else {\n this.files = [validFiles[0]];\n }\n if(this.files.length) {\n const dataValues = await this.getDataURLs(this.files)\n this.setValue(JSON.stringify(dataValues));\n }\n\n await this.getPreview();\n this.changeEventEmit();\n }\n\n /**\n * @description Validates a single file against the component's constraints.\n * @summary Checks the file type and size against the accepted values and limits.\n * Returns true if the file is valid, or an error code if it is not.\n *\n * @param {File} file - The file to be validated.\n * @returns {true | string} - Returns true if valid, error code otherwise.\n */\n private validateFile(file: File): true | string {\n if (this.accept && this.accept !== '*') {\n const acceptedExtensions = Array.isArray(this.accept) ?\n this.accept : this.accept.split(',').map(ext => ext.trim());\n const accept = acceptedExtensions.some(ext => {\n if (ext === '*')\n return true;\n if (ext.endsWith('/*'))\n return file.type.startsWith(ext.replace(/\\/\\*$/, ''));\n const fileExtension = file.type.split('/').pop() || '';\n return file.type === ext || fileExtension === ext || file.name.toLowerCase().endsWith(ext.replace('.', ''));\n });\n if (!accept)\n return FileErrors.notAllowed;\n }\n if (this.maxFileSize && file.size > this.maxFileSize)\n return FileErrors.maxSize;\n return true;\n }\n\n /**\n * @description Displays a preview of the selected file in a lightbox.\n * @summary If the file is an image, its data URL is retrieved and displayed in a modal lightbox.\n * The lightbox shows the image at its natural size, constrained to the viewport dimensions.\n *\n * @param {File | string} [file] - The file to be previewed. If not provided, the current preview file is used.\n * @returns {Promise<void>}\n */\n async showFilePreview(file: File | string, fileExtension: string = 'image/'): Promise<void> {\n\n let content: string | undefined;\n if(file instanceof File) {\n const dataUrl = await this.getDataURLs(file) as string[];\n if(dataUrl && dataUrl.length)\n file = dataUrl[0];\n }\n if(fileExtension.includes('image/'))\n content = '<img src=\"' + file + '\" style=\"max-width: 100%; height: auto;\" />';\n\n if(fileExtension.includes('xml')) {\n const parseXml = (xmlString: string): string | undefined => {\n try {\n xmlString = (xmlString as string).replace(/^data:[^;]+;base64,/, '').replace(/\\s+/g, '')\n const decodedString = atob(xmlString);\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(decodedString, \"text/xml\");\n\n // const encoder = new TextEncoder(); // gera bytes UTF-8\n // const utf8Bytes = encoder.encode(xmlDoc.documentElement.outerHTML);\n // return new TextDecoder(\"utf-8\").decode(utf8Bytes);\n\n return xmlDoc.documentElement.innerHTML;\n\n } catch (error: unknown) {\n this.log.error((error as Error)?.message);\n return undefined;\n }\n\n }\n content = parseXml(file as string);\n content = `<div class=\"dfc-padding\">${content}</div>`;\n }\n await presentNgxLightBoxModal(content || \"\");\n }\n\n /**\n * @description Checks if a file is an image based on its MIME type.\n * @summary Determines if the file can be accepted as an image by checking\n * if its type starts with 'image/'.\n *\n * @param {File} file - The file to be checked.\n * @returns {boolean} - True if the file is an image, false otherwise.\n */\n isImageFile(file: File): boolean {\n return file && file.type.startsWith('image/');\n }\n\n /**\n * @description Removes a file from the selection.\n * @summary Updates the file list to exclude the file at the specified index.\n * Emits the change event and updates the preview if necessary.\n *\n * @param {number} index - The index of the file to be removed.\n * @returns {Promise<void>}\n */\n async removeFile(index: number): Promise<void> {\n if (index <= this.files.length)\n this.files = [...this.files.filter((_, i) => i !== index)];\n await this.getPreview();\n this.changeEventEmit();\n }\n\n /**\n * @description Retrieves the preview image for the selected files.\n * @summary If the first selected file is an image, its data URL is retrieved and set as the preview.\n * If the file is not an image, the preview is cleared.\n *\n * @returns {Promise<void>}\n */\n private async getPreview(): Promise<void> {\n this.preview = undefined;\n const file = this.files && this.files.length ? this.files[0] : null;\n if (file) {\n const dataUrl = await this.getDataURLs(file) as string[];\n if(dataUrl && dataUrl.length)\n this.preview = dataUrl[0];\n }\n\n }\n\n /**\n * @description Emits the change event for the file upload field.\n * @summary Triggers the change event, notifying any listeners that the value has changed.\n * The event contains the updated value, component name, and event type.\n *\n * @returns {void}\n */\n private changeEventEmit(): void {\n this.changeEvent.emit({\n data: this.value,\n component: this.componentName,\n name: ComponentEventNames.CHANGE,\n });\n }\n\n /**\n * @description Retrieves the data URLs for the selected files.\n * @summary Converts the selected image files to data URLs using FileReader.\n * The resulting data URLs can be used for previewing images in the browser.\n *\n * @param {File[] | File} [files] - The files for which to generate data URLs.\n * If not provided, the currently selected files are used.\n *\n * @returns {Promise<string[] | undefined>} - A promise that resolves to an array of data URLs, or undefined if an error occurs.\n */\n private async getDataURLs(files?: File[] | File): Promise<string[] | undefined> {\n if(!files)\n files = this.files;\n if(!Array.isArray(files))\n files = [files];\n // files = files.filter(f => f.type && f.type.startsWith('image/'));\n return this.readFile(files).then(urls => {\n // validate generated DataURLs\n const invalid = urls.some(u => !this.isValidDataURL(u));\n if (invalid)\n return undefined;\n if (this.multiple || this.enableDirectoryMode)\n return urls;\n return urls.length ? [urls[0]] : undefined;\n }).catch(() => {\n return undefined;\n });\n }\n\n /**\n * @description Validates the format of a data URL.\n * @summary Checks if the data URL is a non-empty string and matches the expected pattern\n * for base64-encoded image data URLs. Uses a regular expression to validate the format.\n *\n * @param {string | undefined} dataURL - The data URL to be validated.\n * @returns {boolean} - True if the data URL is valid, false otherwise.\n */\n private isValidDataURL(dataURL: string | undefined): boolean {\n if (!dataURL || typeof dataURL !== 'string') {\n return false;\n }\n\n // Regex para qualquer MIME type seguido de ;base64\n const match = dataURL.match(/^data:([a-zA-Z0-9.+-\\\\/]+);base64,([A-Za-z0-9+/=\\s]+)$/);\n if (!match)\n return false;\n\n const payload = match[2];\n try {\n if (typeof atob === 'function') {\n // remove espaços e tenta decodificar\n atob(payload.replace(/\\s+/g, ''));\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * @description Clears all error messages from the component.\n * @summary Resets the error state, removing all error messages from the display.\n *\n * @returns {void}\n */\n private clearErrors(): void {\n this.errors = [];\n }\n\n /**\n * @description Reads the selected files as data URLs.\n * @summary Uses the FileReader API to read each file as a data URL.\n * Returns a promise that resolves to an array of data URLs.\n *\n * @param {File[]} files - The files to be read.\n * @returns {Promise<string[]>} - A promise that resolves to an array of data URLs.\n */\n private readFile(files: File[]): Promise<string[]> {\n return Promise.all(files.map(file => new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onerror = () => reject(reader.error);\n reader.onload = () => resolve(String(reader.result || ''));\n reader.readAsDataURL(file);\n })));\n }\n\n}\n","<div class=\"decaf-file-component\" #component>\n <input\n id=\"dcf-file-input\"\n type=\"file\"\n placeholder=\"Select files\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"handleSelection($event)\"\n [multiple]=\"multiple\"\n hidden\n [attr.webkitdirectory]=\"enableDirectoryMode ? true : null\"\n />\n\n <ngx-decaf-card [className]=\"className\" [body]=\"'blank'\">\n <div>\n <div\n [class]=\"\n 'dcf-drop-area '\n + ' dcf-' + size\n + ' dcf-flex dcf-flex-' + position\n + ' dcf-text-' + position\n \"\n\n [class.dcf-dragging]=\"dragging\"\n [class.dcf-has-files]=\"files.length\"\n (drop)=\"!files?.length ? handleDrop($event) : dragging = false\"\n (dragover)=\"!files?.length ? handleDragOver($event) : dragging = false\"\n (dragleave)=\"!files?.length ? handleDragLeave($event) : dragging = false\"\n >\n <div>\n @if (!preview) {\n @if(showIcon) {\n <ngx-decaf-icon name=\"cloud-upload-outline\" size=\"large\" />\n }\n <p class=\"dcf-drag-description\">{{ label ? (label | translate) : (locale + \".drag_file\" | translate) }}</p>\n <ion-button class=\"dcf-button-select\" (click)=\"handleClickToSelect()\" size=\"small\">\n {{ buttonLabel ? (buttonLabel | translate) : (locale + \".buttons.select\" | translate) }}\n </ion-button>\n <div #container>\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n } @else {\n @if ((!directoryMode && !multiple) ) {\n <div class=\"dcf-preview dcf-grid dcf-grid-match dcf-grid-collapse\">\n <div class=\"dcf-width-1-4@m dcf-width-1-3@s dcf-flex dcf-flex-center dcf-flex-middle\">\n <div class=\"dcf-preview-image\">\n <ion-img\n [src]=\"preview\"\n [title]=\"locale + '.preview' | translate\"\n [alt]=\"locale + '.preview' | translate\"\n />\n <div class=\"dcf-overlay\">\n <ion-button (click)=\"showFilePreview(preview)\" fill=\"clear\" color=\"light\" size=\"small\">\n {{ locale + \".buttons.preview\" | translate }}\n </ion-button>\n </div>\n </div>\n </div>\n <div class=\"description dcf-flex dcf-flex-middle dcf-width-expand@s\">\n <div>\n <p class=\"dcf-title\">{{ locale + \".preview\" | translate }}</p>\n <p class=\"subtitle\">{{ files[0].name }}</p>\n <ion-button (click)=\"handleClear()\" fill=\"clear\" color=\"danger\" size=\"small\">{{ locale + \".buttons.clear\" | translate }} </ion-button>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"dcf-margin-bottom\">\n {{ locale + \".selection\" | translate: { \"0\": files.length > 10 ? files.length : `0${files.length}` } }}\n @if(errors.length > 0) {\n <br /><span class=\"dcf-error-message\">{{ locale + \".selection_error\" | translate: { \"0\": errors.length > 10 ? errors.length : `0${errors.length}` } }}</span>\n }\n </div>\n <div class=\"dcf-preview-list-container\">\n <ion-list class=\"dcf-preview-list\">\n @for (file of errors; track $index) {\n <ion-item lines=\"full\" class=\"dcf-error-item\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <div class=\"dcf-error-message\" slot=\"end\">\n {{ locale + \".errors.\" + file.error | translate: { \"0\": file.error === 'max_size' ? maxFileSize / 1024 / 1024 : file.name.split(\".\") } }}\n </div>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n </ion-item>\n }\n\n @for (file of files; track $index) {\n <ion-item lines=\"full\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n <div class=\"dcf-flex dcf-flex-middle\" slot=\"end\">\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n (click)=\"showFilePreview(file, file.type)\"\n [name]=\"'image-outline'\"\n />\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n [name]=\"'trash-outline'\"\n (click)=\"removeFile($index)\"\n [color]=\"'danger'\"\n [size]=\"'small'\"\n />\n </div>\n </ion-item>\n }\n </ion-list>\n </div>\n }\n }\n </div>\n\n\n </div>\n </div>\n </ngx-decaf-card>\n</div>\n\n<!-- <ion-card-header>\n <ion-card-title>Upload de Imagem</ion-card-title>\n </ion-card-header>\n\n <ion-card-content>\n <div\n class=\"dcf-drop-area\"\n [class.dragging]=\"dragging\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n >\n <div class=\"dcf-drop-content\">\n <ion-icon name=\"cloud-upload-outline\" size=\"large\"></ion-icon>\n <p>Arraste e solte aqui ou</p>\n <ion-button size=\"small\" fill=\"outline\" (click)=\"triggerFileSelect()\">Selecionar arquivo</ion-button>\n </div>\n </div>\n\n <input\n #fileInput\n type=\"file\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"onFileSelected($event)\"\n hidden\n />\n\n <div *ngIf=\"previewUrl\" class=\"dcf-preview\">\n <ion-item>\n <div slot=\"start\">\n <ion-img [src]=\"previewUrl\"></ion-img>\n </div>\n <ion-label>\n <h3>Pré-visualização</h3>\n <p *ngIf=\"files.length\">{{ files[0].name }}</p>\n </ion-label>\n </ion-item>\n </div>\n\n <ion-list *ngIf=\"files.length\">\n <ion-list-header>\n <ion-label>Arquivos selecionados</ion-label>\n </ion-list-header>\n <ion-item *ngFor=\"let f of files; let i = index\">\n <ion-label>{{ f.name }}</ion-label>\n <ion-note slot=\"end\">{{ (f.size / 1024 / 1024) | number:'1.1-1' }} MB</ion-note>\n <ion-button fill=\"clear\" slot=\"end\" (click)=\"removeFile(i)\">\n <ion-icon slot=\"icon-only\" name=\"close-circle\"></ion-icon>\n </ion-button>\n </ion-item>\n </ion-list>\n\n <div *ngIf=\"errors.length\">\n <ion-list>\n <ion-item *ngFor=\"let err of errors\">\n <ion-icon name=\"alert-circle\" slot=\"start\" color=\"danger\"></ion-icon>\n <ion-label color=\"danger\">{{ err }}</ion-label>\n </ion-item>\n </ion-list>\n </div>\n\n <ion-row class=\"dcf-actions\">\n <ion-col>\n <ion-button expand=\"block\" (click)=\"triggerFileSelect()\">Selecionar</ion-button>\n </ion-col>\n <ion-col>\n <ion-button expand=\"block\" color=\"danger\" fill=\"outline\" (click)=\"clear()\">Limpar</ion-button>\n </ion-col>\n </ion-row>\n </ion-card-content> -->\n","/**\n * @module module:lib/components/for-angular-components.module\n * @description Aggregate module for library components.\n * @summary Bundles and exports all UI components from `src/lib/components` as an\n * Angular `NgModule`. This module re-exports components like `ListComponent`,\n * `PaginationComponent`, `SearchbarComponent`, and others so they can be imported\n * together in consumer applications.\n *\n * @link {@link ForAngularComponentsModule}\n */\n\nimport { NgModule } from '@angular/core';\nimport { CrudFieldComponent } from './crud-field/crud-field.component';\nimport { CrudFormComponent } from './crud-form/crud-form.component';\nimport { ModelRendererComponent } from './model-renderer/model-renderer.component';\nimport { SearchbarComponent } from './searchbar/searchbar.component';\nimport { EmptyStateComponent } from './empty-state/empty-state.component';\nimport { ListItemComponent } from './list-item/list-item.component';\nimport { ComponentRendererComponent } from './component-renderer/component-renderer.component';\nimport { PaginationComponent } from './pagination/pagination.component';\nimport { ListComponent } from './list/list.component';\nimport { FieldsetComponent } from './fieldset/fieldset.component';\nimport { LayoutComponent } from './layout/layout.component';\nimport { FilterComponent } from './filter/filter.component';\nimport { SteppedFormComponent } from './stepped-form/stepped-form.component';\nimport { IconComponent } from './icon/icon.component';\nimport { CardComponent } from './card/card.component';\nimport { FileUploadComponent } from './file-upload/file-upload.component';\n\nconst Components = [\n ModelRendererComponent,\n ComponentRendererComponent,\n CrudFieldComponent,\n CrudFormComponent,\n EmptyStateComponent,\n ListComponent,\n ListItemComponent,\n SearchbarComponent,\n PaginationComponent,\n CrudFormComponent,\n FieldsetComponent,\n LayoutComponent,\n FilterComponent,\n SteppedFormComponent,\n IconComponent,\n CardComponent,\n FileUploadComponent\n];\n\n@NgModule({\n imports: [...Components],\n declarations: [],\n schemas: [],\n exports: [...Components],\n})\nexport class ForAngularComponentsModule {}\n","/**\n * @module module:lib/components/index\n * @description Barrel exports for components.\n * @summary Re-exports the component modules and individual components from\n * `src/lib/components` so consumers can import them from a single entrypoint.\n * This file exposes components such as `ListComponent`, `PaginationComponent`,\n * `SearchbarComponent`, and the `ForAngularComponentsModule`.\n *\n * @link {@link ForAngularComponentsModule}\n */\n\n// Component exports\nexport * from './component-renderer/component-renderer.component';\nexport * from './crud-field/crud-field.component';\nexport * from './crud-form/crud-form.component';\nexport * from './empty-state/empty-state.component';\nexport * from './fieldset/fieldset.component';\nexport * from './filter/filter.component';\nexport * from './layout/layout.component';\nexport * from './list/list.component';\nexport * from './list-item/list-item.component';\nexport * from './model-renderer/model-renderer.component';\nexport * from './pagination/pagination.component';\nexport * from './searchbar/searchbar.component';\nexport * from './stepped-form/stepped-form.component';\nexport * from './modal/modal.component';\nexport * from './icon/icon.component';\nexport * from './card/card.component';\nexport * from './file-upload/file-upload.component';\n// Module export\nexport * from './for-angular-components.module';\n","/**\n * @module lib/engine/interfaces\n * @description Type and interface definitions used by the Angular rendering engine.\n * @summary Exposes interfaces for component input metadata, rendering outputs, form events,\n * and supporting types used across the engine and components.\n */\nimport { FormArray, FormControl, FormGroup } from '@angular/forms';\nimport { ElementRef, EnvironmentInjector, Injector, Type } from '@angular/core';\nimport { OrderDirection } from '@decaf-ts/core';\nimport { AngularFieldDefinition, FieldUpdateMode, KeyValue, StringOrBoolean } from './types';\nimport { CrudOperationKeys, FieldProperties, IPagedComponentProperties } from '@decaf-ts/ui-decorators';\nimport { FormParent } from './types';\nimport { Model } from '@decaf-ts/decorator-validation';\n\n\n/**\n * @description Interface for models that can be rendered\n * @summary Defines the basic structure for models that can be rendered by the engine.\n * Contains an optional rendererId that uniquely identifies the rendered instance.\n * @interface IRenderedModel\n * @property {string} [rendererId] - Optional unique ID for the rendered model instance\n * @memberOf module:engine\n */\nexport interface IRenderedModel {\n rendererId?: string;\n}\n\n\n/**\n * @description Interface for components that hold an ElementRef\n * @summary Defines a component holder interface that provides access to the underlying DOM element through ElementRef\n * @interface IComponentHolder\n * @memberOf module:engine\n */\nexport interface IComponentHolder {\n /**\n * @description Reference to the component's DOM element\n * @property {ElementRef} component - The ElementRef instance providing access to the native DOM element\n */\n component: ElementRef;\n}\n\n/**\n * @description Interface for form components that hold both an ElementRef and a FormGroup\n * @summary Extends IComponentHolder to include a FormGroup for form handling capabilities\n * @interface IFormElement\n * @memberOf module:engine\n */\nexport interface IFormElement extends IComponentHolder {\n /**\n * @description The Angular FormGroup associated with this form element\n * @property {FormGroup|undefined} formGroup - The form group instance for managing form controls and validation\n */\n formGroup: FormParent | undefined;\n}\n\n\n/**\n * @description Interface for fieldset item representation in the UI.\n * @summary Defines the structure for items displayed in the reorderable list within the fieldset.\n * Each item represents a value added to the fieldset with display properties for the UI.\n * @memberOf module:engine\n */\nexport interface IFieldSetItem {\n /** @description Sequential index number for ordering items in the list */\n index: number;\n /** @description Primary display text for the item */\n title: string;\n /** @description Optional secondary text providing additional item details */\n description?: string;\n}\n\n/**\n * @description Interface for fieldset validation event data.\n * @summary Defines the structure of validation events emitted when form validation occurs.\n * Used for communication between form components and the fieldset container.\n * @memberOf module:engine\n */\nexport interface IFieldSetValidationEvent {\n /** @description The FormGroup containing the validated form controls */\n formGroup: FormArray | FormGroup;\n /** @description The current form value being validated */\n value: unknown;\n /** @description Whether the form validation passed or failed */\n isValid: boolean;\n}\n\n\n/**\n * @description Interface for individual filter query items\n * @summary Defines the structure of a single filter criterion in a filter query.\n * Each item represents one condition to be applied to the data, consisting of\n * an index (field name), a condition (comparison operator), and a value to compare against.\n * @interface IFilterQueryItem\n * @property {string} [index] - Optional field name or index to filter on\n * @property {string} [condition] - Optional comparison condition (e.g., 'Equal', 'Contains', 'Greater Than')\n * @property {string} [value] - Optional value to compare the field against\n * @memberOf module:engine\n */\nexport interface IFilterQueryItem {\n index?: string,\n condition?: string,\n value?: string\n};\n\n/**\n * @description Interface for sorting configuration objects\n * @summary Defines the structure for specifying sort criteria including the field\n * to sort by and the direction of the sort (ascending or descending).\n * @interface ISortObject\n * @property {string} value - The field name or property to sort by\n * @property {OrderDirection} direction - The sort direction (ASC or DSC)\n * @memberOf module:engine\n */\nexport interface ISortObject {\n value: string,\n direction: OrderDirection\n};\n\n/**\n * @description Interface for complete filter query configuration\n * @summary Defines the complete structure for filter and sort operations.\n * Combines multiple filter criteria with sorting configuration to provide\n * comprehensive data filtering and ordering capabilities.\n * @interface IFilterQuery\n * @property {IFilterQueryItem[] | undefined} query - Array of filter criteria or undefined for no filtering\n * @property {ISortObject} sort - Sorting configuration specifying field and direction\n * @memberOf module:engine\n */\nexport interface IFilterQuery {\n query: IFilterQueryItem[] | undefined,\n sort: ISortObject\n}\n\n\n/**\n * @description Component input properties\n * @summary Extends FieldProperties with additional properties specific to Angular components.\n * Includes update mode for form controls and optional FormGroup and FormControl references.\n * @interface IComponentProperties\n * @property {FieldUpdateMode} [updateMode] - When the field value should be updated\n * @property {FormGroup} [formGroup] - Optional FormGroup reference\n * @property {FormControl} [formControl] - Optional FormControl reference\n * @memberOf module:engine\n */\nexport interface IComponentProperties extends FieldProperties, IPagedComponentProperties {\n model?: Model | string;\n props?: FieldProperties;\n}\n\n\nexport interface IFormComponentProperties extends IComponentProperties {\n updateMode?: FieldUpdateMode;\n formGroup?: FormGroup;\n operation?: CrudOperationKeys | undefined;\n formControl?: FormControl;\n mergeInParent?: boolean;\n}\n\n\n/**\n * @description Component configuration structure\n * @summary Defines the configuration for dynamically creating Angular components.\n * Contains the component name, input properties, injector, and optional child components.\n * @interface IComponentConfig\n * @property {string} component - The name of the component to render\n * @property {IComponentProperties} inputs - The input properties for the component\n * @property {EnvironmentInjector | Injector} injector - The Angular injector for dependency injection\n * @property {IComponentConfig[]} [children] - Optional child component configurations\n * @memberOf module:engine\n */\nexport interface IComponentConfig {\n component: string;\n inputs: IComponentProperties;\n injector: EnvironmentInjector | Injector;\n children?: IComponentConfig[];\n}\n\n/**\n * @description Metadata structure for Angular components\n * @summary Defines the structure of metadata for Angular components, including\n * change detection strategy, selector, standalone status, imports, template, and styles.\n * This is used for reflection and dynamic component creation.\n * @interface ComponentMetadata\n * @property {number} changeDetection - The change detection strategy number\n * @property {string} selector - The CSS selector for the component\n * @property {boolean} standalone - Whether the component is standalone\n * @property imports - Array of imported modules/components\n * @property {string} template - The HTML template for the component\n * @property {string[]} styles - Array of CSS styles for the component\n * @memberOf module:engine\n */\nexport interface ComponentMetadata {\n changeDetection: number;\n selector: string;\n standalone: boolean;\n imports: (new (...args: unknown[]) => unknown)[];\n template: string;\n styles: string[];\n}\n\n\n/**\n * @description Output structure from the Angular rendering engine\n * @summary Defines the structure of the output produced by the NgxRenderingEngine\n * when rendering a component. Contains the component type, inputs, injector,\n * content nodes, and child components.\n * @typedef {Object} AngularDynamicOutput\n * @property {Type<unknown>} component - The Angular component type\n * @property {string} [rendererId] - Optional unique ID for the rendered component\n * @property {Record<string, unknown>} [inputs] - Optional input properties for the component\n * @property {Injector} [injector] - Optional Angular injector for dependency injection\n * @property {Node[][]} [content] - Optional content nodes for projection\n * @property {AngularDynamicOutput[]} [children] - Optional child components\n * @property {Type<unknown>} [instance] - Optional component instance\n * @property {FormGroup} [formGroup] - Optional component FormGroup\n * @property {FormControl} [formControl] - Optional component FormControl\n * @memberOf module:engine\n */\nexport interface AngularDynamicOutput {\n component?: Type<unknown>;\n rendererId?: string;\n inputs?: Record<string, unknown>;\n injector?: Injector;\n content?: Node[][];\n children?: AngularDynamicOutput[];\n formGroup?: FormGroup;\n page?: number;\n formControl?: FormControl;\n projectable?: boolean;\n}\n\n\n/**\n * @description Base option type for input components\n * @summary Defines the common structure for options used in select, radio, and checkbox inputs.\n * Contains properties for the display text, value, disabled state, CSS class, and icon.\n * @interface InputOption\n * @property {string} text - The display text for the option\n * @property {string|number} value - The value associated with the option\n * @property {StringOrBoolean} [disabled] - Whether the option is disabled\n * @property {string} [className] - CSS class name for styling the option\n * @property {string} [icon] - Icon to display with the option\n * @memberOf module:engine\n */\nexport interface InputOption {\n text: string;\n value: string | number;\n disabled?: StringOrBoolean;\n className?: string;\n icon?: string;\n}\n\n/**\n * @description Interface for list component refresh events\n * @summary Defines the structure of a refresh event for list components.\n * Contains an array of key-value pairs representing the new data for the list.\n * @interface IListComponentRefreshEvent\n * @property {KeyValue[]} data - Array of key-value pairs representing the new data\n * @memberOf module:engine\n */\nexport interface IListComponentRefreshEvent {\n data: KeyValue[];\n}\n\n\n/**\n * @description Form service control structure\n * @summary Defines the structure for a form control managed by the form service.\n * Contains the FormGroup control and the associated field properties for rendering.\n * @interface FormServiceControl\n * @property {FormGroup} control - The Angular FormGroup for the control\n * @property {AngularFieldDefinition} props - The field properties for rendering the control\n * @memberOf module:engine\n */\nexport interface FormServiceControl {\n control: FormGroup;\n props: AngularFieldDefinition;\n}\n\n\n/**\n * @description Interface for list item custom events\n * @summary Defines the structure of custom events triggered by list items.\n * Extends IBaseCustomEvent with additional properties for the action and primary key.\n * @interface ListItemCustomEvent\n * @property {string} action - The action performed on the list item\n * @property {string} [pk] - Optional primary key of the affected item\n * @property {any} data - The data associated with the event (inherited from IBaseCustomEvent)\n * @property {HTMLElement} [target] - The target element (inherited from IBaseCustomEvent)\n * @property {string} [name] - The name of the event (inherited from IBaseCustomEvent)\n * @property {string} component - The component that triggered the event (inherited from IBaseCustomEvent)\n * @memberOf module:engine\n */\nexport interface ListItemCustomEvent extends IBaseCustomEvent {\n action: string;\n pk?: string;\n}\n\n\n/**\n * @description Base interface for custom events\n * @summary Defines the base structure for custom events in the application.\n * Contains properties for the event data, target element, name, and component.\n * @interface IBaseCustomEvent\n * @property {any} data - The data associated with the event\n * @property {HTMLElement} [target] - The target element that triggered the event\n * @property {string} [name] - The name of the event\n * @property {string} component - The component that triggered the event\n * @memberOf module:engine\n */\nexport interface IBaseCustomEvent {\n name: string;\n component?: string;\n data?: unknown;\n target?: HTMLElement;\n}\n\n\nexport interface IModelPageCustomEvent extends IBaseCustomEvent {\n success: boolean;\n message?: string;\n}\n\n\n/**\n * @description Configuration for internationalization (i18n) resource file paths\n * @summary Defines the structure for configuring i18n resource file paths with prefix and suffix.\n * Used by the translation system to locate and load language resource files.\n * @interface I18nResourceConfig\n * @property {string} prefix - The prefix to be used for the resource file path\n * @property {string} suffix - The suffix to be appended to the resource file path\n * @memberOf module:engine\n */\nexport interface I18nResourceConfig {\n prefix: string,\n suffix: string\n}\n\n/**\n * @description Internationalization token configuration\n * @summary Defines the structure for i18n tokens, including resource configurations and versioned suffix flag.\n * @interface I18nToken\n * @property {I18nResourceConfig[]} resources - Array of i18n resource configurations\n * @property {boolean} versionedSuffix - Whether to use a versioned suffix for resources\n * @memberOf module:engine\n */\nexport interface I18nToken {\n resources: I18nResourceConfig[];\n versionedSuffix: boolean;\n}\n\n\n/**\n * @description CRUD form event type\n * @summary Extends IBaseCustomEvent to include optional handlers for CRUD form operations.\n * This event type is used for form-related actions like create, read, update, and delete operations.\n * @interface ICrudFormEvent\n * @property {Record<string, unknown>} [handlers] - Optional handlers for form operations\n * @property {string} name - The name of the event (inherited from IBaseCustomEvent)\n * @property {string} [component] - The component that triggered the event (inherited from IBaseCustomEvent)\n * @property {unknown} [data] - The data associated with the event (inherited from IBaseCustomEvent)\n * @property {HTMLElement} [target] - The target element (inherited from IBaseCustomEvent)\n * @memberOf module:engine\n */\nexport interface ICrudFormEvent extends IBaseCustomEvent {\n handlers?: Record<string, unknown>;\n};\n\n/**\n * @description Pagination custom event\n * @summary Event emitted by pagination components to signal page navigation.\n * Extends IBaseCustomEvent and carries a payload with the target page number and navigation direction.\n * @interface IPaginationCustomEvent\n * @property {Object} data - The pagination data payload\n * @property {number} data.page - The target page number\n * @property {'next' | 'previous'} data.direction - The navigation direction\n * @memberOf module:engine\n */\nexport interface IPaginationCustomEvent extends IBaseCustomEvent {\n data: {\n page: number;\n direction: 'next' | 'previous';\n };\n}\n\n/**\n * @description Menu item definition\n * @summary Represents a single item in a navigation or contextual menu.\n * Includes the visible label and optional metadata such as accessibility title, target URL, icon, and color.\n * @interface IMenuItem\n * @property {string} label - The visible text label for the menu item\n * @property {string} [title] - Optional accessibility title or tooltip text\n * @property {string} [url] - Optional target URL for navigation\n * @property {string} [icon] - Optional icon identifier to display with the menu item\n * @property {string} [color] - Optional color theme for the menu item\n * @memberOf module:engine\n */\nexport interface IMenuItem {\n label: string;\n title?: string;\n url?: string;\n icon?: string;\n color?: string;\n}\n\n/**\n * @description Form reactive submit event data\n * @summary Defines the structure of data emitted when a reactive form is submitted.\n * Contains the processed form data as key-value pairs.\n * @interface IFormReactiveSubmitEvent\n * @property {Record<string, unknown>} data - The form data as key-value pairs\n * @memberOf module:engine\n */\nexport interface IFormReactiveSubmitEvent {\n data: Record<string, unknown>;\n}\n\n/**\n * @description CRUD form options configuration\n * @summary Defines the configuration options for CRUD form buttons including submit and clear buttons.\n * Each button can be customized with text, icon, and icon position.\n * @interface ICrudFormOptions\n * @property {Object} buttons - Configuration for form action buttons\n * @property {Object} buttons.submit - Submit button configuration\n * @property {string} [buttons.submit.icon] - Optional icon for the submit button\n * @property {'start' | 'end'} [buttons.submit.iconSlot] - Position of the icon relative to text\n * @property {string} [buttons.submit.text] - Text label for the submit button\n * @property {Object} [buttons.clear] - Optional clear button configuration\n * @property {string} [buttons.clear.icon] - Optional icon for the clear button\n * @property {'start' | 'end'} [buttons.clear.iconSlot] - Position of the icon relative to text\n * @property {string} [buttons.clear.text] - Text label for the clear button\n * @memberOf module:engine\n */\nexport interface ICrudFormOptions {\n buttons: {\n submit: {\n icon?: string;\n iconSlot?: 'start' | 'end';\n text?: string;\n };\n clear?: {\n icon?: string;\n iconSlot?: 'start' | 'end';\n text?: string;\n };\n };\n}\n\n/**\n * @description Empty list display options\n * @summary Defines the configuration for displaying an empty state in list components\n * when no data is available. Includes text, button, icon, and link settings.\n * @interface IListEmptyOptions\n * @property {string} title - Title text or translation key for empty state\n * @property {string} subtitle - Subtitle text or translation key for empty state\n * @property {boolean} showButton - Whether to show an action button in empty state\n * @property {string} buttonText - Button text or translation key\n * @property {string} link - Navigation link for the button\n * @property {string} icon - Icon identifier for the empty state\n * @memberOf module:engine\n */\nexport interface IListEmptyOptions {\n title: string;\n subtitle: string;\n showButton: boolean;\n buttonText: string;\n link: string;\n icon: string;\n}\n\n/**\n * @description Event emitted when the viewport/window size changes.\n * @summary Provides the new width and height in pixels for responsive handlers.\n *\n * Typical usage: subscribed by UI layout services or components to react to\n * window resizing and adjust layouts or trigger reflows.\n *\n * @example\n * const e: IWindowResizeEvent = { width: window.innerWidth, height: window.innerHeight };\n */\nexport interface IWindowResizeEvent {\n /** The new width of the window (innerWidth) in pixels */\n width: number;\n /** The new height of the window (innerHeight) in pixels */\n height: number;\n}\n\n\n\nexport interface IFileUploadError {\n name: string;\n size?: number;\n error: string\n}\n","/**\n * @description Abstract base class for dynamic Angular modules\n * @summary The DynamicModule serves as a base class for Angular modules that need to be\n * dynamically loaded or configured at runtime. It provides a common type for the rendering\n * engine to identify and work with dynamic modules.\n * @class DynamicModule\n * @example\n * ```typescript\n * @NgModule({\n * declarations: [MyComponent],\n * imports: [CommonModule]\n * })\n * export class MyDynamicModule extends DynamicModule {}\n * ```\n */\nexport abstract class DynamicModule {}\n","/**\n * @module module:lib/engine/NgxEventHandler\n * @description Event handler base class used by Decaf components.\n * @summary Defines NgxEventHandler which standardizes event handling logic and provides\n * logging support for handlers that process custom events emitted by components.\n *\n * @link {@link NgxEventHandler}\n */\nimport { LoggedClass } from \"@decaf-ts/logging\";\nimport { IBaseCustomEvent } from \"./interfaces\";\n\nexport abstract class NgxEventHandler<PAYLOAD> extends LoggedClass {\n\tabstract handle(evt: IBaseCustomEvent | CustomEvent<PAYLOAD>): Promise<unknown>;\n}\n","/**\n * @module lib/engine/NgxPageDirective\n * @description Base page component for Decaf Angular applications.\n * @summary Provides a page-level base class (NgxPageDirective) that extends NgxComponentDirective and\n * offers page-focused utilities such as menu management, title handling and router event hooks.\n * @link {@link NgxPageDirective}\n */\nimport { AfterViewInit, Directive, Inject, inject, OnInit } from \"@angular/core\";\nimport { NgxComponentDirective} from \"./NgxComponentDirective\";\nimport { Title } from \"@angular/platform-browser\";\nimport { IMenuItem } from \"./interfaces\";\nimport { CPTKN } from \"../for-angular-common.module\";\nimport { NavigationEnd, NavigationStart } from \"@angular/router\";\nimport { removeFocusTrap } from \"../utils/helpers\";\nimport { KeyValue } from \"./types\";\nimport { MenuController } from \"@ionic/angular\";\n\n\n/**\n * @description Base directive for page-level components in Decaf Angular applications.\n * @summary Abstract directive that provides foundational functionality for page components.\n * Extends NgxComponentDirective to add page-specific features including menu management,\n * page title handling, and Ionic lifecycle hooks. This directive serves as the base class for\n * all page-level components, providing consistent behavior for navigation, routing, and UI state.\n * @class NgxPageDirective\n * @extends {NgxComponentDirective}\n * @memberOf module:lib/engine/NgxPageDirective\n */\n@Directive()\nexport abstract class NgxPageDirective extends NgxComponentDirective implements OnInit, AfterViewInit {\n\n /**\n * @description Application name for display or identification purposes.\n * @summary Stores the name of the application, which can be used for display in headers,\n * titles, or for logging and identification throughout the app.\n * @type {string}\n * @memberOf module:lib/engine/NgxPageDirective\n */\n appName?: string;\n\n /**\n * @description Page title text for the current view.\n * @summary Stores the title text to be displayed for this page. This can be set dynamically\n * based on the current route or menu configuration and is used to update the browser's\n * title bar or page header.\n * @type {string}\n * @default ''\n * @memberOf module:lib/engine/NgxPageDirective\n */\n title: string = '';\n\n\n /**\n * @description Global key-value pairs for application-wide settings.\n * @summary This property stores global configuration values that can be accessed\n * throughout the application. It is typically used to manage shared state or\n * settings that are relevant across multiple components or services.\n * @type {KeyValue}\n * @memberOf module:lib/engine/NgxPageDirective\n */\n globals!: KeyValue;\n\n\n /**\n * @description Ionic menu controller service for menu management.\n * @summary Injected service that provides programmatic control over Ionic menu components.\n * This service allows the component to open, close, toggle, and manage menu states within\n * the application. It provides access to menu functionality for implementing navigation\n * and layout features that require menu interaction.\n * @protected\n * @type {MenuController}\n * @memberOf module:lib/engine/NgxPageDirective\n */\n protected menuController: MenuController = inject(MenuController);\n\n\n /**\n * @description Menu items array for page navigation.\n * @summary Contains the collection of menu items available for this page. Each menu item\n * defines a navigation option with properties like label, URL, icon, and visibility settings.\n * This array is used to construct the application's navigation menu and can be filtered or\n * customized per page.\n * @protected\n * @type {IMenuItem[]}\n * @default []\n * @memberOf module:lib/engine/NgxPageDirective\n */\n protected menu: IMenuItem[] = [];\n\n /**\n * @description Angular Title service for browser title management.\n * @summary Injected service that provides control over the browser's document title.\n * Used to dynamically set the page title based on the current route or active menu item,\n * improving SEO and user experience.\n * @protected\n * @type {Title}\n * @memberOf module:lib/engine/NgxPageDirective\n */\n protected titleService: Title = inject(Title);\n\n\n /**\n * @description Flag indicating whether the page should display the navigation menu.\n * @summary Controls the visibility and availability of the application menu for this page.\n * When set to true, the menu is enabled and accessible to users. When false, the menu\n * is disabled, which is useful for pages like login screens or standalone views that\n * should not show navigation options.\n * @protected\n * @type {boolean}\n * @default true\n * @memberOf module:lib/engine/NgxPageDirective\n */\n protected hasMenu: boolean = true;\n\n\n /**\n * @description Currently active route path for the page (without leading slash).\n * @summary This protected property stores the current route segment used by the\n * page to determine the displayed title and menu state. It is updated on\n * NavigationEnd events (see ngAfterViewInit) and consumed by the `pageTitle`\n * getter and `setPageTitle()` method. When undefined the component will\n * attempt to resolve the route from the router URL.\n * @protected\n * @type {string | undefined}\n * @default undefined\n */\n protected currentRoute?: string;\n\n /**\n * @description Constructor for NgxPageDirective.\n * @summary Initializes the page directive with optional locale root and menu visibility settings.\n * Calls the parent NgxComponentDirective constructor to set up base functionality including\n * logging, localization, and component identification.\n * @param {string} [localeRoot] - Optional locale root key for internationalization\n * @param {boolean} [hasMenu=true] - Whether this page should display the menu\n * @memberOf module:lib/engine/NgxPageDirective\n */\n // eslint-disable-next-line @angular-eslint/prefer-inject\n constructor(@Inject(CPTKN) localeRoot: string = \"NgxPageDirective\", @Inject(CPTKN) hasMenu: boolean = true) {\n super(localeRoot);\n this.hasMenu = hasMenu;\n // subscribe to media service color scheme changes\n this.mediaService.colorScheme$.subscribe();\n }\n\n get pageTitle(): string {\n if(this.title)\n return this.title;\n if(this.locale)\n return `${this.locale}.title`;\n if(this.currentRoute)\n return this.currentRoute?.charAt(0).toUpperCase() + this.currentRoute?.slice(1) || 'Decaf For Angular';\n return \"\";\n }\n\n ngOnInit(): Promise<void> | void{\n // connect component to media service for color scheme toggling\n this.mediaService.colorSchemeObserver(this.component);\n this.currentRoute = this.router.url.replace('/', '');\n this.setPageTitle(this.currentRoute);\n this.initialized = true;\n }\n\n /**\n * @description Ionic lifecycle hook called when the page is about to enter view.\n * @summary This lifecycle hook is triggered just before the page becomes visible to the user.\n * It enables or disables the application menu based on the hasMenu property, allowing pages\n * to control whether the menu should be accessible. This is useful for pages like login screens\n * where the menu should be hidden.\n * @return {Promise<void>} A promise that resolves when menu state is updated\n * @memberOf module:lib/engine/NgxPageDirective\n */\n\tasync ngAfterViewInit(): Promise<void> {\n this.router.events.subscribe(async event => {\n if(event instanceof NavigationEnd) {\n const url = (event?.url || \"\").replace('/', '');\n this.hasMenu = url !== \"login\" && url !== \"\";\n this.currentRoute = url;\n this.setPageTitle(this.currentRoute);\n this.title = this.pageTitle;\n }\n if (event instanceof NavigationStart)\n removeFocusTrap();\n });\n await this.menuController.enable(this.hasMenu);\n\t}\n\n\n\n /**\n * @description Sets the browser page title based on the current route.\n * @summary Updates the browser's document title by finding the active menu item that matches\n * the provided route. If a matching menu item is found, it sets the title using the format\n * \"Decaf For Angular - {menu title or label}\". This improves SEO and provides clear context\n * to users about the current page. If a custom menu array is provided, it uses that instead\n * of the component's default menu.\n * @protected\n * @param {string} route - The current route path to match against menu items\n * @param {IMenuItem[]} [menu] - Optional custom menu array to search (uses this.menu if not provided)\n * @return {void}\n * @memberOf module:lib/engine/NgxPageDirective\n */\n protected async setPageTitle(route?: string, menu?: IMenuItem[]): Promise<void> {\n if(!route)\n route = this.router.url.replace('/', '');\n if(!menu)\n menu = this.menu;\n const activeMenu = menu.find(item => item?.url?.includes(route));\n if(activeMenu) {\n const title = activeMenu?.title || activeMenu?.label;\n this.titleService.setTitle(`${await this.translate(title)} ${this.appName ? `- ${this.appName}` : ''}`);\n if(!this.title)\n this.title = title;\n }\n }\n\n}\n","import { Directive, Input } from '@angular/core';\nimport {\n InternalError,\n IRepository,\n OperationKeys,\n} from '@decaf-ts/db-decorators';\nimport { EventIds, Repository } from '@decaf-ts/core';\nimport { Model, Primitives } from '@decaf-ts/decorator-validation';\nimport { NgxPageDirective } from './NgxPageDirective';\nimport { ComponentEventNames } from './constants';\nimport { IBaseCustomEvent, IModelPageCustomEvent } from './interfaces';\nimport { KeyValue, DecafRepository } from './types';\nimport { Constructor, Metadata } from '@decaf-ts/decoration';\nimport { getModelAndRepository } from '../for-angular-common.module';\n\n\n@Directive()\nexport abstract class NgxModelPageDirective extends NgxPageDirective {\n\n /**\n * @description Primary key value of the current model instance.\n * @summary Specifies the primary key value for the current model record being displayed or\n * manipulated by the component. This identifier is used for CRUD operations that target\n * specific records, such as read, update, and delete operations. The value corresponds to\n * the field designated as the primary key in the model definition.\n * @type {EventIds}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override modelId!: EventIds;\n\n /**\n * @description The CRUD operation type to be performed on the model.\n * @summary Specifies which operation (Create, Read, Update, Delete) this component instance\n * should perform. This determines the UI behavior, form configuration, and available actions.\n * The operation affects form validation, field availability, and the specific repository\n * method called during data submission.\n *\n * @type {OperationKeys.CREATE | OperationKeys.READ | OperationKeys.UPDATE | OperationKeys.DELETE}\n * @default OperationKeys.READ\n * @memberOf ModelPage\n */\n @Input()\n override operation:\n | OperationKeys.CREATE\n | OperationKeys.READ\n | OperationKeys.UPDATE\n | OperationKeys.DELETE = OperationKeys.READ;\n\n /**\n * @description The name of the model class to operate on.\n * @summary Identifies which registered model class this component should work with.\n * This name is used to resolve the model constructor from the global model registry\n * and instantiate the appropriate repository for data operations. The model must\n * be properly registered using the @Model decorator for resolution to work.\n *\n * @type {string}\n * @memberOf ModelPage\n */\n @Input()\n modelName!: string;\n\n\n /**\n * @description Array of operations allowed for the current model instance.\n * @summary Dynamically determined list of operations that are permitted based on\n * the current context and model state. Initially contains CREATE and READ operations,\n * with UPDATE and DELETE added when a modelId is present. This controls which\n * action buttons are displayed and which operations are accessible to the user.\n *\n * @type {OperationKeys[]}\n * @default [OperationKeys.CREATE, OperationKeys.READ]\n * @memberOf ModelPage\n */\n allowedOperations: OperationKeys[] = [OperationKeys.CREATE, OperationKeys.READ];\n\n\n /**\n * @description Current model data loaded from the repository.\n * @summary Stores the raw data object representing the current model instance retrieved\n * from the repository. This property holds the actual data values for the model being\n * displayed or edited, and is set to undefined when no data is available or when an\n * error occurs during data loading.\n * @type {KeyValue | undefined}\n * @default undefined\n * @memberOf NgxModelPageDirective\n */\n modelData: KeyValue | undefined = undefined;\n\n /**\n * @description Error message from failed operations.\n * @summary Stores error messages that occur during repository operations such as\n * data loading, creation, update, or deletion. When set, this indicates an error\n * state that should be displayed to the user. Cleared on successful operations.\n * @type {string | undefined}\n * @default undefined\n * @memberOf NgxModelPageDirective\n */\n errorMessage: string | undefined = undefined;\n\n\n // constructor(@Inject(CPTKN) hm: boolean = true, @Inject(CPTKN) protected toastController?: ToastController) {\n // super(\"NgxModelPageDirective\");\n // }\n\n override get pageTitle(): string {\n if(!this.modelName && this.model instanceof Model)\n this.modelName = this.model?.constructor?.name || \"\";\n if(!this.operation)\n return this.title ? this.title : `Listing ${this.modelName}`;\n const operation = this.operation.charAt(0).toUpperCase() + this.operation.slice(1).toLowerCase();\n return this.modelName ?\n `${operation} ${this.modelName}` : this.title;\n }\n /**\n * @description Lazy-initialized repository getter with model resolution.\n * @summary Creates and returns a repository instance for the specified model name.\n * Resolves the model constructor from the global registry, instantiates the repository,\n * and creates a new model instance. Throws an InternalError if the model is not\n * properly registered with the @Model decorator.\n *\n * @return {DecafRepository<Model>} The repository instance for the current model\n *\n * @throws {InternalError} When the model is not found in the registry\n */\n protected override get repository(): DecafRepository<Model> | undefined{\n try {\n if (!this._repository) {\n const constructor = Model.get(this.modelName);\n if (!constructor)\n throw new InternalError(\n 'Cannot find model. was it registered with @model?',\n );\n this._repository = Repository.forModel(constructor);\n if (!this.pk)\n this.pk = this._repository.pk as string;\n this.model = new constructor() as Model;\n }\n }catch (error: unknown) {\n this.log.warn(`Error getting repository for model: ${this.modelName}. ${(error as Error).message}`);\n this._repository = undefined;\n // throw new InternalError((error as Error)?.message || (error as string));\n }\n return this._repository as DecafRepository<Model>;\n }\n\n /**\n * @description Angular lifecycle hook for component initialization.\n * @summary Initializes the component by setting up the logger instance using the getLogger\n * utility. This ensures that logging is available throughout the component's lifecycle\n * for error tracking and debugging purposes.\n */\n async ionViewWillEnter(): Promise<void> {\n // await super.ionViewWillEnter();\n if (this.modelId)\n this.allowedOperations = this.allowedOperations.concat([OperationKeys.UPDATE, OperationKeys.DELETE]);\n this.getLocale(this.modelName as string);\n await this.refresh(this.modelId);\n this.initialized = true;\n }\n\n\n /**\n * @description Refreshes the component data by loading the specified model instance.\n * @summary Loads model data from the repository based on the current operation type.\n * For READ, UPDATE, and DELETE operations, fetches the existing model data using\n * the provided unique identifier. Handles errors gracefully by logging them through\n * the logger instance.\n *\n * @param {string} [uid] - The unique identifier of the model to load; defaults to modelId\n */\n async refresh(uid?: EventIds): Promise<void> {\n if (!uid)\n uid = this.modelId;\n this._repository = this.repository;\n switch(this.operation){\n case OperationKeys.READ:\n case OperationKeys.UPDATE:\n case OperationKeys.DELETE:\n this.model = await this.handleGet(uid || this.modelId, this._repository, this.modelName as string) as Model;\n break;\n }\n }\n\n /**\n * @description Generic event handler for component events.\n * @summary Processes incoming events from child components and routes them to appropriate\n * handlers based on the event name. Currently handles SUBMIT events by delegating to\n * the handleSubmit method. This centralized event handling approach allows for easy\n * extension and consistent event processing.\n *\n * @param {IBaseCustomEvent} event - The event object containing event data and metadata\n */\n override async handleEvent(event: IBaseCustomEvent) {\n const { name } = event;\n switch (name) {\n case ComponentEventNames.SUBMIT:\n await this.handleSubmit(event);\n break;\n }\n }\n\n /**\n * @description Handles form submission events for CRUD operations.\n * @summary Processes form submission by executing the appropriate repository operation\n * based on the current operation type. Handles CREATE, UPDATE, and DELETE operations,\n * processes the form data, refreshes the repository cache, navigates back to the previous\n * page, and displays success notifications. Comprehensive error handling ensures robust\n * operation with detailed logging.\n *\n * @param {IBaseCustomEvent} event - The submit event containing form data\n * @return {Promise<IModelPageCustomEvent|void>} Promise that resolves on success or throws on error\n */\n async handleSubmit(event: IBaseCustomEvent, redirect: boolean = false): Promise<IModelPageCustomEvent|void> {\n try {\n const repo = this._repository as IRepository<Model>;\n const operation = this.operation === OperationKeys.READ ? 'delete' : this.operation.toLowerCase();\n const data = this.parseData(event.data as KeyValue, operation as OperationKeys);\n const result = this.operation === OperationKeys.CREATE ?\n await repo.create(data as Model) : this.operation === OperationKeys.UPDATE ?\n await repo.update(data as Model) : repo.delete(data as string | number);\n const message = await this.translate(\n `operations.${operation}.${result ? 'success' : 'error'}`, {\n \"0\": this.pk,\n \"1\": this.modelId || (result as KeyValue)[this.pk],\n }\n );\n\n if (result) {\n (repo as DecafRepository<Model>).refresh(this.modelName, this.operation, this.modelId as EventIds);\n if(redirect)\n this.location.back();\n }\n return {\n ... event,\n success: result ? true : false,\n message\n };\n } catch (error: unknown) {\n this.log.error(error as Error | string);\n return {\n ... event,\n success: false,\n message: error instanceof Error ? error.message : error as string\n };\n }\n }\n\n /**\n * @description Retrieves a model instance from the repository by unique identifier.\n * @summary Fetches a specific model instance using the repository's read method.\n * Handles both string and numeric identifiers by automatically converting numeric\n * strings to numbers. If no identifier is provided, logs an informational message\n * and navigates back to the previous page. Returns undefined for missing instances.\n *\n * @param {string} uid - The unique identifier of the model instance to retrieve\n * @return {Promise<Model | undefined>} Promise resolving to the model instance or undefined\n */\n async handleGet(uid?: EventIds, repository?: IRepository<Model>, modelName?: string): Promise<Model | undefined> {\n if (!uid) {\n this.log.info('No key passed to model page read operation, backing to last page');\n this.location.back();\n return undefined;\n }\n\n const getRepository = async (modelName: string, parent?: string, model?: KeyValue): Promise<DecafRepository<Model> | undefined> => {\n if(this._repository)\n return this._repository as DecafRepository<Model>;\n const constructor = Model.get(modelName);\n if (constructor) {\n const properties = Metadata.properties(constructor as Constructor<Model>) as string[];\n if(!model)\n model = {} as KeyValue;\n for (const prop of properties) {\n const type = Metadata.type(constructor as Constructor<Model>, prop).name;\n const context = getModelAndRepository(type as string);\n if(!context)\n return getRepository(type, prop, model);\n const {repository} = context;\n if(modelName === this.modelName) {\n const data = await this.handleGet(uid, repository, modelName);\n this.model = Model.build({[prop]: data}, modelName);\n } else {\n model[prop as string] = Model.build({}, type);\n }\n }\n (this.model as KeyValue)[parent as string] = Model.build(model, modelName);\n }\n }\n\n repository = (repository || await getRepository(modelName as string)) as IRepository<Model>;\n if(!repository)\n return this.model as Model;\n const type = Metadata.type(repository.class as Constructor<Model>, repository.pk as string).name;\n try {\n const result = await (repository as IRepository<Model>).read(\n ([Primitives.NUMBER, Primitives.BIGINT].includes(type.toLowerCase()) ? Number(uid) : uid) as string | number,\n );\n return result;\n } catch (error: unknown) {\n this.log.for(this.handleGet).info(`Error getting model instance with id ${uid}: ${(error as Error).message}`);\n return undefined;\n }\n }\n\n /**\n * @description Parses and transforms form data for repository operations.\n * @summary Converts raw form data into the appropriate format for repository operations.\n * For DELETE operations, returns the primary key value (string or number). For CREATE\n * and UPDATE operations, builds a complete model instance using the Model.build method\n * with proper primary key assignment for updates.\n *\n * @param {Partial<Model>} data - The raw form data to be processed\n * @return {Model | string | number} Processed data ready for repository operations\n * @private\n */\n private parseData(data: Partial<Model>, operation: OperationKeys): Model | EventIds {\n const repo = this._repository as IRepository<Model>;\n let uid = this.modelId as EventIds;\n if (repo.pk === 'id' as keyof Model)\n uid = Number(uid);\n if (operation !== OperationKeys.DELETE)\n return Model.build(this.modelId ? Object.assign(data, {[repo.pk]: uid}) : data, this.modelName) as Model;\n return uid as EventIds;\n }\n}\n","/**\n * @module engine\n * @description Angular rendering engine for Decaf applications\n * @summary The engine module provides core functionality for rendering Angular components\n * in Decaf applications. It includes constants, decorators, rendering engines, and utility types\n * that enable dynamic component creation, property mapping, and component lifecycle management.\n * Key exports include {@link NgxRenderingEngine}, {@link DynamicModule}, and various decorators\n * for component configuration.\n */\nexport * from './constants';\nexport * from './decorators';\nexport * from './types';\nexport * from './interfaces';\nexport * from './DynamicModule';\nexport * from './NgxRenderingEngine';\nexport * from './NgxFormFieldDirective';\nexport * from '../services/NgxFormService';\nexport * from './NgxEventHandler';\nexport * from './NgxModelPageDirective';\nexport * from './NgxPageDirective';\nexport * from './NgxFormDirective';\nexport * from './NgxParentComponentDirective';\nexport * from './NgxComponentDirective';\nexport * from '../services/NgxMediaService';\n","/**\n * @module module:lib/public-apis\n * @description Public exports for the for-angular package.\n * @summary Re-exports the public API surface for the Decaf for-Angular integration. Consumers\n * should import from this barrel to access components, engine utilities, directives, helpers,\n * and i18n loaders provided by the library.\n *\n * @link {@link ForAngularCommonModule}\n */\nimport '@decaf-ts/ui-decorators';\nexport * from './components';\nexport * from './engine';\nexport * from './directives';\nexport * from './utils';\nexport * from './i18n/Loader';\nexport * from './for-angular-common.module';\n/**\n * @description Angular integration for the Decaf framework\n * @summary This module provides Angular components and services for integrating with the Decaf framework.\n * It includes components for rendering models, CRUD operations, and form handling, as well as\n * rendering engines and utility functions to facilitate Angular application development with Decaf.\n * @module for-angular\n */\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-apis';\n"],"names":["isValidDate","AllIcons"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"decaf-ts-for-angular.mjs","sources":["../../../src/lib/engine/constants.ts","../../../src/lib/engine/ValidatorFactory.ts","../../../src/lib/for-angular-common.module.ts","../../../src/lib/utils/helpers.ts","../../../src/lib/services/NgxFormService.ts","../../../src/lib/utils/DecafFakerRepository.ts","../../../src/lib/utils/index.ts","../../../src/lib/engine/NgxRenderingEngine.ts","../../../src/lib/i18n/Loader.ts","../../../src/lib/services/NgxMediaService.ts","../../../src/lib/engine/NgxComponentDirective.ts","../../../src/lib/engine/NgxRenderableComponentDirective.ts","../../../src/lib/components/component-renderer/component-renderer.component.ts","../../../src/lib/components/component-renderer/component-renderer.component.html","../../../src/lib/engine/NgxFormFieldDirective.ts","../../../src/lib/engine/decorators.ts","../../../src/lib/components/model-renderer/model-renderer.component.ts","../../../src/lib/components/model-renderer/model-renderer.component.html","../../../src/lib/engine/NgxParentComponentDirective.ts","../../../src/lib/components/modal/modal.component.ts","../../../src/lib/components/modal/modal.component.html","../../../src/lib/components/crud-field/crud-field.component.ts","../../../src/lib/components/crud-field/crud-field.component.html","../../../src/lib/engine/NgxFormDirective.ts","../../../src/lib/components/card/card.component.ts","../../../src/lib/components/card/card.component.html","../../../src/lib/components/layout/layout.component.ts","../../../src/lib/components/layout/layout.component.html","../../../src/lib/components/crud-form/crud-form.component.ts","../../../src/lib/components/crud-form/crud-form.component.html","../../../src/lib/directives/NgxSvgDirective.ts","../../../src/lib/components/icon/icon.component.ts","../../../src/lib/components/icon/icon.component.html","../../../src/lib/components/empty-state/empty-state.component.ts","../../../src/lib/components/empty-state/empty-state.component.html","../../../src/lib/components/fieldset/fieldset.component.ts","../../../src/lib/components/fieldset/fieldset.component.html","../../../src/lib/components/searchbar/searchbar.component.ts","../../../src/lib/components/searchbar/searchbar.component.html","../../../src/lib/components/filter/filter.component.ts","../../../src/lib/components/filter/filter.component.html","../../../src/lib/components/pagination/pagination.component.ts","../../../src/lib/components/pagination/pagination.component.html","../../../src/lib/components/list/list.component.ts","../../../src/lib/components/list/list.component.html","../../../src/lib/components/list-item/list-item.component.ts","../../../src/lib/components/list-item/list-item.component.html","../../../src/lib/components/stepped-form/stepped-form.component.ts","../../../src/lib/components/stepped-form/stepped-form.component.html","../../../src/lib/components/file-upload/file-upload.component.ts","../../../src/lib/components/file-upload/file-upload.component.html","../../../src/lib/components/for-angular-components.module.ts","../../../src/lib/components/index.ts","../../../src/lib/engine/interfaces.ts","../../../src/lib/engine/DynamicModule.ts","../../../src/lib/engine/NgxEventHandler.ts","../../../src/lib/engine/NgxPageDirective.ts","../../../src/lib/engine/NgxModelPageDirective.ts","../../../src/lib/engine/index.ts","../../../src/lib/public-apis.ts","../../../src/lib/decaf-ts-for-angular.ts"],"sourcesContent":["import { VALIDATION_PARENT_KEY } from '@decaf-ts/decorator-validation';\nimport { ICrudFormOptions, IListEmptyOptions } from './interfaces';\n\nimport { ModalOptions } from '@ionic/angular/standalone';\n\n/**\n * @description Angular engine key constants.\n * @summary Contains key strings used by the Angular rendering engine for reflection,\n * dynamic component creation, and other engine operations. These constants provide\n * consistent naming for metadata keys, DOM attributes, and component identification\n * throughout the rendering system.\n * @typedef {Object} AngularEngineKeys\n * @property {string} REFLECT - Prefix for reflection metadata keys\n * @property {string} DYNAMIC - Key for dynamic component identification\n * @property {string} ANNOTATIONS - Key for component annotations\n * @property {string} ECMP - Key for embedded components\n * @property {string} NG_REFLECT - Prefix for Angular reflection attributes\n * @property {string} RENDERED - Prefix for rendered component markers\n * @property {string} MAPPER - Key for property mappers\n * @property {string} CHILDREN - Key for child components\n * @property {string} LISTABLE - Key for listable components\n * @property {string} RENDER - Key for renderable components\n * @property {string} RENDERED_ID - Template for rendered component IDs\n * @property {string} PARENT - Key for comparison decorators and validators\n * @property {string} VALIDATION_PARENT_KEY - Key for validation parent reference\n * @property {string} FLAVOUR - Identifier for the Angular engine flavor\n * @const AngularEngineKeys\n * @memberOf module:lib/engine/constants\n */\nexport const AngularEngineKeys = {\n REFLECT: `angular`,\n DYNAMIC: 'dynamic-component',\n ANNOTATIONS: '__annotations__',\n ECMP: 'ecmp',\n NG_REFLECT: 'ng-reflect-',\n RENDERED: 'rendered-as-',\n MAPPER: 'mapper',\n CHILDREN: 'children',\n LISTABLE: 'listable',\n RENDER: 'render',\n RENDERED_ID: 'rendered-as-{0}',\n PARENT: '_parent',\n VALIDATION_PARENT_KEY: VALIDATION_PARENT_KEY,\n FLAVOUR: 'angular',\n LOADED: 'engineLoaded',\n DARK_PALETTE_CLASS: 'dcf-palette-dark',\n} as const;\n\n/**\n * @description Form validation state constants.\n * @summary Contains constants representing the possible validation states of a form.\n * These are used to check and handle form validation throughout the application.\n * The VALID state indicates all form controls pass validation, while INVALID\n * indicates one or more validation errors exist.\n * @typedef {Object} FormConstants\n * @property {string} VALID - Constant representing a valid form state\n * @property {string} INVALID - Constant representing an invalid form state\n * @const FormConstants\n * @memberOf module:lib/engine/constants\n */\nexport const FormConstants = {\n VALID: 'VALID',\n INVALID: 'INVALID',\n} as const;\n\n/**\n * @description Event name constants.\n * @summary Contains constants for standardized event names used throughout the application.\n * These constants ensure consistent event naming across components and make it easier to\n * track and handle events. Each constant represents a specific application event type.\n * @typedef {Object} ComponentEventNames\n * @property {string} BACK_BUTTON_NAVIGATION - Event fired when back button navigation ends\n * @property {string} REFRESH - Event fired when a refresh action occurs\n * @property {string} CLICK - Event fired when a click action occurs\n * @property {string} SUBMIT - Event fired when a form submission occurs\n * @property {string} VALIDATION_ERROR - Event fired when a validation error occurs\n * @property {string} FIELDSET_ADD_GROUP - Event fired when adding a group to a fieldset\n * @property {string} FIELDSET_UPDATE_GROUP - Event fired when updating a fieldset group\n * @property {string} FIELDSET_REMOVE_GROUP - Event fired when removing a fieldset group\n * @const ComponentEventNames\n * @memberOf module:lib/engine/constants\n */\nexport const ComponentEventNames = {\n BACK_BUTTON_NAVIGATION: 'backButtonNavigationEndEvent',\n REFRESH: 'RefreshEvent',\n CLICK: 'ClickEvent',\n CHANGE: 'ChangeEvent',\n SUBMIT: 'SubmitEvent',\n VALIDATION_ERROR: 'validationErrorEvent',\n FIELDSET_ADD_GROUP: 'fieldsetAddGroupEvent',\n FIELDSET_UPDATE_GROUP: 'fieldsetUpdateGroupEvent',\n FIELDSET_REMOVE_GROUP: 'fieldsetRemoveGroupEvent',\n THEME_CHANGE: 'themeChangeEvent',\n // FIELDSET_GROUP_VALIDATION: 'fieldsetGroupValidationEvent'\n} as const;\n\n/**\n * @description Logger level constants.\n * @summary Defines the logging levels used in the application's logging system.\n * Lower numeric values represent more verbose logging, while higher values represent\n * more critical logs. These levels control which log messages are output based on\n * the configured logging threshold.\n * @enum {number}\n * @readonly\n * @property {number} ALL - Log everything (most verbose)\n * @property {number} DEBUG - Log debug information\n * @property {number} INFO - Log informational messages\n * @property {number} WARN - Log warnings\n * @property {number} ERROR - Log errors\n * @property {number} CRITICAL - Log critical errors (least verbose)\n * @memberOf module:lib/engine/constants\n */\nexport enum LoggerLevels {\n ALL = 0,\n DEBUG = 1,\n INFO = 2,\n WARN = 3,\n ERROR = 4,\n CRITICAL = 5,\n}\n\n/**\n * @description Route direction constants.\n * @summary Defines the possible navigation directions in the application.\n * Used for controlling navigation flow and animation directions during route transitions.\n * These constants help maintain consistent navigation behavior throughout the app.\n * @enum {string}\n * @readonly\n * @property {string} BACK - Navigate back to the previous page\n * @property {string} FORWARD - Navigate forward to the next page\n * @property {string} ROOT - Navigate to the root/home page\n * @memberOf module:lib/engine/constants\n */\nexport enum RouteDirections {\n BACK = 'back',\n FORWARD = 'forward',\n ROOT = 'root',\n}\n\n/**\n * @description Component tag name constants.\n * @summary Defines the custom HTML tag names for specialized components used in the application.\n * These tag names are registered with Angular and used for component rendering and identification.\n * Each constant represents the selector for a specific custom component type.\n * @enum {string}\n * @readonly\n * @property {string} LIST_ITEM - Tag name for list item component\n * @property {string} LIST_INFINITE - Tag name for infinite scrolling list component\n * @property {string} LIST_PAGINATED - Tag name for paginated list component\n * @property {string} CRUD_FIELD - Tag name for CRUD form field component\n * @property {string} LAYOUT_COMPONENT - Tag name for layout container component\n * @memberOf module:lib/engine/constants\n */\nexport enum ComponentsTagNames {\n LIST_ITEM = 'ngx-decaf-list-item',\n LIST_INFINITE = 'ngx-decaf-list-infinite',\n LIST_PAGINATED = 'ngx-decaf-list-paginated',\n CRUD_FIELD = 'ngx-decaf-crud-field',\n LAYOUT_COMPONENT = 'ngx-decaf-layout',\n}\n\n/**\n * @description Base component property name constants.\n * @summary Defines the standard property names used by base components throughout the application.\n * These constants ensure consistent property naming across components and facilitate\n * property access, validation, and data binding. Used primarily for component input\n * properties and change detection.\n * @enum {string}\n * @readonly\n * @property {string} MODEL - Property name for the component's data model\n * @property {string} LOCALE - Property name for localization settings\n * @property {string} LOCALE_ROOT - Property name for the locale root identifier\n * @property {string} PK - Property name for primary key\n * @property {string} ITEMS - Property name for collection items\n * @property {string} ROUTE - Property name for routing information\n * @property {string} OPERATIONS - Property name for available operations\n * @property {string} UID - Property name for unique identifier\n * @property {string} TRANSLATABLE - Property name for translation flag\n * @property {string} MAPPER - Property name for property mapper\n * @property {string} INITIALIZED - Property name for initialization state\n * @property {string} COMPONENT_NAME - Property name for component identifier\n * @property {string} PARENT_FORM - Property name for parent component reference\n * @property {string} FORM_GROUP_COMPONENT_PROPS - Property name for form group component properties\n * @memberOf module:lib/engine/constants\n */\nexport enum BaseComponentProps {\n MODEL = 'model',\n LOCALE = 'locale',\n LOCALE_ROOT = 'locale_root',\n PK = 'pk',\n ITEMS = 'items',\n ROUTE = 'route',\n OPERATIONS = 'operations',\n UID = 'uid',\n TRANSLATABLE = 'translatable',\n MAPPER = 'mapper',\n INITIALIZED = 'initialized',\n COMPONENT_NAME = 'componentName',\n PARENT_FORM = 'parentForm',\n FORM_GROUP_COMPONENT_PROPS = 'componentProps',\n}\n\n/**\n * @description List component type constants.\n * @summary Defines the available types for list components, determining their\n * pagination and scrolling behavior. Used to configure list rendering strategies.\n * @enum {string}\n * @readonly\n * @property {string} INFINITE - Infinite scroll list type\n * @property {string} PAGINATED - Paginated list type with page navigation\n * @memberOf module:lib/engine/constants\n */\nexport enum ListComponentsTypes {\n INFINITE = 'infinite',\n PAGINATED = 'paginated',\n}\n\n/**\n * @description CSS class name constants.\n * @summary Contains predefined CSS class names used for consistent styling\n * across components. These constants help maintain a unified visual language\n * and make it easier to apply standard styles.\n * @typedef {Object} CssClasses\n * @property {string} BUTTONS_CONTAINER - CSS class for button container elements\n * @const CssClasses\n * @memberOf module:lib/engine/constants\n */\nexport const CssClasses = {\n BUTTONS_CONTAINER: 'buttons-container',\n};\n\n/**\n * @description Default options for reactive CRUD forms.\n * @summary Provides default configuration for form buttons in CRUD operations.\n * Includes default text labels for submit and clear buttons, which can be\n * overridden by individual form implementations.\n * @type {ICrudFormOptions}\n * @property {Object} buttons - Configuration for form action buttons\n * @property {Object} buttons.submit - Submit button configuration\n * @property {string} buttons.submit.text - Default text for submit button\n * @property {Object} buttons.clear - Clear button configuration\n * @property {string} buttons.clear.text - Default text for clear button\n * @const DefaultFormReactiveOptions\n * @memberOf module:lib/engine/constants\n */\nexport const DefaultFormReactiveOptions: ICrudFormOptions = {\n buttons: {\n submit: {\n text: 'Submit',\n },\n clear: {\n text: 'Clear',\n },\n },\n};\n\n/**\n * @description Default options for empty list state display.\n * @summary Provides default configuration for displaying empty state in list components\n * when no data is available. Includes default text for title and subtitle, icon name,\n * button text and visibility settings. These defaults can be overridden by individual\n * list component implementations to customize the empty state presentation.\n * @type {IListEmptyOptions}\n * @property {string} title - Default translation key for empty list title\n * @property {string} subtitle - Default translation key for empty list subtitle\n * @property {boolean} showButton - Whether to show action button in empty state\n * @property {string} icon - Default Ionic icon name for empty state\n * @property {string} buttonText - Default translation key for button text\n * @property {string} link - Default navigation link (empty string)\n * @const DefaultListEmptyOptions\n * @memberOf module:lib/engine/constants\n */\nexport const DefaultListEmptyOptions = {\n title: 'empty.title',\n subtitle: 'empty.subtitle',\n showButton: false,\n icon: 'folder-open-outline',\n buttonText: 'locale.empty.button',\n link: '',\n} as IListEmptyOptions;\n\nexport const DefaultModalOptions = {\n component: '',\n showBackdrop: true,\n backdropDismiss: false,\n animated: true,\n canDismiss: true,\n showBackdropTapClose: true,\n focusTrap: true,\n} as ModalOptions;\n\nexport const ActionRoles = {\n cancel: 'cancel',\n confirm: 'confirm',\n submit: 'submit',\n clear: 'clear',\n back: 'back',\n} as const;\n\nexport const WindowColorSchemes = {\n light: 'light',\n dark: 'dark',\n undefined: 'undefined',\n} as const;\n\nexport const ElementSizes = {\n xsmall: 'xsmall',\n small: 'small',\n medium: 'medium',\n default: 'default',\n large: 'large',\n xLarge: 'xlarge',\n '2xLarge': '2xlarge',\n auto: 'auto',\n expand: 'expand',\n block: 'block',\n} as const;\n\nexport const ElementPositions = {\n left: 'left',\n center: 'center',\n right: 'right',\n top: 'top',\n bottom: 'bottom',\n} as const;\n\nexport const LayoutGridGaps = {\n small: 'small',\n medium: 'medium',\n large: 'large',\n collapse: 'collapse',\n none: '',\n} as const;\n\nexport const ListItemPositions = {\n uid: 'uid',\n title: 'title',\n description: 'description',\n info: 'info',\n subinfo: 'subinfo',\n} as const;\n","/**\n * @module module:lib/engine/ValidatorFactory\n * @description Factory for generating Angular ValidatorFn from Decaf validation metadata.\n * @summary ValidatorFactory maps validation keys defined by the Decaf validation system\n * into Angular ValidatorFn instances. It supports type-based resolution and comparison\n * validators and provides helpers to create proxies for nested control validation.\n *\n * @link {@link ValidatorFactory}\n */\nimport { AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn } from '@angular/forms';\nimport {\n ComparisonValidationKeys,\n DEFAULT_PATTERNS,\n PathProxy,\n PathProxyEngine,\n Primitives,\n Validation,\n ValidationKeys,\n Validator,\n} from '@decaf-ts/decorator-validation';\nimport { FieldProperties, HTML5InputTypes, parseValueByType } from '@decaf-ts/ui-decorators';\nimport { AngularEngineKeys } from './constants';\nimport { KeyValue } from './types';\nimport { NgxRenderingEngine } from './NgxRenderingEngine';\n\n\ntype ComparisonValidationKey = typeof ComparisonValidationKeys[keyof typeof ComparisonValidationKeys];\n\n/**\n *\n * Resolves the correct validator key and its associated properties based on the input key and type.\n *\n * When the validation key is TYPE, it's necessary to resolve the actual validator based on the\n * field's type (e.g., 'password', 'email', 'url') instead of using the generic getValidator(\"type\") logic.\n * This allows directly invoking specific validators like getValidator('password'), ensuring the correct\n * behavior for type-based validation.\n *\n * @param key - The validation key (e.g., 'type', 'required', etc.).\n * @param value - The value that needs be provided to the validator.\n * @param type - The field's declared type.\n * @returns An object containing the resolved validator key and its corresponding props.\n */\nconst resolveValidatorKeyProps = (key: string, value: unknown, type: string): {\n validatorKey: string;\n props: Record<string, unknown>;\n} => {\n const patternValidators: Record<string, unknown> = {\n [ValidationKeys.PASSWORD]: DEFAULT_PATTERNS.PASSWORD.CHAR8_ONE_OF_EACH,\n [ValidationKeys.EMAIL]: DEFAULT_PATTERNS.EMAIL,\n [ValidationKeys.URL]: DEFAULT_PATTERNS.URL,\n };\n const isTypeBased = key === ValidationKeys.TYPE && Object.keys(patternValidators).includes(type);\n const validatorKey = isTypeBased ? type : key;\n if (key === ValidationKeys.TYPE && HTML5InputTypes.CHECKBOX && value !== type )\n value = type;\n const props: Record<string, unknown> = {\n // [validatorKey]: (!isTypeBased && key === 'type') ? parseType(type) : value,\n [validatorKey]: (!isTypeBased && validatorKey === ValidationKeys.TYPE) ? NgxRenderingEngine.get().translate(value as string, false) : value,\n // Email, Password, and URL are validated using the \"pattern\" key\n ...(isTypeBased && { [ValidationKeys.PATTERN] : patternValidators[type] }),\n };\n\n return { validatorKey, props };\n};\n\n\nexport class ValidatorFactory {\n static spawn(fieldProps: FieldProperties, key: string): ValidatorFn {\n if (!Validation.keys().includes(key))\n throw new Error('Unsupported custom validation');\n\n const validatorFn: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {\n const { type, customTypes, options } = fieldProps;\n let fieldType = (customTypes || type) as string;\n if ((fieldType === HTML5InputTypes.CHECKBOX || fieldType === Array.name) && Array.isArray(options))\n fieldType = Primitives.STRING;\n\n const { validatorKey, props } = resolveValidatorKeyProps(key, fieldProps[key as keyof FieldProperties], fieldType);\n const validator = Validation.get(validatorKey) as Validator;\n\n // parseValueByType does not support undefined values\n const value = typeof control.value !== 'undefined'\n ? parseValueByType(fieldType, control.value, fieldProps)\n : undefined;\n\n // Create a proxy to enable access to parent and child values\n let proxy: PathProxy<unknown> = ValidatorFactory.createProxy({} as AbstractControl);\n if (Object.values(ComparisonValidationKeys).includes(key as ComparisonValidationKey)) {\n const parent: FormGroup = control instanceof FormGroup ? control : (control as KeyValue)[AngularEngineKeys.PARENT];\n proxy = ValidatorFactory.createProxy(parent) as PathProxy<unknown>;\n }\n\n let errs: string | undefined;\n try {\n\n errs = validator.hasErrors(value, props, proxy);\n } catch (e: unknown) {\n errs = `${key} validator failed to validate: ${e}`;\n console.error(errs);\n }\n return errs ? { [validatorKey]: true } : null;\n };\n\n Object.defineProperty(validatorFn, 'name', {\n value: `${key}Validator`,\n });\n\n return validatorFn;\n }\n\n /**\n * @summary Creates a proxy wrapper for an Angular AbstractControl to assist with custom validation logic.\n * @description Returns a structured proxy object that simulates a hierarchical tree of form values.\n * Enables Validators handling method to access parent and child properties using consistent dot-notation in Angular forms.\n *\n * @param {AbstractControl} control - The control to wrap in a proxy.\n * @returns {PathProxy<unknown>} A proxy object exposing form values and enabling recursive parent access.\n */\n static createProxy(control: AbstractControl): PathProxy<unknown> {\n return PathProxyEngine.create(control, {\n getValue(target: AbstractControl, prop: string): unknown {\n if (target instanceof FormControl)\n return target.value;\n\n if (target instanceof FormGroup) {\n const control = target.controls[prop];\n return control instanceof FormControl ? control.value : control;\n }\n\n // const value = target[prop];\n // if (value instanceof FormControl)\n // return value.value;\n //\n // if (value instanceof FormGroup) {\n // const control = value.controls[prop];\n // return control instanceof FormControl ? control.value : control;\n // }\n\n return (target as KeyValue)?.[prop];\n },\n getParent: function(target: AbstractControl) {\n return target?.['_parent'];\n },\n ignoreUndefined: true,\n ignoreNull: true,\n });\n }\n}\n","/**\n * @module lib/for-angular-common.module\n * @description Core Angular module and providers for Decaf's for-angular package.\n * @summary Provides the shared Angular module, injection tokens and helper functions used\n * by the for-angular integration. This module wires up common imports (forms, translation)\n * and exposes helper providers such as DB adapter registration and logger utilities.\n * @link {@link ForAngularCommonModule}\n */\nimport {\n NgModule,\n ModuleWithProviders,\n InjectionToken,\n Provider,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { TranslateModule, TranslatePipe } from '@ngx-translate/core';\nimport { Logger, Logging } from '@decaf-ts/logging';\nimport { I18nToken } from './engine/interfaces';\nimport { getOnWindow, setOnWindow } from './utils/helpers';\nimport {\n DecafRepository,\n FunctionLike,\n DecafRepositoryAdapter,\n KeyValue,\n} from './engine/types';\nimport { Model, Primitives } from '@decaf-ts/decorator-validation';\nimport { Repository } from '@decaf-ts/core';\nimport { Constructor, uses } from '@decaf-ts/decoration';\n\nexport const DB_ADAPTER_PROVIDER = 'DB_ADAPTER_PROVIDER';\n\n/**\n * @description Injection token for registering the database adapter provider.\n * @summary Used to inject the database adapter instance that implements DecafRepositoryAdapter.\n * This token allows the framework to locate and use the application's specific database implementation.\n * @const {InjectionToken<DecafRepositoryAdapter>}\n * @memberOf module:lib/for-angular-common.module\n */\nexport const DB_ADAPTER_PROVIDER_TOKEN =\n new InjectionToken<DecafRepositoryAdapter>('DB_ADAPTER_PROVIDER_TOKEN');\n/**\n * @description Injection token for the root path of locale translation files.\n * @summary Used to configure the base path where i18n translation files are located.\n * This allows the translation loader to locate JSON files for different languages.\n * @const {InjectionToken<string>}\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // Typical usage when providing the token\n * { provide: LOCALE_ROOT_TOKEN, useValue: './assets/i18n/' }\n */\nexport const LOCALE_ROOT_TOKEN = new InjectionToken<string>(\n 'LOCALE_ROOT_TOKEN'\n);\n\n/* Generic token for injecting on class constructors */\n/**\n * @description Generic injection token for providing arbitrary values to constructors.\n * @summary Used to inject classes, strings, or any other value into component or service constructors.\n * This is a flexible token that can be used to provide any type of dependency when more specific\n * tokens are not appropriate. The actual type and purpose of the injected value is determined by\n * the provider configuration.\n * @const {InjectionToken<unknown>}\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // Inject a string value\n * { provide: CPTKN, useValue: 'some-config-value' }\n *\n * // Inject a class\n * { provide: CPTKN, useClass: MyService }\n *\n * // Inject any arbitrary value\n * { provide: CPTKN, useValue: { key: 'value', data: [1, 2, 3] } }\n */\nexport const CPTKN = new InjectionToken<unknown>('CPTKN', {\n providedIn: 'root',\n factory: () => '',\n});\n\n/**\n * @description Injection token for i18n resource configuration.\n * @summary Used to provide configuration for internationalization resources, including\n * translation file locations and supported languages. This token configures how the\n * application loads and manages translation resources.\n * @const {InjectionToken<I18nToken>}\n * @memberOf module:lib/for-angular-common.module\n */\nexport const I18N_CONFIG_TOKEN = new InjectionToken<I18nToken>(\n 'I18N_CONFIG_TOKEN'\n);\n\n/**\n * @description Provides an array of component types for dynamic rendering.\n * @summary Helper function to package component constructors for registration with the\n * rendering engine. This function accepts component classes and returns them as an array\n * suitable for use with the CPTKN injection token.\n * @param {...Constructor[]} components - Component constructor classes to register\n * @return {Constructor} Array of component constructors\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // Register multiple custom components\n * providers: [\n * { provide: CPTKN, useValue: provideDynamicComponents(MyComponent, AnotherComponent) }\n * ]\n */\nexport function provideDynamicComponents(\n ...components: Constructor<unknown>[]\n): Constructor<unknown>[] {\n return components;\n}\n\n/**\n * @description Retrieves the repository instance for a given model.\n * @summary Creates or retrieves a DecafRepository instance for the specified model. This function\n * resolves the model by name or class, locates the registered database adapter, and returns\n * a fully initialized repository instance for performing CRUD operations.\n * @param {Model | string} model - The model class or model name string\n * @return {DecafRepository<Model>} Repository instance for the model\n * @throws {InternalError} If model is not found or not registered with @model decorator\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // Get repository by model class\n * const userRepo = getModelAndRepository(User);\n *\n * // Get repository by model name\n * const productRepo = getModelAndRepository('Product');\n *\n * // Use repository for queries\n * const users = await userRepo.findAll();\n */\nexport function getModelAndRepository(\n model: Model | string\n): { repository: DecafRepository<Model>, model: Model, pk: string } | undefined {\n try {\n const modelName = (\n typeof model === Primitives.STRING\n ? model\n : (model as Model).constructor.name\n ) as string;\n const constructor = Model.get(\n (modelName.charAt(0).toUpperCase() + modelName.slice(1)) as string\n );\n if (!constructor) return undefined;\n const dbAdapterFlavour = getOnWindow(DB_ADAPTER_PROVIDER) || undefined;\n if (dbAdapterFlavour)\n uses(dbAdapterFlavour as string)(constructor);\n const repository = Repository.forModel(constructor);\n model = new constructor() as Model;\n const pk = Model.pk(repository.class as Constructor<Model>);\n if (!pk)\n return undefined;\n return { repository, model, pk };\n } catch (error: unknown) {\n getLogger(getModelAndRepository).warn((error as Error)?.message || (error as string));\n return undefined;\n }\n}\n\n/**\n * @description Provides a database adapter for dependency injection.\n * @summary Creates an Angular provider that registers a database adapter instance. This function\n * instantiates the adapter class, registers its flavour globally, and returns a provider object\n * for use in Angular's dependency injection system.\n * @template DbAdapter - The database adapter class type extending {flavour: string}\n * @param {Constructor<DbAdapter>} adapterClass - Database adapter constructor class\n * @param {KeyValue} [options={}] - Configuration options passed to adapter constructor\n * @param {string} [flavour] - Optional flavour override; uses adapter.flavour if not provided\n * @return {Provider} Angular provider object for DB_ADAPTER_PROVIDER_TOKEN\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // Register a SQLite adapter\n * providers: [\n * provideDbAdapter(SqliteAdapter, { database: 'myapp.db' }, 'sqlite')\n * ]\n *\n * // Register with default flavour from adapter\n * providers: [\n * provideDbAdapter(PostgresAdapter, { host: 'localhost', port: 5432 })\n * ]\n */\nexport function provideDbAdapter<DbAdapter extends { flavour: string }>(\n clazz: Constructor<DbAdapter>,\n options: KeyValue = {},\n flavour?: string\n): Provider {\n const adapter = new clazz(options);\n if (flavour) flavour = adapter.flavour;\n getLogger(provideDbAdapter).info(`Using ${adapter.constructor.name} ${flavour} as Db Provider`);\n setOnWindow(DB_ADAPTER_PROVIDER, flavour);\n return {\n provide: DB_ADAPTER_PROVIDER_TOKEN,\n useValue: adapter,\n };\n}\n\n/**\n * @const {Logger}\n * @private\n * @description Base logger instance for the for-angular module.\n * @memberOf module:lib/for-angular-common.module\n */\nconst log = Logging.for('for-angular');\n\n/**\n * @description Retrieves a logger instance for the given context.\n * @summary Creates or retrieves a namespaced logger instance using the Decaf logging system.\n * The logger is automatically namespaced under \"for-angular\" and can be further scoped\n * to a specific instance, function, or string identifier.\n * @param {string | FunctionLike | unknown} instance - The instance, function, or string to scope the logger to\n * @return {Logger} Logger instance for the specified context\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // Get logger for a class\n * const logger = getLogger(MyComponent);\n * logger.info('Component initialized');\n *\n * // Get logger with string identifier\n * const serviceLogger = getLogger('UserService');\n * serviceLogger.error('Operation failed', error);\n */\nexport function getLogger(instance: string | FunctionLike | unknown): Logger {\n return log.for(instance as string | FunctionLike);\n}\n\nconst CommonModules = [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n TranslateModule,\n TranslatePipe,\n];\n\n/**\n * @description Main Angular module for the Decaf framework.\n * @summary The ForAngularCommonModule provides the core functionality for integrating Decaf with Angular applications.\n * It imports and exports common Angular and Ionic components and modules needed for Decaf applications,\n * including form handling, translation support, and Ionic UI components. This module can be imported\n * directly or via the forRoot() method for proper initialization in the application's root module.\n * @class ForAngularCommonModule\n * @memberOf module:lib/for-angular-common.module\n * @example\n * // In your app module:\n * @NgModule({\n * imports: [\n * ForAngularCommonModule.forRoot(),\n * // other imports\n * ],\n * // ...\n * })\n * export class AppModule {}\n */\n@NgModule({\n imports: CommonModules,\n declarations: [],\n exports: CommonModules,\n schemas: [],\n providers: [],\n})\nexport class ForAngularCommonModule {\n /**\n * @description Creates a module with providers for root module import.\n * @summary This static method provides the proper way to import the ForAngularCommonModule in the application's\n * root module. It returns a ModuleWithProviders object that includes the ForAngularCommonModule itself.\n * Using forRoot() ensures that the module and its providers are properly initialized and only\n * instantiated once in the application.\n * @return {ModuleWithProviders<ForAngularCommonModule>} The module with its providers\n * @memberOf ForAngularCommonModule\n * @static\n * @example\n * // Import in root module\n * @NgModule({\n * imports: [ForAngularCommonModule.forRoot()],\n * // ...\n * })\n * export class AppModule {}\n */\n static forRoot(): ModuleWithProviders<ForAngularCommonModule> {\n return {\n ngModule: ForAngularCommonModule,\n };\n }\n}\n","/**\n * @module module:lib/helpers/utils\n * @description General helper utilities used across the library.\n * @summary Exposes small, reusable utility functions for window/document access, date handling,\n * string manipulation, simple mapping helpers and environment helpers used by UI components\n * and services. This module's functions include `getWindow`, `getWindowDocument`, `formatDate`,\n * `isValidDate`, `itemMapper`, `dataMapper`, and event helpers like `windowEventEmitter`.\n *\n * Do not document individual exports here — functions are documented inline.\n * @link {@link getWindow}\n */\n\nimport { isDevMode } from '@angular/core';\nimport { InjectableRegistryImp, InjectablesRegistry } from '@decaf-ts/injectable-decorators';\nimport { Primitives } from '@decaf-ts/decorator-validation';\nimport { KeyValue, StringOrBoolean, } from '../engine/types';\nimport { FunctionLike } from '../engine/types';\nimport { getLogger } from '../for-angular-common.module';\n\nlet injectableRegistry: InjectablesRegistry;\n\n/**\n * @description Retrieves the singleton instance of the injectables registry\n * @summary This function implements the singleton pattern for the InjectablesRegistry.\n * It returns the existing registry instance if one exists, or creates a new instance\n * if none exists. The registry is used to store and retrieve injectable dependencies\n * throughout the application.\n *\n * @return {InjectablesRegistry} The singleton injectables registry instance\n *\n * @function getInjectablesRegistry\n * @memberOf module:for-angular\n */\nexport function getInjectablesRegistry(): InjectablesRegistry {\n if (!injectableRegistry)\n injectableRegistry = new InjectableRegistryImp();\n return injectableRegistry;\n}\n\n/**\n * @description Determines if the application is running in development mode\n * @summary This function checks whether the application is currently running in a development\n * environment. It uses Angular's isDevMode() function and also checks the window context\n * and hostname against the provided context parameter. This is useful for enabling\n * development-specific features or logging.\n *\n * @param {string} [context='localhost'] - The context string to check against the current environment\n * @return {boolean} True if the application is running in development mode, false otherwise\n *\n * @function isDevelopmentMode\n * @memberOf module:for-angular\n */\nexport function isDevelopmentMode(context: string = 'localhost'): boolean {\n if (!context)\n return isDevMode();\n const win = getWindow();\n return (\n isDevMode() ||\n win?.['env']?.['CONTEXT'].toLowerCase() !== context.toLowerCase() ||\n win?.['location']?.hostname?.includes(context)\n );\n}\n\n/**\n * @description Dispatches a custom event to the document window\n * @summary This function creates and dispatches a custom event to the browser window.\n * It's useful for cross-component communication or for triggering application-wide events.\n * The function allows specifying the event name, detail data, and additional event properties.\n *\n * @param {string} name - The name of the custom event to dispatch\n * @param {unknown} detail - The data to include in the event's detail property\n * @param {object} [props] - Optional additional properties for the custom event\n * @return {void}\n *\n * @function windowEventEmitter\n * @memberOf module:for-angular\n */\nexport function windowEventEmitter(\n name: string,\n detail: unknown,\n props?: object\n): void {\n const data = Object.assign(\n {\n bubbles: true,\n composed: true,\n cancelable: false,\n detail: detail,\n },\n props || {}\n );\n (getWindow() as Window).dispatchEvent(new CustomEvent(name, data));\n}\n/**\n * @description Retrieves a property from the window's document object\n * @summary This function provides a safe way to access properties on the window's document object.\n * It uses the getWindowDocument function to get a reference to the document, then accesses\n * the specified property. This is useful for browser environment interactions that need\n * to access document properties.\n *\n * @param {string} key - The name of the property to retrieve from the document object\n * @return {any} The value of the specified property, or undefined if the document or property doesn't exist\n *\n * @function getOnWindowDocument\n * @memberOf module:for-angular\n */\nexport function getOnWindowDocument(key: string): Document | undefined {\n const doc = getWindowDocument() as Document;\n return doc instanceof Document ?\n (doc as KeyValue)?.[key] || undefined : undefined;\n}\n\n/**\n * @description Retrieves the document object from the window\n * @summary This function provides a safe way to access the document object from the window.\n * It uses the getOnWindow function to retrieve the 'document' property from the window object.\n * This is useful for browser environment interactions that need access to the document.\n *\n * @return {Document | undefined} The window's document object, or undefined if it doesn't exist\n *\n * @function getWindowDocument\n * @memberOf module:for-angular\n */\nexport function getWindowDocument(): Document | undefined {\n return getOnWindow('document') as Document;\n}\n\n/**\n * @description Retrieves a property from the window object\n * @summary This function provides a safe way to access properties on the window object.\n * It uses the getWindow function to get a reference to the window, then accesses\n * the specified property. This is useful for browser environment interactions that need\n * to access window properties or APIs.\n *\n * @param {string} key - The name of the property to retrieve from the window object\n * @return {unknown | undefined} The value of the specified property, or undefined if the window or property doesn't exist\n *\n * @function getOnWindow\n * @memberOf module:for-angular\n */\nexport function getOnWindow(key: string): unknown | undefined {\n return getWindow()?.[key];\n}\n\n/**\n * @description Sets a property on the window object\n * @summary This function provides a way to set properties on the window object.\n * It uses the getWindow function to get a reference to the window, then sets\n * the specified property to the provided value. This is useful for storing\n * global data or functions that need to be accessible across the application.\n *\n * @param {string} key - The name of the property to set on the window object\n * @param {any} value - The value to assign to the property\n * @return {void}\n *\n * @function setOnWindow\n * @memberOf module:for-angular\n */\nexport function setOnWindow(key: string, value: unknown): void {\n getWindow()[key] = value;\n}\n\n/**\n * @description Retrieves the global window object\n * @summary This function provides a safe way to access the global window object.\n * It uses globalThis to ensure compatibility across different JavaScript environments.\n * This is the core function used by other window-related utility functions to\n * access the window object.\n *\n * @return {Window} The global window object\n *\n * @function getWindow\n * @memberOf module:for-angular\n */\nexport function getWindow(): Window & KeyValue {\n return (globalThis as KeyValue)?.['window'] as Window & KeyValue;\n}\n\n/**\n * @description Retrieves the width of the browser window\n * @summary This function provides a convenient way to get the current width of the browser window.\n * It uses the getOnWindow function to access the 'innerWidth' property of the window object.\n * This is useful for responsive design implementations and viewport-based calculations.\n *\n * @return {number | undefined} The current width of the browser window in pixels\n *\n * @function getWindowWidth\n * @memberOf module:for-angular\n */\nexport function getWindowWidth(): number {\n return getOnWindow('innerWidth') as number || 0;\n}\n\n/**\n * @description Checks if a value is not undefined\n * @summary This utility function determines whether a given value is not undefined.\n * It's a simple wrapper that makes code more readable when checking for defined values.\n * The function is particularly useful for checking StringOrBoolean properties that might be undefined.\n *\n * @param {StringOrBoolean | undefined} prop - The property to check\n * @return {boolean} True if the property is not undefined, false otherwise\n *\n * @function isNotUndefined\n * @memberOf module:for-angular\n */\nexport function isNotUndefined(prop: StringOrBoolean | undefined): boolean {\n return (prop !== undefined) as boolean;\n}\n\n/**\n * @description Generates a locale string from a class name or instance\n * @summary This utility function converts a class name or instance into a locale string\n * that can be used for internationalization purposes. It handles different input types\n * (string, function, or object) and applies formatting rules to generate a consistent\n * locale identifier. For short names (less than 3 parts), it reverses the dot-separated\n * string. For longer names, it uses the last part as a prefix and joins the rest with\n * underscores.\n *\n * @param {string|FunctionLike|object} instance - The input to generate the locale from (class name, constructor, or instance)\n * @param {string} [suffix] - Optional string to append to the instance name before processing\n * @return {string} A formatted locale string derived from the input\n *\n * @function getLocaleFromClassName\n * @memberOf module:for-angular\n */\nexport function getLocaleFromClassName(\n instance: string | FunctionLike | KeyValue,\n suffix?: string\n): string {\n if (typeof instance !== Primitives.STRING)\n instance = (instance as FunctionLike).name || (instance as object)?.constructor?.name;\n\n let name: string | string[] = instance as string;\n\n if (suffix)\n name = `${instance}${suffix.charAt(0).toUpperCase() + suffix.slice(1)}`;\n\n name = name.replace(/_|-/g, '').replace(/(?:^\\w|[A-Z]|\\b\\w)/g, (word: string, index: number) => {\n if (index > 1) word = '.' + word;\n return word.toLowerCase();\n }).split('.');\n\n if (name.length < 3)\n return name.reverse().join('.');\n\n const preffix = name[name.length - 1];\n name.pop();\n name = name.join('_');\n return `${preffix}.${name}`;\n}\n\n\n\n/**\n * @description Retrieves the current locale language\n * @summary This utility function gets the current locale language based on the user's browser settings.\n * It provides a consistent way to access the user's language preference throughout the application.\n * The function returns the browser's navigator.language value, defaulting to 'en' if not available.\n *\n * @return {string} The current locale language (e.g., 'en', 'fr')\n *\n * @function getLocaleLanguage\n * @memberOf module:for-angular\n */\nexport function getLocaleLanguage(): string {\n const win = getWindow();\n return (win as Window).navigator.language || \"en\";\n // return win?.[WINDOW_KEYS.LANGUAGE_SELECTED] || (win.navigator.language || '').split('-')[0] || \"en\";\n}\n\n\n\n/**\n * @description Generates a random string or number of specified length\n * @summary This utility function creates a random string of a specified length.\n * It can generate either alphanumeric strings (including uppercase and lowercase letters)\n * or numeric-only strings. This is useful for creating random IDs, temporary passwords,\n * or other random identifiers throughout the application.\n *\n * @param {number} [length=8] - The length of the random value to generate\n * @param {boolean} [onlyNumbers=false] - Whether to generate only numeric characters\n * @return {string} A randomly generated string of the specified length and character set\n *\n * @function generateRandomValue\n * @memberOf module:for-angular\n */\nexport function generateRandomValue(length: number = 8, onlyNumbers: boolean = false): string {\n const chars = onlyNumbers\n ? '0123456789'\n : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++)\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n\n return result;\n}\n\n\n/**\n * @description Converts a string representation of a boolean or a boolean value to a boolean type.\n * @summary This utility function handles conversion of string-based boolean values ('true', 'false')\n * to actual boolean types. It performs case-insensitive string comparison and returns the\n * corresponding boolean value. This is particularly useful when parsing configuration values,\n * URL parameters, or form inputs that may come as strings but need to be used as booleans.\n *\n * @param {'true' | 'false' | boolean} prop - The value to convert. Can be the string 'true', 'false', or a boolean\n * @returns {boolean} The boolean representation of the input value. Returns true if the input is the string 'true' or boolean true, false otherwise\n *\n * @function stringToBoolean\n * @memberOf module:lib/helpers/utils\n */\nexport function stringToBoolean(prop: 'true' | 'false' | boolean): boolean {\n if (typeof prop === 'string')\n prop = prop.toLowerCase() === 'true' ? true : false;\n return prop;\n}\n\n\n/**\n * @description Checks if a value is a valid Date object.\n * @summary This validation function determines whether a given value represents a valid date.\n * It handles multiple input types including Date objects, timestamp numbers, and date strings.\n * For string inputs, it supports ISO 8601 format (YYYY-MM-DD) with or without time components.\n * The function performs comprehensive validation including regex pattern matching and Date\n * object creation to ensure the date is not only parseable but also represents a real date.\n *\n * @param {string | Date | number} date - The value to check. Can be a Date object, a timestamp number, or a date string\n * @returns {boolean} Returns true if the value is a valid Date object (not NaN), otherwise false\n *\n * @function isValidDate\n * @memberOf module:lib/helpers/utils\n */\nexport function isValidDate(date: string | Date | number): boolean {\n try {\n return (date instanceof Date && !isNaN(date as unknown as number)) || (() => {\n const testRegex = new RegExp(/^\\d{4}-\\d{2}-\\d{2}$/).test(date as string)\n if (typeof date !== Primitives.STRING || !(date as string)?.includes('T') && !testRegex)\n return false;\n\n date = (date as string).split('T')[0];\n if (!new RegExp(/^\\d{4}-\\d{2}-\\d{2}$/).test(date))\n return false;\n\n return !!(new Date(date));\n })();\n } catch(error: unknown) {\n getLogger(isValidDate).error(error as Error | string);\n return false;\n }\n}\n\n/**\n * @description Formats a date into a localized string representation.\n * @summary This function converts a date value into a formatted string according to a specified\n * or system locale. It accepts multiple input formats (Date objects, timestamps, or date strings)\n * and returns a consistently formatted date string in DD/MM/YYYY format. If the input date is\n * invalid, the function returns the original input as a string. The function automatically\n * uses the system locale if none is provided and handles string format conversions by replacing\n * forward slashes with hyphens for proper Date parsing.\n *\n * @param {string | Date | number} date - The date to format. Can be a Date object, a timestamp number, or a date string\n * @param {string} [locale] - The locale to use for formatting. If not provided, the system's locale will be used\n * @returns {Date | string} A formatted date string in the format DD/MM/YYYY according to the specified locale,\n * or the original input as a string if the date is invalid\n *\n * @function formatDate\n * @memberOf module:lib/helpers/utils\n */\nexport function formatDate(date: string | Date | number, locale?: string | undefined): Date | string {\n\n if (!locale)\n locale = getLocaleLanguage();\n\n if (typeof date === 'string' || typeof date === 'number')\n date = new Date(typeof date === 'string' ? date.replace(/\\//g, '-') : date);\n\n if (!isValidDate(date))\n return `${date}` as string;\n const r = date.toLocaleString(locale, {\n year: \"numeric\",\n day: \"2-digit\",\n month: '2-digit'\n });\n\n\n return r;\n}\n\n/**\n * @description Attempts to parse a date string, Date object, or number into a valid Date object.\n * @summary This function provides robust date parsing functionality that handles the specific\n * format \"DD/MM/YYYY HH:MM:SS:MS\". It first validates the input date, and if already valid,\n * returns it as-is. For string inputs, it parses the date and time components separately,\n * extracts numeric values, and constructs a new Date object. The function includes validation\n * to ensure the resulting Date object is valid and logs a warning if parsing fails.\n * Returns null for invalid or unsupported date formats.\n *\n * @param {string | Date | number} date - The date to parse. Can be a Date object, a timestamp number,\n * or a date string in the format \"DD/MM/YYYY HH:MM:SS:MS\"\n * @returns {Date | null} A valid Date object if parsing is successful, or null if the date is invalid\n * or doesn't match the expected format\n *\n * @function parseToValidDate\n * @memberOf module:lib/helpers/utils\n */\nexport function parseToValidDate(date: string | Date | number): Date | null {\n if (isValidDate(date))\n return date as Date;\n\n if (!`${date}`.includes('/'))\n return null;\n\n const [dateString, timeString] = (date as string).split(' ');\n const [day, month, year] = dateString.split('/').map(Number);\n const [hours, minutes, seconds, milliseconds] = timeString.split(':').map(Number);\n date = new Date(year, month - 1, day, hours, minutes, seconds, milliseconds);\n\n if (!isValidDate(date)) {\n console.warn('parseToValidDate - Invalid date format', date);\n return null;\n }\n\n return date;\n}\n\n\n/**\n * @description Maps an item object using a provided mapper object and optional additional properties.\n * @summary This function transforms a source object into a new object based on mapping rules defined\n * in the mapper parameter. It supports dot notation for nested property access (e.g., 'user.name.first')\n * and handles various data types including strings and complex objects. For date values, it automatically\n * formats them using the formatDate function. The function also allows merging additional properties\n * into the result. When a mapped value is null or undefined, it uses the original mapper value as\n * a fallback.\n *\n * @param {KeyValue} item - The source object to be mapped\n * @param {KeyValue} mapper - An object that defines the mapping rules. Keys represent the new property names,\n * and values represent the path to the corresponding values in the source object\n * @param {KeyValue} [props] - Optional additional properties to be included in the mapped object\n * @returns {KeyValue} A new object with properties mapped according to the mapper object and including any additional properties\n *\n * @function itemMapper\n * @memberOf module:lib/helpers/utils\n */\nexport function itemMapper(item: KeyValue, mapper: KeyValue, props?: KeyValue): KeyValue {\n return Object.entries(mapper).reduce((accum: KeyValue, [key, value]) => {\n const arrayValue = (value as string).split('.');\n if (!value) {\n accum[key] = value;\n } else {\n if (arrayValue.length === 1) {\n accum[key] = item?.[value as string] || (value !== key ? value : \"\");\n } else {\n let val;\n\n for (const _value of arrayValue)\n val = !val\n ? item[_value]\n : (typeof val === 'string' ? JSON.parse(val) : val)[_value];\n\n if (isValidDate(new Date(val))) val = `${formatDate(val)}`;\n\n accum[key] = val === null || val === undefined ? value : val;\n }\n }\n return Object.assign({}, props || {}, accum);\n }, {});\n}\n\n/**\n * @description Maps an array of data objects using a provided mapper object.\n * @summary This function transforms an array of objects by applying mapping rules to each item\n * using the itemMapper function. It processes each element in the data array and creates\n * new mapped objects based on the mapper configuration. The function includes validation\n * to ensure meaningful data: if a mapped item contains only null/undefined values, it\n * preserves the original item instead. This prevents data loss during transformation.\n * Returns an empty array if the input data is null, undefined, or empty.\n *\n * @template T - The type of the resulting mapped items\n * @param {T[]} data - The array of data objects to be mapped\n * @param {KeyValue} mapper - An object that defines the mapping rules\n * @param {KeyValue} [props] - Additional properties to be included in the mapped items\n * @returns {T[]} The array of mapped items. If an item in the original array does not have any non-null values after mapping,\n * the original item is returned instead\n *\n * @function dataMapper\n * @memberOf module:lib/helpers/utils\n */\nexport function dataMapper<T>(data: T[], mapper: KeyValue, props?: KeyValue): T[] {\n if (!data || !data.length) return [];\n return data.reduce((accum: T[], curr) => {\n const item = itemMapper(curr as KeyValue, mapper, props) as T;\n const hasValues =\n [...new Set(Object.values(item as T[]))].filter((value) => value).length >\n 0;\n accum.push(hasValues ? item : curr);\n return accum;\n }, []);\n}\n\n/**\n * @description Removes focus from the currently active DOM element\n * @summary This utility function blurs the currently focused element in the document,\n * effectively removing focus traps that might prevent proper navigation or keyboard\n * interaction. It safely accesses the document's activeElement and calls blur() if\n * an element is currently focused. This is useful for accessibility and user experience\n * improvements, particularly when closing modals or dialogs.\n *\n * @return {void}\n *\n * @function removeFocusTrap\n * @memberOf module:for-angular\n */\nexport function removeFocusTrap(): void {\n const doc = getWindowDocument();\n if (doc?.activeElement)\n (doc.activeElement as HTMLElement)?.blur();\n}\n\n/**\n * @description Cleans and normalizes whitespace in a string value\n * @summary This utility function trims leading and trailing whitespace from a string\n * and replaces multiple consecutive whitespace characters with a single space.\n * Optionally converts the result to lowercase for consistent text processing.\n * This is useful for normalizing user input, search terms, or data sanitization.\n *\n * @param {string} value - The string value to clean and normalize\n * @param {boolean} [lowercase=false] - Whether to convert the result to lowercase\n * @return {string} The cleaned and normalized string\n *\n * @function cleanSpaces\n * @memberOf module:for-angular\n */\nexport function cleanSpaces(value: string = \"\", lowercase: boolean = false): string {\n value = `${value}`.trim().replace(/\\s+/g, ' ');\n return lowercase ? value.toLowerCase() : value;\n}\n\n\n/**\n * @description Determines if the user's system is currently in dark mode\n * @summary This function checks the user's color scheme preference using the CSS media query\n * '(prefers-color-scheme: dark)'. It returns a boolean indicating whether the system is\n * currently set to dark mode. This is useful for implementing theme-aware functionality\n * and adjusting UI elements based on the user's preferred color scheme.\n *\n * @return {Promise<boolean>} True if the system is in dark mode, false otherwise\n *\n * @function isDarkMode\n * @memberOf module:for-angular\n */\nexport async function isDarkMode(): Promise<boolean> {\n const {matches} = getWindow().matchMedia('(prefers-color-scheme: dark)');\n return matches;\n}\n\n/**\n * @description Filters out strings containing or not containing a specific substring from an array or space-separated string.\n * @summary This function removes or retains strings based on whether they include the specified substring.\n * If the input is a single string, it is split into an array using spaces as delimiters before filtering.\n *\n * @param {string | string[]} original - The input string or array of strings to filter.\n * @param {string} value - The substring to filter by.\n * @param {boolean} [contain=true] - Determines the filtering behavior. If true, retains strings containing the substring; otherwise, removes them.\n * @returns {string} A string that contains or excludes the specified substring based on the `contain` parameter.\n *\n * @function filterString\n * @memberOf module:lib/helpers/utils\n */\nexport function filterString(original: string | string[], value: string, contain: boolean = true): string {\n if (typeof original === Primitives.STRING)\n original = (original as string).split(' ');\n return ((original as string[]).filter(str =>\n contain ?\n str.includes(value) : !str.includes(value)\n ) || []).join(' ');\n}\n","/**\n * @module lib/engine/NgxFormService\n * @description Utilities to create and manage Angular forms in Decaf components.\n * @summary The NgxFormService exposes helpers to build FormGroup/FormArray instances\n * from component metadata or UI model definitions, register forms in a registry,\n * validate and extract form data, and create controls with appropriate validators.\n */\nimport { escapeHtml, FieldProperties, HTML5CheckTypes, HTML5InputTypes, IPagedComponentProperties, parseToNumber, UIModelMetadata } from '@decaf-ts/ui-decorators';\nimport { FieldUpdateMode, FormParent, FormParentGroup, KeyValue } from '../engine/types';\nimport { IComponentConfig, IFormComponentProperties } from '../engine/interfaces';\nimport { AbstractControl, FormArray, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';\nimport { isValidDate, ModelKeys, parseDate, Primitives, Validation } from '@decaf-ts/decorator-validation';\nimport { ValidatorFactory } from '../engine/ValidatorFactory';\nimport { cleanSpaces } from '../utils/helpers';\nimport { OperationKeys } from '@decaf-ts/db-decorators';\nimport { BaseComponentProps } from '../engine/constants';\n\n\n/**\n * @description Service for managing Angular forms and form controls.\n * @summary The NgxFormService provides utility methods for creating, managing, and validating Angular forms and form controls. It includes functionality for registering forms, adding controls, validating fields, and handling form data.\n *\n * @class\n * @param {WeakMap<AbstractControl, FieldProperties>} controls - A WeakMap to store control properties.\n * @param {Map<string, FormGroup>} formRegistry - A Map to store registered forms.\n *\n * @example\n * // Creating a form from components\n * const components = [\n * { inputs: { name: 'username', type: 'text', required: true } },\n * { inputs: { name: 'password', type: 'password', minLength: 8 } }\n * ];\n * const form = NgxFormService.createFormFromComponents('loginForm', components, true);\n *\n * // Validating fields\n * NgxFormService.validateFields(form);\n *\n * // Getting form data\n * const formData = NgxFormService.getFormData(form);\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant AF as Angular Forms\n * C->>NFS: createFormFromComponents()\n * NFS->>AF: new FormGroup()\n * NFS->>NFS: addFormControl()\n * NFS->>AF: addControl()\n * NFS-->>C: Return FormGroup\n * C->>NFS: validateFields()\n * NFS->>AF: markAsTouched(), markAsDirty(), updateValueAndValidity()\n * C->>NFS: getFormData()\n * NFS->>AF: Get control values\n * NFS-->>C: Return form data\n */\nexport class NgxFormService {\n /**\n * @description WeakMap that stores control properties for form controls.\n * @summary A WeakMap that associates AbstractControl instances with their corresponding FieldProperties.\n * This allows the service to track metadata for form controls without creating memory leaks.\n * @type {WeakMap<AbstractControl, FieldProperties>}\n * @private\n * @static\n */\n private static controls: WeakMap<AbstractControl, FieldProperties> = new WeakMap<AbstractControl, FieldProperties>();\n\n /**\n * @description Registry of form groups indexed by their unique identifiers.\n * @summary A Map that stores FormGroup instances with their unique string identifiers.\n * This allows global access to registered forms throughout the application.\n * @type {Map<string, FormGroup>}\n * @private\n * @static\n */\n private static formRegistry: Map<string, FormParent> = new Map<string, FormParent>();\n\n /**\n * @description Creates a new form group or form array with the specified identifier.\n * @summary Generates a FormGroup or FormArray based on the provided parameters. If formArray is true,\n * creates a FormArray; otherwise creates a FormGroup. The form can optionally be registered in the\n * global form registry for later access throughout the application. If a form with the given id\n * already exists in the registry, it returns the existing form.\n * @param {string} id - Unique identifier for the form\n * @param {boolean} [formArray=false] - Whether to create a FormArray instead of a FormGroup\n * @param {boolean} [registry=true] - Whether to register the form in the global registry\n * @return {FormGroup | FormArray} The created or existing form instance\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant FR as Form Registry\n * participant AF as Angular Forms\n * C->>NFS: createForm(id, formArray, registry)\n * NFS->>FR: Check if form exists\n * alt Form exists\n * FR-->>NFS: Return existing form\n * else Form doesn't exist\n * alt formArray is true\n * NFS->>AF: new FormArray([])\n * else\n * NFS->>AF: new FormGroup({})\n * end\n * alt registry is true\n * NFS->>FR: addRegistry(id, form)\n * end\n * end\n * NFS-->>C: Return FormGroup | FormArray\n * @static\n */\n static createForm(id: string, formArray = false, registry: boolean = true): FormGroup | FormArray {\n const form = this.formRegistry.get(id) ?? (formArray ? new FormArray([]) : new FormGroup({}));\n if (!this.formRegistry.has(id) && registry)\n this.addRegistry(id, form as FormArray | FormGroup);\n return form as FormArray | FormGroup;\n }\n\n\n /**\n * @description Adds a form to the registry.\n * @summary Registers a FormGroup or FormArray with a unique identifier for global access throughout\n * the application. This allows forms to be retrieved and managed centrally. Throws an error if\n * the identifier is already in use to prevent conflicts.\n * @param {string} formId - The unique identifier for the form\n * @param {FormParent} formGroup - The FormGroup or FormArray to be registered\n * @return {void}\n * @throws {Error} If a FormGroup with the given id is already registered\n * @static\n */\n static addRegistry(formId: string, formGroup: FormParent): void {\n if (this.formRegistry.has(formId))\n throw new Error(`A FormGroup with id '${formId}' is already registered.`);\n this.formRegistry.set(formId, formGroup);\n }\n\n /**\n * @description Retrieves a form from the registry by its identifier.\n * @summary Gets a FormGroup or FormArray from the registry using its unique identifier.\n * Returns undefined if the form is not found in the registry. This method provides\n * safe access to registered forms without throwing errors.\n * @param {string} [id] - The unique identifier of the form to retrieve\n * @return {FormParent | undefined} The FormGroup or FormArray if found, undefined otherwise\n * @static\n */\n static getOnRegistry(id?: string): FormParent | undefined {\n return this.formRegistry.get(id as string);\n }\n\n /**\n * @description Removes a form from the registry.\n * @summary Deletes a FormGroup or FormArray from the registry using its unique identifier.\n * This cleans up the registry and allows the identifier to be reused. The form itself\n * is not destroyed, only removed from the central registry.\n * @param {string} formId - The unique identifier of the form to be removed\n * @return {void}\n * @static\n */\n static removeRegistry(formId: string): void {\n this.formRegistry.delete(formId);\n }\n\n /**\n * @description Resolves the parent group and control name from a path.\n * @summary Traverses the form group structure to find the parent group and control name for a given path.\n * Handles complex nested structures including arrays and sub-groups. Creates missing intermediate\n * groups as needed and properly configures FormArray controls for multiple value scenarios.\n * @param {FormGroup} formGroup - The root FormGroup to traverse\n * @param {string} path - The dot-separated path to the control (e.g., 'user.address.street')\n * @param {IFormComponentProperties} componentProps - Properties defining the component configuration\n * @param {KeyValue} parentProps - Properties from the parent component for context\n * @return {FormParentGroup} A tuple containing the parent FormGroup and the control name\n * @private\n * @mermaid\n * sequenceDiagram\n * participant NFS as NgxFormService\n * participant FG as FormGroup\n * participant FA as FormArray\n * NFS->>NFS: Split path into parts\n * loop For each path part\n * alt Control doesn't exist\n * alt isMultiple and part is childOf\n * NFS->>FA: new FormArray([new FormGroup({})])\n * else\n * NFS->>FG: new FormGroup({})\n * end\n * NFS->>FG: addControl(part, newControl)\n * end\n * NFS->>NFS: Navigate to next level\n * end\n * NFS-->>NFS: Return [parentGroup, controlName]\n * @static\n */\n private static resolveParentGroup(\n formGroup: FormGroup,\n path: string,\n componentProps: IFormComponentProperties,\n parentProps: Partial<IFormComponentProperties>\n ): FormParentGroup {\n const isMultiple = parentProps?.multiple || parentProps?.type === Array.name || false;\n const parts = path.split('.');\n const controlName = parts.pop() as string;\n\n const {childOf} = componentProps\n let currentGroup = formGroup;\n function setArrayComponentProps(formGroupArray: KeyValue) {\n const props = formGroupArray?.[BaseComponentProps.FORM_GROUP_COMPONENT_PROPS] || {};\n if(!props[ModelKeys.MODEL][controlName])\n props[ModelKeys.MODEL] = Object.assign({}, props[ModelKeys.MODEL], {[controlName]: {...componentProps}});\n }\n\n for (const part of parts) {\n if (!currentGroup.get(part)) {\n const partFormGroup = (isMultiple && (part === childOf|| childOf?.endsWith(`${part}`))) ? new FormArray([new FormGroup({})]) : new FormGroup({});\n const pk = componentProps?.pk || parentProps?.pk || '';\n (partFormGroup as KeyValue)[BaseComponentProps.FORM_GROUP_COMPONENT_PROPS] = {\n childOf: childOf || '',\n isMultiple: isMultiple,\n required: parentProps?.required ?? false,\n name: part,\n pk,\n [ModelKeys.MODEL]: {},\n } as Partial<FieldProperties> & {model: KeyValue};\n\n if(currentGroup instanceof FormArray) {\n (currentGroup as FormArray).push(partFormGroup);\n } else {\n for(const control of Object.values(partFormGroup.controls)) {\n if(control instanceof FormControl)\n this.register(control as AbstractControl, componentProps);\n }\n\n if(partFormGroup instanceof AbstractControl)\n this.register(partFormGroup as AbstractControl, componentProps);\n currentGroup.addControl(part, partFormGroup);\n }\n }\n if(childOf && currentGroup instanceof FormArray)\n setArrayComponentProps(currentGroup);\n currentGroup = currentGroup.get(part) as FormGroup;\n }\n return [currentGroup, controlName];\n }\n\n /**\n * @description Retrieves component properties from a FormGroup or FormArray.\n * @summary Extracts component properties stored in the form group metadata. If a FormGroup is provided\n * and groupArrayName is specified, it will look for the FormArray within the form structure.\n * @param {FormGroup | FormArray} formGroup - The form group or form array to extract properties from\n * @param {string} [key] - Optional key to retrieve a specific property\n * @param {string} [groupArrayName] - Optional name of the group array if formGroup is not a FormArray\n * @return {Partial<FieldProperties>} The component properties or a specific property if key is provided\n * @static\n */\n static getComponentPropsFromGroupArray(formGroup: FormGroup | FormArray, key?: string, groupArrayName?: string | undefined): Partial<FieldProperties> {\n if(!(formGroup instanceof FormArray) && typeof groupArrayName === Primitives.STRING)\n formGroup = formGroup.root.get(groupArrayName as string) as FormArray || {};\n const props = (formGroup as KeyValue)?.[BaseComponentProps.FORM_GROUP_COMPONENT_PROPS] || {};\n return (!key ? props : props?.[key]) || {};\n }\n\n /**\n * @description Adds a new group to a parent FormArray.\n * @summary Creates and adds a new FormGroup to the specified parent FormArray based on the\n * component properties stored in the parent's metadata. This is used for dynamic form arrays\n * where new groups need to be added at runtime. Clones the control at the specified index\n * to maintain the same structure and validators.\n * @param {FormParent} parentForm - The FormArray or FormGroup containing the parent FormArray\n * @param {number} [index] - The index position to clone from; defaults to last index if length > 0, otherwise 0\n * @return {FormArray} The parent FormArray after adding the new group\n * @static\n */\n static addGroupToParent(parentForm: FormParent, index?: number): FormArray {\n if(parentForm instanceof FormGroup)\n parentForm = parentForm.parent as FormArray;\n index = index || (parentForm.length === 0 ? 0 : parentForm.length - 1);\n parentForm.push(this.cloneFormControl(parentForm.at(index)));\n return parentForm;\n }\n\n /**\n * @description Retrieves a FormGroup from a parent FormArray at the specified index.\n * @summary Gets a FormGroup from the specified parent FormArray. If the group doesn't exist\n * at the given index, it will create a new one using addGroupToParent.\n * @param {FormParent} formGroup - The root form group containing the parent FormArray\n * @param {string} parentName - The name of the parent FormArray to retrieve the group from\n * @param {number} [index=1] - The index of the group to retrieve\n * @return {FormGroup} The FormGroup at the specified index\n * @static\n */\n static getGroupFromParent(formGroup: FormParent, parentName: string, index: number = 1): FormGroup {\n const childGroup = ((formGroup.get(parentName) || formGroup) as FormArray).at(index);\n if(childGroup instanceof FormGroup)\n return childGroup;\n return this.addGroupToParent(formGroup, index).at(index) as FormGroup;\n }\n\n /**\n * @description Clones a form control with its validators.\n * @summary Creates a deep copy of a FormControl, FormGroup, or FormArray, preserving\n * validators but resetting values and state. This is useful for creating new instances\n * of form controls with the same validation rules, particularly in dynamic FormArrays\n * where new groups need to be added with identical structure.\n * @param {AbstractControl} control - The control to clone (FormControl, FormGroup, or FormArray)\n * @return {AbstractControl} A new instance of the control with the same validators\n * @throws {Error} If the control type is not supported\n * @static\n */\n static cloneFormControl(control: AbstractControl): AbstractControl {\n const syncValidators = (control.validator ? [control.validator] : []).filter(fn => {\n // if(lastIndex > 0)\n // if(fn !== Validators.required)\n // return fn;\n return fn;\n });\n const asyncValidators = control.asyncValidator ?? null;\n const validators = {\n validators: syncValidators,\n asyncValidators\n }\n if (control instanceof FormControl) {\n control = new FormControl(\"\", validators);\n // control.markAsPristine();\n // control.markAsUntouched();\n // control.setErrors(null);\n // control.updateValueAndValidity();\n return control;\n }\n\n if (control instanceof FormGroup) {\n const groupControls: Record<string, AbstractControl> = {};\n for (const key in control.controls) {\n groupControls[key] = this.cloneFormControl(control.controls[key]);\n }\n return new FormGroup(groupControls, validators);\n }\n\n if (control instanceof FormArray) {\n const arrayControls = control.controls.map(child => this.cloneFormControl(child));\n return new FormArray(arrayControls, validators);\n }\n\n throw new Error('Unsupported control type');\n }\n\n /**\n * @description Checks if a value is unique within a FormArray group.\n * @summary Validates that the primary key value in a FormGroup is unique among all groups\n * in the parent FormArray. The uniqueness check behavior differs based on the operation type.\n * For both CREATE and UPDATE operations, it checks that no other group in the array has the same\n * primary key value.\n * @param {FormGroup} formGroup - The FormGroup to check for uniqueness\n * @param {OperationKeys} [operation=OperationKeys.CREATE] - The type of operation being performed\n * @param {number} [index] - The index of the current group within the FormArray\n * @return {boolean} True if the value is unique, false otherwise\n * @static\n */\n static isUniqueOnGroup(formGroup: FormGroup, operation: OperationKeys = OperationKeys.CREATE, index?: number): boolean {\n const formArray = formGroup.parent as FormArray;\n if(index === undefined || index === null)\n index = formArray.length - 1;\n const pk = this.getComponentPropsFromGroupArray(formArray, BaseComponentProps.PK as string) as string;\n const controlName = Object.keys(formGroup.controls)[0];\n\n if(controlName !== pk || !pk)\n return true;\n const controlValue = cleanSpaces(`${formGroup.get(pk)?.value}`, true);\n if(operation === OperationKeys.CREATE) {\n return !formArray.controls.some((group, i) => {\n const value = cleanSpaces(`${group.get(pk)?.value}`, true);\n return i !== index && value === controlValue;\n });\n }\n\n return !formArray.controls.some((group, i) => {\n const value = cleanSpaces(`${group.get(pk)?.value}`, true);\n return i !== index && value === controlValue;\n });\n }\n\n /**\n * @description Enables all controls within a FormGroup or FormArray.\n * @summary Recursively enables all form controls within the provided FormGroup or FormArray.\n * This is useful for making all controls interactive after they have been disabled.\n * @param {FormArray | FormGroup} formGroup - The FormGroup or FormArray to enable all controls for\n * @return {void}\n * @static\n */\n static enableAllGroupControls(formGroup: FormArray | FormGroup): void {\n Object.keys(formGroup.controls).forEach(key => {\n const control = formGroup.get(key);\n if (control instanceof FormArray) {\n control.controls.forEach(child => {\n if (child instanceof FormGroup) {\n child.enable({ emitEvent: false });\n child.updateValueAndValidity({ emitEvent: true });\n }\n });\n }\n });\n }\n\n /**\n * @description Adds a form control to a form group based on component properties.\n * @summary Creates and configures a FormControl within the specified FormGroup using the provided\n * component properties. Handles nested paths, multiple controls (FormArrays), and control registration.\n * This method supports complex form structures with nested groups and arrays. It also manages\n * page-based forms and FormArray indexing.\n * @param {FormParent} formGroup - The form group or form array to add the control to\n * @param {IFormComponentProperties} componentProps - The component properties defining the control configuration\n * @param {Partial<IFormComponentProperties>} [parentProps={}] - Properties from the parent component for context\n * @param {number} [index=0] - The index for multiple controls in FormArrays\n * @return {FormParent} The updated form parent (FormGroup or FormArray)\n * @private\n * @static\n */\n private static addFormControl(formGroup: FormParent, componentProps: IFormComponentProperties, parentProps: Partial<IFormComponentProperties> = {}, index: number = 0): FormParent {\n\n const isMultiple = parentProps?.['multiple'] || parentProps?.['type'] === 'Array' || false;\n const { name, childOf } = componentProps;\n if(isMultiple)\n componentProps['pk'] = componentProps['pk'] || parentProps?.['pk'] || '';\n const fullPath = childOf ? isMultiple ? `${childOf}.${index}.${name}` : `${childOf}.${name}` : name;\n const [parentGroup, controlName] = this.resolveParentGroup(formGroup as FormGroup, fullPath, componentProps, parentProps);\n\n if (!parentGroup.get(controlName)) {\n const control = NgxFormService.fromProps(\n componentProps,\n componentProps.updateMode || 'change',\n );\n NgxFormService.register(control, componentProps);\n if (parentGroup instanceof FormGroup) {\n parentGroup.addControl(controlName, control);\n }\n if(parentGroup instanceof FormArray) {\n const root = parentGroup.controls[(componentProps as KeyValue)?.['page'] - 1] as FormGroup;\n if(root) {\n root.addControl(controlName, control);\n } else {\n parentGroup.push({[controlName]: control});\n }\n }\n }\n let rootGroup = parentGroup;\n if(rootGroup instanceof FormArray)\n rootGroup = (parentGroup as FormArray).controls[(componentProps as KeyValue)?.['page'] - 1] as FormParent;\n // if(childOf?.includes(\".\"))\n // rootGroup = (rootGroup as FormGroup)?.parent as FormArray\n\n // componentProps['formGroup'] = root as FormGroup;\n componentProps['formGroup'] = rootGroup as FormGroup;\n componentProps['formControl'] = parentGroup.get(controlName) as FormControl;\n // componentProps['multiple'] = isMultiple;\n\n return parentGroup as FormParent;\n }\n\n /**\n * @description Retrieves a control from a registered form.\n * @summary Finds and returns an AbstractControl from a registered form using the form id and optional path.\n * This method provides centralized access to form controls across the application by leveraging\n * the form registry system.\n * @param {string} formId - The unique identifier of the form in the registry\n * @param {string} [path] - The optional dot-separated path to a specific control within the form\n * @return {AbstractControl} The requested AbstractControl (FormGroup, FormArray, or FormControl)\n * @throws {Error} If the form is not found in the registry or the control is not found in the form\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant FR as Form Registry\n * C->>NFS: getControlFromForm(formId, path?)\n * NFS->>FR: Get form by formId\n * alt Form not found\n * FR-->>NFS: null\n * NFS-->>C: Throw Error\n * else Form found\n * FR-->>NFS: Return form\n * alt path provided\n * NFS->>NFS: form.get(path)\n * alt Control not found\n * NFS-->>C: Throw Error\n * else\n * NFS-->>C: Return control\n * end\n * else\n * NFS-->>C: Return form\n * end\n * end\n * @static\n */\n static getControlFromForm(formId: string, path?: string): AbstractControl {\n const form = this.formRegistry.get(formId);\n if (!form)\n throw new Error(`Form with id '${formId}' not found in the registry.`);\n\n if (!path)\n return form;\n\n const control = form.get(path);\n if (!control)\n throw new Error(`Control with path '${path}' not found in form '${formId}'.`);\n return control;\n }\n\n\n /**\n * @description Creates a form from UI model metadata children.\n * @summary Generates a FormGroup from an array of UIModelMetadata objects, extracting component\n * properties and creating appropriate form controls. This method is specifically designed to work\n * with the UI decorator system and provides automatic form generation from metadata.\n * @param {string} id - Unique identifier for the form\n * @param {boolean} [registry=false] - Whether to register the created form in the global registry\n * @param {UIModelMetadata[]} [children] - Array of UI model metadata objects to create controls from\n * @return {FormGroup} The created FormGroup with controls for each child metadata\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant AF as Angular Forms\n * C->>NFS: createFormFromChildren(id, registry, children)\n * NFS->>AF: new FormGroup({})\n * loop For each child metadata\n * NFS->>NFS: addFormControl(form, child.props)\n * NFS->>AF: Create and add FormControl\n * end\n * alt registry is true\n * NFS->>NFS: addRegistry(id, form)\n * end\n * NFS-->>C: Return FormGroup\n * @static\n */\n static createFormFromChildren(id: string, registry: boolean = false, children?: UIModelMetadata[],): FormGroup {\n const form = new FormGroup({});\n if(children?.length)\n children.forEach(child => {\n this.addFormControl(form, child.props as IFormComponentProperties);\n });\n if (registry)\n this.addRegistry(id, form);\n return form;\n }\n\n /**\n * @description Creates a form from component configurations.\n * @summary Generates a FormGroup based on an array of component configurations and optionally registers it.\n * This method processes component input configurations to create appropriate form controls with\n * validation and initial values.\n * @param {string} id - The unique identifier for the form\n * @param {IComponentConfig[]} components - An array of component configurations defining the form structure\n * @param {boolean} [registry=false] - Whether to register the created form in the global registry\n * @return {FormGroup} The created FormGroup with controls for each component configuration\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant AF as Angular Forms\n * C->>NFS: createFormFromComponents(id, components, registry)\n * NFS->>AF: new FormGroup({})\n * loop For each component config\n * NFS->>NFS: addFormControl(form, component.inputs)\n * NFS->>AF: Create and add FormControl\n * end\n * alt registry is true\n * NFS->>NFS: addRegistry(id, form)\n * end\n * NFS-->>C: Return FormGroup\n * @static\n */\n static createFormFromComponents(id: string, components: IComponentConfig[], registry: boolean = false): FormGroup {\n const form = new FormGroup({});\n components.forEach(component => {\n this.addFormControl(form, component.inputs);\n });\n\n if (registry)\n this.addRegistry(id, form);\n\n return form;\n }\n\n /**\n * @description Adds a control to a form based on component properties.\n * @summary Creates and adds a form control to a form (existing or new) based on the provided component properties.\n * Handles multi-page forms by managing FormArray structures and proper indexing. This method supports\n * complex form scenarios including nested controls and page-based form organization. It automatically\n * creates FormArrays for forms with multiple pages and manages page indexing.\n * @param {string} id - The unique identifier of the form\n * @param {ComponentProperties} props - The properties of the component to create the control from\n * @param {props} [parentProps] - Optional parent properties for context and configuration\n * @return {FormParent} The form or created control (FormGroup or FormArray)\n * @throws {Error} If page property is required but not provided or is invalid\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant F as Form\n * C->>NFS: addControlFromProps(id, props, parentProps?)\n * NFS->>NFS: createForm(id, formArray, true)\n * alt Multi-page form (parentProps.pages > 0)\n * NFS->>NFS: Calculate page index\n * alt Group doesn't exist at index\n * NFS->>F: Create new FormGroup at index\n * end\n * NFS->>NFS: Set form to page FormGroup\n * end\n * alt props has path\n * NFS->>NFS: addFormControl(form, props, parentProps)\n * end\n * NFS-->>C: Return form/control\n * @static\n */\n static addControlFromProps(id: string, props: IFormComponentProperties, parentProps?: IFormComponentProperties): FormParent {\n\n const componentPages = (typeof props?.pages === Primitives.NUMBER ?\n props?.pages : (props?.pages as IPagedComponentProperties[])?.length) as number;\n const parentPages = (typeof parentProps?.pages === Primitives.NUMBER ?\n parentProps?.pages : (parentProps?.pages as IPagedComponentProperties[])?.length) as number;\n\n const isFormArray = (componentPages && componentPages >= 1 || props.multiple === true);\n let form = this.createForm(id, isFormArray, true);\n\n if(parentPages && parentPages > 0) {\n const childOf = props.childOf || \"\";\n const parentChildOf = parentProps?.childOf || \"\";\n const index = props.page || parentProps?.page;\n // dont check page in nested childs with same childOf\n if((!(typeof index === 'number') || index === 0) && (childOf.length && childOf !== parentChildOf))\n throw Error(`Property 'page' is required and greather than 0 on ${props.name}`);\n // if(index > formLength) {\n // if((form as KeyValue)?.['lastIndex'] && index === (form as KeyValue)['lastIndex']['page']) {\n // index = (form as KeyValue)['lastIndex']['index'];\n // } else {\n // (form as KeyValue)['lastIndex'] = {\n // page: index,\n // index: formLength + 1\n // };\n // index = formLength + 1;\n\n // }\n // }\n let group = (form as FormArray).controls[(index as number) - 1];\n if(!group) {\n group = new FormGroup({});\n (form as FormArray).insert(index as number, group);\n }\n form = group as FormGroup;\n }\n if(props.path)\n form = this.addFormControl(form, props, parentProps);\n return form;\n }\n\n /**\n * @description Retrieves form data from a FormGroup.\n * @summary Extracts and processes the data from a FormGroup, handling different input types and nested form groups.\n * Performs type conversion for various HTML5 input types, validates nested controls, and manages\n * multiple control scenarios. Automatically enables all group controls after data extraction.\n * @param {FormGroup} formGroup - The FormGroup to extract data from\n * @return {Record<string, unknown>} An object containing the processed form data with proper type conversions\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant FG as FormGroup\n * participant FC as FormControl\n * C->>NFS: getFormData(formGroup)\n * loop For each control in formGroup\n * alt Control is not FormControl\n * NFS->>NFS: Recursive getFormData(control)\n * alt parentProps.multiple and !isValid\n * NFS->>NFS: reset(control)\n * end\n * else Control is FormControl\n * NFS->>FC: Get control value\n * NFS->>NFS: Apply type conversion based on props.type\n * alt HTML5CheckTypes\n * NFS->>NFS: Keep boolean value\n * else NUMBER type\n * NFS->>NFS: parseToNumber(value)\n * else DATE/DATETIME types\n * NFS->>NFS: new Date(value)\n * else Other types\n * NFS->>NFS: escapeHtml(value)\n * end\n * end\n * end\n * NFS->>NFS: enableAllGroupControls(formGroup)\n * NFS-->>C: Return processed data object\n * @static\n */\n static getFormData(formGroup: FormGroup): Record<string, unknown> {\n const data: Record<string, unknown> = {};\n for (const key in formGroup.controls) {\n const control = formGroup.controls[key];\n const parentProps = NgxFormService.getPropsFromControl(formGroup as FormGroup | FormArray);\n if (!(control instanceof FormControl)) {\n if(control.disabled)\n continue;\n const value = NgxFormService.getFormData(control as FormGroup);\n const isValid = control.valid;\n if(parentProps.multiple) {\n if(isValid) {\n data[key] = value;\n } else {\n this.reset(control as FormControl);\n }\n continue;\n }\n data[key] = value;\n continue;\n }\n\n const props = NgxFormService.getPropsFromControl(control as FormControl | FormArray);\n let value = control.value;\n if (!HTML5CheckTypes.includes(props['type'])) {\n switch (props['type']) {\n case HTML5InputTypes.NUMBER:\n value = parseToNumber(value);\n break;\n case HTML5InputTypes.DATE:\n case HTML5InputTypes.DATETIME_LOCAL:\n value = new Date(value);\n break;\n default:\n value = escapeHtml(value);\n }\n } else {\n if(props['type'] === HTML5InputTypes.CHECKBOX && Array.isArray(value))\n value = control.value;\n }\n data[key] = value;\n }\n NgxFormService.enableAllGroupControls(formGroup as FormGroup);\n return data;\n }\n\n /**\n * @description Validates fields in a form control or form group.\n * @summary Recursively validates all fields in a form control or form group, marking them as touched and dirty.\n * Performs comprehensive validation including uniqueness checks for primary keys in FormArray scenarios.\n * This method ensures all validation rules are applied and form state is properly updated.\n * @param {AbstractControl} control - The control or form group to validate\n * @param {string} [pk] - Optional primary key field name for uniqueness validation\n * @param {string} [path] - The path to the control within the form for error reporting\n * @return {boolean} True if all fields are valid, false otherwise\n * @throws {Error} If no control is found at the specified path or if the control type is unknown\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant FC as FormControl\n * participant FG as FormGroup\n * participant FA as FormArray\n * C->>NFS: validateFields(control, pk?, path?)\n * alt Control is FormControl\n * NFS->>FC: markAsTouched()\n * NFS->>FC: markAsDirty()\n * NFS->>FC: updateValueAndValidity()\n * alt Is in FormArray group\n * NFS->>NFS: Check uniqueness in group\n * alt Not unique\n * NFS->>FC: setErrors({notUnique: true})\n * end\n * end\n * NFS-->>C: Return control.valid\n * else Control is FormGroup\n * loop For each child control\n * NFS->>NFS: Recursive validateFields(child)\n * end\n * NFS-->>C: Return allValid\n * else Control is FormArray\n * loop For each array control\n * NFS->>NFS: Recursive validateFields(child)\n * end\n * NFS-->>C: Return allValid\n * else Unknown control type\n * NFS-->>C: Throw Error\n * end\n * @static\n */\n static validateFields(control: AbstractControl, pk?: string, path?: string): boolean {\n control = path ? control.get(path) as AbstractControl : control;\n if (!control)\n throw new Error(`No control found at path: ${path || 'root'}.`);\n\n const isAllowed = [FormArray, FormGroup, FormControl].some(type => control instanceof type);\n if (!isAllowed)\n throw new Error(`Unknown control type at: ${path || 'root'}`);\n\n control.markAsTouched();\n control.markAsDirty();\n control.updateValueAndValidity({emitEvent: true });\n\n if (control instanceof FormGroup) {\n Object.values(control.controls).forEach(childControl => {\n this.validateFields(childControl);\n });\n }\n\n if (control instanceof FormArray) {\n const totalGroups = control.length;\n const hasValid = control.controls.some(control => control.valid);\n const parentProps = (control as KeyValue)[BaseComponentProps.FORM_GROUP_COMPONENT_PROPS] || {};\n const childControl = control.at(0);\n if(totalGroups === 1) {\n const parent = childControl.parent as FormGroup;\n if(!parentProps.required) {\n parent.setErrors(null);\n parent.updateValueAndValidity({ emitEvent: true });\n childControl.disable();\n } else {\n this.validateFields(childControl);\n }\n }\n else if(totalGroups > 1 && hasValid) {\n for (let i = control.length - 1; i >= 0; i--) {\n const childControl = control.at(i);\n // disable no valid groups on array\n if (!childControl.valid) {\n const parent = childControl.parent as FormGroup;\n parent.setErrors(null);\n parent.updateValueAndValidity({ emitEvent: true });\n childControl.disable();\n } else {\n this.validateFields(childControl);\n }\n }\n } else {\n Object.values(control.controls).forEach(childControl => {\n this.validateFields(childControl);\n });\n }\n }\n\n // function getControlName(control: AbstractControl): string | null {\n // const group = control.parent as FormGroup;\n // if (!group)\n // return null;\n // return Object.keys(group.controls).find(name => control === group.get(name)) || null;\n // }\n\n return control?.disabled ? true : control.valid;\n }\n\n /**\n * @description Generates validators from component properties.\n * @summary Creates an array of ValidatorFn based on the supported validation keys in the component properties.\n * Maps each validation property to its corresponding Angular validator function using the ValidatorFactory.\n * Only processes properties that are recognized as validation keys by the Validation utility.\n * @param {KeyValue} props - The component properties containing validation rules\n * @return {ValidatorFn[]} An array of validator functions\n * @private\n * @static\n */\n private static validatorsFromProps(props: KeyValue): ValidatorFn[] {\n const supportedValidationKeys = Validation.keys();\n return Object.keys(props)\n .filter((k: string) => supportedValidationKeys.includes(k))\n .map((k: string) => {\n return ValidatorFactory.spawn(props as FieldProperties, k);\n });\n }\n\n /**\n * @description Creates a FormControl from component properties.\n * @summary Generates a FormControl with validators and initial configuration based on the provided\n * component properties. Handles different input types, sets initial values, and configures\n * validation rules and update modes.\n * @param {FieldProperties} props - The component properties defining the control configuration\n * @param {FieldUpdateMode} [updateMode='change'] - The update mode for the control ('change', 'blur', 'submit')\n * @return {FormControl} The created FormControl with proper configuration and validators\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant VF as ValidatorFactory\n * participant AF as Angular Forms\n * C->>NFS: fromProps(props, updateMode?)\n * NFS->>NFS: validatorsFromProps(props)\n * NFS->>VF: Create validators from props\n * VF-->>NFS: Return validator array\n * NFS->>NFS: Compose validators\n * alt props.value exists and not checkbox\n * alt props.type is DATE\n * NFS->>NFS: Validate date format\n * end\n * NFS->>NFS: Set initial value\n * end\n * NFS->>AF: new FormControl(config)\n * AF-->>NFS: Return FormControl\n * NFS-->>C: Return configured FormControl\n * @static\n */\n static fromProps(props: FieldProperties, updateMode: FieldUpdateMode = 'change'): FormControl {\n const validators = this.validatorsFromProps(props);\n const composed = validators.length ? Validators.compose(validators) : null;\n return new FormControl(\n {\n value:\n props.value\n ? props.type === HTML5InputTypes.CHECKBOX ?\n Array.isArray(props.value) ? props.value : undefined\n : props.type === HTML5InputTypes.DATE\n ? !isValidDate(parseDate(props.format as string, props.value as string))\n ? undefined : props.value :\n (props.value as unknown) : undefined,\n disabled: props.disabled,\n },\n {\n validators: composed,\n updateOn: updateMode,\n },\n );\n }\n\n /**\n * @description Retrieves properties from a FormControl, FormArray, or FormGroup.\n * @summary Gets the FieldProperties associated with a form control from the internal WeakMap.\n * This method provides access to the original component properties that were used to create\n * the control, enabling validation, rendering, and behavior configuration.\n * @param {FormControl | FormArray | FormGroup} control - The form control to get properties for\n * @return {FieldProperties} The properties associated with the control, or empty object if not found\n * @static\n */\n static getPropsFromControl(control: FormControl | FormArray | FormGroup): FieldProperties {\n return this.controls.get(control) || {} as FieldProperties;\n }\n\n /**\n * @description Finds a parent element with a specific tag in the DOM tree.\n * @summary Traverses up the DOM tree to find the nearest parent element with the specified tag name.\n * This is useful for finding container elements or specific parent components in the DOM hierarchy.\n * The search is case-insensitive for tag name matching.\n * @param {HTMLElement} el - The starting element to traverse from\n * @param {string} tag - The tag name to search for (case-insensitive)\n * @return {HTMLElement} The found parent element with the specified tag\n * @throws {Error} If no parent with the specified tag is found in the DOM tree\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant NFS as NgxFormService\n * participant DOM as DOM Tree\n * C->>NFS: getParentEl(element, tagName)\n * loop Traverse up DOM tree\n * NFS->>DOM: Get parentElement\n * DOM-->>NFS: Return parent or null\n * alt Parent exists and tag matches\n * NFS-->>C: Return parent element\n * else Parent is null\n * NFS-->>C: Throw Error\n * end\n * end\n * @static\n */\n static getParentEl(el: HTMLElement, tag: string): HTMLElement {\n let parent: HTMLElement | null;\n while ((parent = el.parentElement) !== null) {\n if (parent.tagName.toLowerCase() === tag.toLowerCase()) {\n return parent;\n }\n el = parent;\n }\n throw new Error(\n `No parent with the tag ${tag} was found for provided element`,\n );\n }\n\n /**\n * @description Registers a control with its properties in the internal WeakMap.\n * @summary Associates a form control with its component properties for later retrieval.\n * This enables the service to maintain metadata about controls without creating memory leaks,\n * as WeakMap automatically cleans up references when controls are garbage collected.\n * @param {AbstractControl} control - The control to register (FormControl, FormGroup, or FormArray)\n * @param {FieldProperties} props - The properties to associate with the control\n * @return {void}\n * @static\n */\n static register(control: AbstractControl, props: FieldProperties): void {\n this.controls.set(control, props);\n }\n\n /**\n * @description Unregisters a control from the internal WeakMap.\n * @summary Removes a control and its associated properties from the internal WeakMap.\n * This cleans up the metadata tracking for the control and frees up memory. Returns\n * true if the control was found and removed, false if it was not in the registry.\n * @param {AbstractControl} control - The control to unregister (FormControl, FormGroup, or FormArray)\n * @return {boolean} True if the control was successfully unregistered, false otherwise\n * @static\n */\n static unregister(control: AbstractControl): boolean {\n return this.controls.delete(control);\n }\n\n /**\n * @description Resets a form group or form control.\n * @summary Recursively resets all controls in a form group or a single form control, clearing values,\n * errors, and marking them as pristine and untouched. For FormControls, it sets the value to empty\n * string (except for checkbox types) and clears validation errors. For FormGroups, it recursively\n * resets all child controls.\n * @param {FormGroup | FormControl} formGroup - The form group or form control to reset\n * @return {void}\n * @static\n */\n static reset(formGroup: FormGroup | FormControl): void {\n if(formGroup instanceof FormControl) {\n const control = formGroup as FormControl;\n const { type } = NgxFormService.getPropsFromControl(control);\n if (!HTML5CheckTypes.includes(type))\n control.setValue(\"\");\n control.markAsPristine();\n control.markAsUntouched();\n control.setErrors(null);\n control.updateValueAndValidity();\n } else {\n for (const key in formGroup.controls) {\n const control = formGroup.controls[key];\n NgxFormService.reset(control as FormControl);\n continue;\n }\n }\n }\n}\n","import { faker } from '@faker-js/faker';\nimport { parseToNumber } from '@decaf-ts/ui-decorators';\nimport { Model, Primitives } from '@decaf-ts/decorator-validation';\nimport { InternalError } from '@decaf-ts/db-decorators';\nimport { Metadata, uses } from '@decaf-ts/decoration';\nimport { Repository } from '@decaf-ts/core';\nimport { DB_ADAPTER_PROVIDER } from '../for-angular-common.module';\nimport { DecafRepository, KeyValue, FunctionLike } from '../engine/types';\nimport { formatDate, getOnWindow } from './helpers';\n\nexport class DecafFakerRepository<T extends Model> {\n protected data: T[] = [];\n\n protected _repository: DecafRepository<Model> | undefined = undefined;\n\n constructor(\n protected model: string | Model,\n protected limit: number = 36\n ) {}\n\n protected get repository(): DecafRepository<Model> {\n if (!this._repository) {\n const modelName =\n typeof this.model === 'string'\n ? this.model\n : (this.model as Model).constructor.name;\n const constructor = Model.get(modelName);\n if (!constructor)\n throw new InternalError(\n `Cannot find model ${modelName}. was it registered with @model?`\n );\n try {\n this.model = new constructor();\n const dbAdapterFlavour = getOnWindow(DB_ADAPTER_PROVIDER) || undefined;\n if (dbAdapterFlavour) uses(dbAdapterFlavour as string)(constructor);\n this._repository = Repository.forModel(constructor);\n } catch (error: unknown) {\n throw new InternalError((error as Error)?.message || (error as string));\n }\n }\n return this._repository;\n }\n\n public async initialize(): Promise<void> {\n if (!this._repository) this._repository = this.repository;\n }\n\n async generateData<T extends Model>(values?: KeyValue, key?: string, keyType?: string): Promise<T[]> {\n const limit = values ? Object.values(values || {}).length : this.limit;\n if (!key)\n key = Model.pk(this.repository.class) as string;\n if (!keyType)\n keyType = Metadata.type(this.repository.class, key).name.toLowerCase();\n\n const props = Object.keys(this.model as KeyValue).filter((k) => {\n if (keyType === Primitives.STRING)\n return !['updatedBy', 'createdAt', 'createdBy', 'updatedAt'].includes(k);\n return ![key, 'updatedBy', 'createdAt', 'createdBy', 'updatedAt'].includes(k);\n });\n const dataProps: Record<string, FunctionLike> = {};\n for (const prop of props) {\n const type = Metadata.type(this.repository.class, prop);\n switch (type.name.toLowerCase()) {\n case 'string':\n dataProps[prop] = () =>\n `${faker.lorem.word()} ${key === prop ? ' - ' + faker.number.int({ min: 1, max: 200 }) : ''}`;\n break;\n case 'step':\n dataProps[prop] = () => faker.lorem.word();\n break;\n case 'email':\n dataProps[prop] = () => faker.internet.email();\n break;\n case 'number':\n dataProps[prop] = () => faker.number.int({ min: 1, max: 5 });\n break;\n case 'boolean':\n dataProps[prop] = () => faker.datatype.boolean();\n break;\n case 'date':\n dataProps[prop] = () => faker.date.past();\n break;\n case 'url':\n dataProps[prop] = () => faker.internet.url();\n break;\n case 'array':\n dataProps[prop] = () =>\n faker.lorem.words({ min: 2, max: 5 }).split(' ');\n break;\n }\n }\n\n const data = getFakerData<T>(\n limit,\n dataProps,\n typeof this.model === 'string' ? this.model : this.model?.constructor.name\n );\n\n if (!values) return data;\n\n const _values = Object.values(values as KeyValue);\n const iterated: (string | number)[] = [];\n\n function getPkValue(item: KeyValue): T {\n if (_values.length > 0) {\n const randomIndex = Math.floor(Math.random() * _values.length);\n const selected = _values.splice(randomIndex, 1)[0];\n const value =\n keyType === Primitives.STRING\n ? selected\n : keyType === Primitives.NUMBER\n ? parseToNumber(selected)\n : keyType === Array.name\n ? [selected]\n : selected;\n item[key as string] = value;\n }\n if (!iterated.includes(item[key as string])) {\n iterated.push(item[key as string]);\n return item as T;\n }\n return undefined as unknown as T;\n }\n const uids = new Set();\n return data\n .map((d) => getPkValue(d))\n .filter((item: KeyValue) => {\n if (!item || uids.has(item[key]) || !item[key] || item[key] === undefined)\n return false;\n uids.add(item[key]);\n return true;\n })\n .filter(Boolean) as T[];\n }\n}\n\nexport function getFakerData<T extends Model>(\n limit = 100,\n data: Record<string, FunctionLike>,\n model?: string\n): T[] {\n let index = 1;\n return Array.from({ length: limit }, () => {\n const item: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n const val = value();\n item[key] = val?.constructor === Date ? formatDate(val) : val;\n }\n // if ((item as any)?.['code'])\n // (item as any).code = `${index}`;\n // item.id = index;\n // item.createdAt = faker.date.past({ refDate: '2025-01-01' });\n if (item['productCode']) item['productCode'] = `${index}`;\n index = index + 1;\n return (!model ? item : Model.build(item, model)) as T;\n });\n}\n","/**\n * @module utils\n * @description Utility functions for Angular Decaf applications\n * @summary The utils module provides a collection of utility functions and types\n * that assist with common tasks in Decaf Angular applications. It includes functions\n * for array manipulation, date formatting, logging, string operations, and various\n * utility functions for working with Angular components and services. These helpers\n * simplify common operations and promote code reuse across the application.\n * Key exports include logging utilities, string manipulation functions, and component\n * utility functions.\n */\nexport * from './helpers';\nexport * from './DecafFakerRepository';\n","/**\n * @module lib/engine/NgxRenderingEngine\n * @description Angular rendering engine for Decaf model-driven UIs.\n * @summary Implements NgxRenderingEngine which converts model decorator metadata\n * into Angular components, manages component registration, and orchestrates\n * dynamic component creation and input mapping.\n * @link {@link NgxRenderingEngine}\n */\nimport { FieldDefinition, HTML5InputTypes, RenderingEngine } from '@decaf-ts/ui-decorators';\nimport { AngularFieldDefinition, KeyValue } from './types';\nimport { AngularDynamicOutput, IFormComponentProperties } from './interfaces';\nimport { AngularEngineKeys } from './constants';\nimport { Model, ModelKeys, Primitives } from '@decaf-ts/decorator-validation';\nimport { Constructor } from '@decaf-ts/decoration';\nimport { InternalError, OperationKeys } from '@decaf-ts/db-decorators';\nimport {\n ComponentMirror,\n ComponentRef,\n createEnvironmentInjector,\n EnvironmentInjector,\n Injector,\n reflectComponentType,\n runInInjectionContext,\n TemplateRef,\n Type,\n ViewContainerRef,\n createComponent,\n} from '@angular/core';\nimport { NgxFormService } from '../services/NgxFormService';\nimport { isDevelopmentMode } from '../utils';\nimport { FormParent } from './types';\nimport { getLogger } from '../for-angular-common.module';\n\n/**\n * @description Angular implementation of the RenderingEngine for Decaf components.\n * @summary This class extends the base RenderingEngine to provide Angular-specific rendering capabilities.\n * It handles the conversion of field definitions to Angular components, manages component registration,\n * and provides utilities for component creation and input handling. The engine converts model decorator\n * metadata into dynamically created Angular components with proper input binding and lifecycle management.\n * @template AngularFieldDefinition - Type for Angular-specific field definitions\n * @template AngularDynamicOutput - Type for Angular-specific component output\n * @class NgxRenderingEngine\n * @extends {RenderingEngine<AngularFieldDefinition, AngularDynamicOutput>}\n * @example\n * ```typescript\n * const engine = NgxRenderingEngine.get();\n * engine.initialize();\n * const output = engine.render(myModel, {}, viewContainerRef, injector, templateRef);\n * ```\n * @mermaid\n * sequenceDiagram\n * participant Client\n * participant Engine as NgxRenderingEngine\n * participant Components as RegisteredComponents\n *\n * Client->>Engine: get()\n * Client->>Engine: initialize()\n * Client->>Engine: render(model, props, vcr, injector, tpl)\n * Engine->>Engine: toFieldDefinition(model, props)\n * Engine->>Engine: fromFieldDefinition(fieldDef, vcr, injector, tpl)\n * Engine->>Components: components(fieldDef.tag)\n * Components-->>Engine: component constructor\n * Engine->>Engine: createComponent(component, inputs, metadata, vcr, injector, template)\n * Engine-->>Client: return AngularDynamicOutput\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\nexport class NgxRenderingEngine extends RenderingEngine<\n AngularFieldDefinition,\n AngularDynamicOutput\n> {\n private static _injector?: Injector;\n\n /**\n * @description Registry of components available for dynamic rendering.\n * @summary Static registry that stores all registered components indexed by their selector name.\n * Each component entry contains a constructor reference that can be used to instantiate\n * the component during the rendering process. This registry is shared across all instances\n * of the rendering engine and is populated through the registerComponent method.\n * @private\n * @static\n * @type {Record<string, { constructor: Constructor<unknown> }>}\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n private static _components: Record<\n string,\n { constructor: Constructor<unknown> }\n >;\n\n /**\n * @description Currently active model being rendered by the engine.\n * @summary Stores a reference to the model instance that is currently being processed\n * by the rendering engine. This property is set during the render method execution\n * and is used throughout the rendering lifecycle to access model data and metadata.\n * The definite assignment assertion (!) is used because this property is always\n * initialized before use within the render method.\n * @private\n * @type {Model}\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n private _model!: Model;\n\n /**\n * @description Current operation context for component visibility control.\n * @summary Static property that stores the current operation being performed,\n * which is used to determine component visibility through the 'hidden' property.\n * Components can specify operations where they should be hidden, and this property\n * provides the context for those visibility checks. The value is typically extracted\n * from the global properties during the rendering process.\n * @private\n * @static\n * @type {string | undefined}\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n private static _operation: string | undefined = undefined;\n\n /**\n * @description Reference to the currently active component instance.\n * @summary Static property that maintains a reference to the most recently created\n * component instance. This is used internally for component lifecycle management\n * and can be cleared through the destroy method. The reference allows access to\n * the active component instance for operations that need to interact with the\n * currently rendered component.\n * @private\n * @static\n * @type {Type<unknown> | undefined}\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n private static _instance: Type<unknown> | undefined;\n\n // private static _projectable: boolean = true\n\n /**\n * @description Parent component properties for child component inheritance.\n * @summary Static property that stores parent component properties that should be\n * inherited by child components. This is particularly used for passing page configuration\n * down to child components in multi-page forms. The property is cleared after rendering\n * to prevent property leakage between unrelated component trees.\n * @private\n * @static\n * @type {KeyValue | undefined}\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n private static _parentProps: KeyValue | undefined = undefined;\n\n /**\n * @description Constructs a new NgxRenderingEngine instance.\n * @summary Initializes a new instance of the Angular rendering engine by calling the parent\n * constructor with the 'angular' engine type identifier. This constructor sets up the base\n * rendering engine functionality with Angular-specific configurations and prepares the\n * instance for component registration and rendering operations.\n * @constructor\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n constructor() {\n super(AngularEngineKeys.FLAVOUR);\n }\n\n /**\n * @description Converts a field definition to an Angular component output.\n * @summary This private method takes a field definition and creates the corresponding Angular component.\n * It handles component instantiation, input property mapping, child component rendering, and visibility\n * control. The method validates input properties against the component's metadata and processes\n * child components recursively.\n * @param {FieldDefinition<AngularFieldDefinition>} fieldDef - The field definition to convert\n * @param {ViewContainerRef} vcr - The view container reference for component creation\n * @param {Injector} injector - The Angular injector for dependency injection\n * @param {TemplateRef<any>} tpl - The template reference for content projection\n * @param {string} registryFormId - Form identifier for the component renderer\n * @param {boolean} createComponent - Whether to create the component instance\n * @param {FormParent} [formGroup] - Optional form group for form components\n * @return {AngularDynamicOutput} The Angular component output with component reference and inputs\n * @mermaid\n * sequenceDiagram\n * participant Method as fromFieldDefinition\n * participant Components as NgxRenderingEngine.components\n * participant Angular as Angular Core\n * participant Process as processChild\n *\n * Method->>Components: components(fieldDef.tag)\n * Components-->>Method: component constructor\n * Method->>Angular: reflectComponentType(component)\n * Angular-->>Method: componentMetadata\n * Method->>Method: Validate input properties\n * Method->>Method: Create result object\n * alt Has children\n * Method->>Process: Process children recursively\n * Process->>Method: Return processed children\n * Method->>Angular: Create embedded view\n * Method->>Method: Create component instance\n * end\n * Method-->>Caller: return AngularDynamicOutput\n * @private\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n private fromFieldDefinition(\n fieldDef: FieldDefinition<AngularFieldDefinition>,\n vcr: ViewContainerRef,\n injector: Injector,\n tpl: TemplateRef<unknown>,\n registryFormId: string = Date.now().toString(36).toUpperCase(),\n createComponent: boolean = true,\n formGroup?: FormParent\n ): AngularDynamicOutput {\n const cmp =\n (fieldDef as KeyValue)?.['component'] ||\n NgxRenderingEngine.components(fieldDef.tag);\n const component = cmp.constructor as unknown as Type<unknown>;\n\n const componentMetadata = reflectComponentType(component);\n if (!componentMetadata) {\n throw new InternalError(\n `Metadata for component ${fieldDef.tag} not found.`\n );\n }\n\n const { inputs: possibleInputs } = componentMetadata;\n const inputs = { ...fieldDef.props };\n\n const unmappedKeys = Object.keys(inputs).filter((input) => {\n const isMapped = possibleInputs.find(\n ({ propName }) => propName === input\n );\n if (!isMapped) delete inputs[input];\n return !isMapped;\n });\n\n if (unmappedKeys.length > 0 && isDevelopmentMode())\n getLogger(this.fromFieldDefinition).warn(\n `Unmapped input properties for component ${fieldDef.tag}: ${unmappedKeys.join(', ')}`\n );\n\n const operation = NgxRenderingEngine._operation;\n\n const hiddenOn = inputs?.hidden || [];\n if ((hiddenOn as string[]).includes(operation as string))\n return { inputs, injector };\n\n // const customTypes = (inputs as KeyValue)?.['customTypes'] || [];\n // const hasFormRoot = Object.values(possibleInputs).some(({propName}) => propName === AngularEngineKeys.PARENT_FORM);\n // if (hasFormRoot && !inputs?.[AngularEngineKeys.PARENT_FORM] && formGroup)\n // inputs[AngularEngineKeys.PARENT_FORM] = formGroup;\n if(operation !== OperationKeys.CREATE && (hiddenOn as string[]).includes(OperationKeys.CREATE)) {\n fieldDef.props = {...fieldDef.props, ... {readonly: true, type: HTML5InputTypes.TEXT} };\n }\n\n const result: AngularDynamicOutput = {\n component,\n inputs,\n injector,\n };\n\n if (fieldDef.rendererId)\n (result.inputs as Record<string, unknown>)['rendererId'] =\n fieldDef.rendererId;\n // process children\n // generating DOM\n // const projectable = NgxRenderingEngine._projectable;\n // const template = !projectable ? [] : vcr.createEmbeddedView(tpl, injector).rootNodes;\n // const template = [];\n const hasChildren = Object.values(possibleInputs).some(\n ({ propName }) => propName === AngularEngineKeys.CHILDREN\n );\n const hasModel = Object.values(possibleInputs).some(\n ({ propName }) => propName === ModelKeys.MODEL\n );\n const componentInputs = Object.assign(\n inputs,\n hasModel ? { model: this._model } : {},\n hasChildren ? { children: fieldDef?.['children'] || [] } : {}\n );\n if (createComponent) {\n vcr.clear();\n const componentInstance = NgxRenderingEngine.createComponent(\n component,\n componentInputs,\n injector,\n componentMetadata,\n vcr,\n []\n );\n result.component = NgxRenderingEngine._instance =\n componentInstance as Type<unknown>;\n }\n if (fieldDef.children?.length) {\n if (!NgxRenderingEngine._parentProps && inputs?.['pages']) {\n NgxRenderingEngine._parentProps = { pages: inputs?.['pages'] };\n // NgxRenderingEngine._projectable = false;\n }\n\n result.children = fieldDef.children.map((child) => {\n const readonly = operation === OperationKeys.UPDATE && ((child?.props?.hidden || []) as string[]).includes(OperationKeys.CREATE);\n // const hiddenOn = (child?.props?.hidden || []) as string[];\n // // moved to ui decorators\n // if (child?.children?.length) {\n // child.children = child.children.filter(c => {\n // const hiddenOn = c?.props?.hidden || [];\n // if (!(hiddenOn as string[]).includes(operation as string))\n // return c\n // })\n // }\n // if (!hiddenOn?.length || !(hiddenOn as CrudOperations[]).includes(operation as CrudOperations))\n if(!readonly) {\n NgxFormService.addControlFromProps(registryFormId, child.props, {\n ...inputs,\n ...(NgxRenderingEngine._parentProps || {}),\n });\n } else {\n child.props = {...child.props, ... {readonly: true} };\n }\n return this.fromFieldDefinition(\n child,\n vcr,\n injector,\n tpl,\n registryFormId,\n false,\n formGroup\n );\n });\n }\n return result;\n }\n\n /**\n * @description Creates an Angular component instance with inputs and template projection.\n * @summary This static utility method creates an Angular component instance with the specified\n * inputs and template. It uses Angular's component creation API to instantiate the component\n * and then sets the input properties using the provided metadata.\n * @param {Type<unknown>} component - The component type to create\n * @param {KeyValue} [inputs={}] - The input properties to set on the component\n * @param {ComponentMirror<unknown>} metadata - The component metadata for input validation\n * @param {ViewContainerRef} vcr - The view container reference for component creation\n * @param {Injector} injector - The Angular injector for dependency injection\n * @param {Node[]} [template=[]] - The template nodes to project into the component\n * @return {ComponentRef<unknown>} The created component reference\n * @static\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n static createComponent<C>(\n component: Type<unknown>,\n inputs: KeyValue = {},\n injector?: Injector,\n metadata?: ComponentMirror<unknown>,\n vcr?: ViewContainerRef,\n template?: Node[]\n ): C {\n if (vcr && metadata && injector)\n return NgxRenderingEngine.createViewComponent(\n component,\n inputs,\n metadata,\n vcr,\n injector,\n template || []\n );\n return NgxRenderingEngine.createHostComponent(component, inputs, injector);\n }\n\n static createViewComponent<C>(\n component: Type<unknown>,\n inputs: KeyValue = {},\n metadata: ComponentMirror<unknown>,\n vcr: ViewContainerRef,\n injector: Injector,\n template: Node[] = []\n ): C {\n const cmp = vcr.createComponent(component as Type<unknown>, {\n environmentInjector: injector as EnvironmentInjector,\n projectableNodes: [template],\n });\n this.setInputs(cmp, inputs, metadata);\n return cmp.instance as C;\n }\n\n static createHostComponent<C>(\n component: Type<C | unknown> | string,\n props: KeyValue = {},\n injector?: Injector\n ): C {\n if (!injector)\n injector =\n NgxRenderingEngine._injector ||\n Injector.create({ providers: [], parent: Injector.NULL });\n const envInjector: EnvironmentInjector = createEnvironmentInjector(\n [],\n injector as EnvironmentInjector\n );\n\n let cmp: ComponentRef<unknown> = {} as ComponentRef<C>;\n\n runInInjectionContext(envInjector, () => {\n const host = document.createElement('div');\n component =\n typeof component === Primitives.STRING\n ? (NgxRenderingEngine.components(\n component as string\n ) as Type<unknown>)\n : component;\n if (!host) throw new Error('Cant create host element for component');\n\n cmp = createComponent(component as Type<unknown>, {\n environmentInjector: envInjector,\n hostElement: host,\n });\n\n const metadata = reflectComponentType(component as Type<unknown>);\n if (!metadata)\n throw new InternalError(\n `Metadata for component ${component} not found.`\n );\n\n const { inputs: possibleInputs } = metadata;\n const inputs = { ...props };\n\n const unmappedKeys = Object.keys(inputs).filter((input) => {\n const isMapped = possibleInputs.find(\n ({ propName }) => propName === input\n );\n if (!isMapped) delete inputs[input];\n return !isMapped;\n });\n\n if (unmappedKeys.length > 0 && isDevelopmentMode())\n getLogger(this.createHostComponent).warn(\n `Unmapped input properties for component ${component}: ${unmappedKeys.join(', ')}`\n );\n\n if (metadata)\n this.setInputs(\n cmp as ComponentRef<unknown>,\n inputs,\n metadata as ComponentMirror<unknown>\n );\n document.body.querySelector('ion-app')?.appendChild(host);\n });\n\n return cmp.instance as C;\n }\n\n /**\n * @description Extracts decorator metadata from a model.\n * @summary This method provides access to the field definition generated from a model's\n * decorators. It's a convenience wrapper around the toFieldDefinition method that\n * converts a model to a field definition based on its decorators and the provided\n * global properties.\n * @param {Model} model - The model to extract decorators from\n * @param {Record<string, unknown>} globalProps - Global properties to include in the field definition\n * @return {FieldDefinition<AngularFieldDefinition>} The field definition generated from the model\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n getDecorators(\n model: Model,\n globalProps: Record<string, unknown>\n ): FieldDefinition<AngularFieldDefinition> {\n return this.toFieldDefinition(model, globalProps);\n }\n\n /**\n * @description Destroys the current engine instance and cleans up resources.\n * @summary This static method clears the current instance reference and parent props,\n * effectively destroying the singleton instance of the rendering engine. Optionally\n * removes the form registry for the specified form ID. This can be used to reset the\n * engine state or to prepare for a new instance creation.\n * @param {string} [formId] - Optional form ID to remove from registry\n * @return {Promise<void>} A promise that resolves when the instance is destroyed\n * @static\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n static async destroy(formId?: string): Promise<void> {\n if (formId) NgxFormService.removeRegistry(formId);\n NgxRenderingEngine._instance = undefined;\n NgxRenderingEngine._parentProps = undefined;\n }\n\n /**\n * @description Renders a model into an Angular component output.\n * @summary This method takes a model and converts it to an Angular component output.\n * It first stores a reference to the model, then converts it to a field definition\n * using the base RenderingEngine's toFieldDefinition method, and finally converts\n * that field definition to an Angular component output using fromFieldDefinition.\n * @template M - Type extending Model\n * @param {M} model - The model to render\n * @param {Record<string, unknown>} globalProps - Global properties to pass to the component\n * @param {ViewContainerRef} vcr - The view container reference for component creation\n * @param {Injector} injector - The Angular injector for dependency injection\n * @param {TemplateRef<any>} tpl - The template reference for content projection\n * @return {AngularDynamicOutput} The Angular component output with component reference and inputs\n * @mermaid\n * sequenceDiagram\n * participant Client as Client Code\n * participant Render as render method\n * participant ToField as toFieldDefinition\n * participant FromField as fromFieldDefinition\n *\n * Client->>Render: render(model, globalProps, vcr, injector, tpl)\n * Render->>Render: Store model reference\n * Render->>ToField: toFieldDefinition(model, globalProps)\n * ToField-->>Render: fieldDef\n * Render->>FromField: fromFieldDefinition(fieldDef, vcr, injector, tpl)\n * FromField-->>Render: AngularDynamicOutput\n * Render-->>Client: return AngularDynamicOutput\n * @override\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n override render<M extends Model>(\n model: M,\n globalProps: Record<string, unknown>,\n vcr: ViewContainerRef,\n injector: Injector,\n tpl: TemplateRef<unknown>\n ): AngularDynamicOutput {\n let result: AngularDynamicOutput;\n if (!NgxRenderingEngine._injector) NgxRenderingEngine._injector = injector;\n try {\n this._model = model;\n const formId = Date.now().toString(36).toUpperCase();\n const fieldDef = this.toFieldDefinition(model, globalProps);\n const props = fieldDef.props as Partial<IFormComponentProperties>;\n if (!NgxRenderingEngine._operation)\n NgxRenderingEngine._operation = props?.operation || undefined;\n const isArray =\n (props?.pages && (props?.pages as number) >= 1) ||\n props?.multiple === true;\n const formGroup = NgxFormService.createForm(formId, isArray);\n result = this.fromFieldDefinition(\n fieldDef,\n vcr,\n injector,\n tpl,\n formId,\n true,\n formGroup\n );\n if (result.component)\n (result.component as KeyValue)['formGroup'] = formGroup;\n NgxRenderingEngine.destroy(formId);\n } catch (e: unknown) {\n throw new InternalError(\n `Failed to render Model ${model.constructor.name}: ${e}`\n );\n }\n\n return result;\n }\n\n /**\n * @description Initializes the rendering engine.\n * @summary This method initializes the rendering engine. It checks if the engine is already initialized\n * and sets the initialized flag to true. This method is called before the engine is used\n * to ensure it's properly set up for rendering operations.\n * @return {Promise<void>} A promise that resolves when initialization is complete\n * @override\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n override async initialize(): Promise<void> {\n if (!this.initialized) this.initialized = true;\n }\n\n /**\n * @description Registers a component with the rendering engine.\n * @summary This static method registers a component constructor with the rendering engine\n * under a specific name. It initializes the components registry if needed and throws\n * an error if a component is already registered under the same name to prevent\n * accidental overrides.\n * @param {string} name - The name to register the component under\n * @param {Constructor<unknown>} constructor - The component constructor\n * @return {void}\n * @static\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n static registerComponent(\n name: string,\n constructor: Constructor<unknown>\n ): void {\n if (!this._components) this._components = {};\n if (name in this._components)\n throw new InternalError(`Component already registered under ${name}`);\n this._components[name] = {\n constructor: constructor,\n };\n }\n\n /**\n * @description Retrieves registered components from the rendering engine.\n * @summary This static method retrieves either all registered components or a specific component\n * by its selector. When called without a selector, it returns an array of all registered\n * components. When called with a selector, it returns the specific component if found,\n * or throws an error if the component is not registered.\n * @param {string} [selector] - Optional selector to retrieve a specific component\n * @return {Object|Array} Either a specific component or an array of all components\n * @static\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n static components(selector?: string): object | string[] {\n if (!selector) return Object.values(this._components);\n if (!(selector in this._components))\n throw new InternalError(`No Component registered under ${selector}`);\n return this._components[selector];\n }\n\n /**\n * @description Sets input properties on a component instance.\n * @summary This static utility method sets input properties on a component instance\n * based on the provided inputs object and component metadata. It handles both simple\n * values and nested objects, recursively processing object properties. The method\n * validates each input against the component's metadata to ensure only valid inputs\n * are set.\n * @param {ComponentRef<unknown>} component - The component reference to set inputs on\n * @param {KeyValue} inputs - The input properties to set\n * @param {ComponentMirror<unknown>} metadata - The component metadata for input validation\n * @return {void}\n * @mermaid\n * sequenceDiagram\n * participant Caller\n * participant SetInputs as setInputs\n * participant Parse as parseInputValue\n * participant Component as ComponentRef\n *\n * Caller->>SetInputs: setInputs(component, inputs, metadata)\n * SetInputs->>SetInputs: Iterate through inputs\n * loop For each input\n * SetInputs->>SetInputs: Check if input exists in metadata\n * alt Input is 'props'\n * SetInputs->>Parse: parseInputValue(component, value)\n * Parse->>Parse: Recursively process nested objects\n * Parse->>Component: setInput(key, value)\n * else Input is valid\n * SetInputs->>Component: setInput(key, value)\n * end\n * end\n * @static\n * @memberOf module:lib/engine/NgxRenderingEngine\n */\n static setInputs(\n component: ComponentRef<unknown>,\n inputs: KeyValue,\n metadata: ComponentMirror<unknown>\n ): void {\n function parseInputValue(\n component: ComponentRef<unknown>,\n input: KeyValue\n ) {\n Object.keys(input).forEach((key) => {\n const value = input[key];\n if (typeof value === 'object' && !!value)\n return parseInputValue(component, value);\n component.setInput(key, value);\n });\n }\n\n Object.entries(inputs).forEach(([key, value]) => {\n const prop = metadata.inputs.find(\n (item: { propName: string }) => item.propName === key\n );\n if (prop) {\n if (key === 'props') {\n component.setInput(key, value);\n parseInputValue(component, value);\n }\n\n // if (key === 'locale' && !value)\n // value = getLocaleFromClassName(this._componentName);\n component.setInput(key, value);\n }\n });\n }\n}\n","/**\n * @module module:lib/i18n/Loader\n * @description Internationalization loader and helpers for the for-angular package.\n * @summary Provides an implementation of TranslateLoader (I18nLoader) and helper factories\n * to load translation resources. Also exposes locale utilities used by components to resolve\n * localized keys.\n *\n * @link {@link I18nLoader}\n */\nimport { inject } from '@angular/core';\nimport { HttpClient, provideHttpClient } from '@angular/common/http';\nimport { provideTranslateParser, provideTranslateService, RootTranslateServiceConfig, TranslateLoader, TranslateParser, TranslationObject } from '@ngx-translate/core';\nimport { Primitives, sf } from '@decaf-ts/decorator-validation';\nimport { forkJoin, Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport {I18nResourceConfig} from '../engine/interfaces';\nimport { FunctionLike, I18nResourceConfigType, KeyValue } from '../engine/types';\nimport { cleanSpaces, getLocaleFromClassName } from '../utils';\nimport en from './data/en.json';\nimport { I18N_CONFIG_TOKEN } from '../for-angular-common.module';\n\nconst libLanguage: Record<string, TranslationObject> = {en};\n\n/**\n * @description Retrieves the locale context for a given class, object, or string.\n * @summary Resolves the locale context by extracting the class name or using the provided suffix.\n *\n * @param {FunctionLike | object | string} clazz - The class, object, or string to derive the locale context from.\n * @param {string} [suffix] - An optional suffix to append to the locale context.\n * @returns {string} - The resolved locale context string.\n */\nexport function getLocaleContext(clazz: FunctionLike | object | string, suffix?: string): string {\n return getLocaleFromClassName(clazz, suffix);\n}\n\n\n/**\n * @description Generates a localized string by combining locale and phrase\n * @summary This utility function creates a properly formatted locale string by combining\n * a locale identifier with a phrase. It handles edge cases such as empty phrases,\n * missing locales, and phrases that already include the locale prefix. This function\n * is useful for ensuring consistent formatting of localized strings throughout the application.\n *\n * @param {string} locale - The locale identifier (e.g., 'en', 'fr')\n * @param {string | undefined} phrase - The phrase to localize\n * @return {string} The formatted locale string, or empty string if phrase is undefined\n *\n * @function generateLocaleFromString\n * @memberOf module:for-angular\n */\nexport function getLocaleContextByKey(\n locale: string,\n phrase: string | undefined\n): string {\n if (!phrase)\n return locale;\n if (!locale || phrase.includes(`${locale}.`))\n return phrase;\n const parts = phrase.split(' ');\n return `${locale}.${cleanSpaces(parts.join('.'), true)}`;\n}\n\n/**\n * @description Factory function for creating an instance of I18nLoader.\n * @summary Configures and returns an I18nLoader instance with the specified HTTP client and translation resources.\n *\n * @param {HttpClient} http - The HTTP client used to fetch translation resources.\n * @returns {TranslateLoader} - An instance of I18nLoader configured with the provided HTTP client and resources.\n */\nexport function I18nLoaderFactory(http: HttpClient): TranslateLoader {\n const { resources, versionedSuffix } = inject(I18N_CONFIG_TOKEN, { optional: true }) ?? provideI18nLoader().useValue;\n return new I18nLoader(http, resources?.length ? resources : [{ prefix: './app/assets/i18n/', suffix: '.json' }], versionedSuffix);\n}\n\n/**\n * @description Provides the I18nLoader configuration.\n * @summary Configures the translation resources and versioned suffix for the I18nLoader.\n *\n * @param {I18nResourceConfigType} [resources=[]] - The translation resources to be used by the loader.\n * @param {boolean} [versionedSuffix=false] - Whether to append a versioned suffix to resource URLs.\n * @returns {object} - The configuration object for the I18nLoader.\n */\nexport function provideI18nLoader(resources: I18nResourceConfigType = [], versionedSuffix: boolean = false) {\n if (!Array.isArray(resources)) {\n resources = [resources];\n }\n return {\n provide: I18N_CONFIG_TOKEN,\n useValue: { resources: [...resources], versionedSuffix },\n };\n}\n\n/**\n * @description Custom implementation of TranslateLoader for loading translations.\n * @summary Fetches and merges translation resources, supporting versioned suffixes and recursive merging.\n */\nexport class I18nLoader implements TranslateLoader {\n /**\n * @param {HttpClient} http - The HTTP client used to fetch translation resources.\n * @param {I18nResourceConfig[]} [resources=[]] - The translation resources to be loaded.\n * @param {boolean} [versionedSuffix=false] - Whether to append a versioned suffix to resource URLs.\n */\n constructor(private http: HttpClient, private resources: I18nResourceConfig[] = [], private versionedSuffix: boolean = false) {}\n\n /**\n * @description Appends a versioned suffix to the resource URL if enabled.\n * @summary Generates a versioned suffix based on the current date.\n *\n * @param {string} suffix - The original suffix of the resource URL.\n * @returns {string} - The modified suffix with a version string appended.\n */\n private getSuffix(suffix: string): string {\n if (!this.versionedSuffix) {\n return suffix;\n }\n const today = new Date();\n return `${suffix}?version=${today.getFullYear()}${today.getMonth()}${today.getDay()}`;\n }\n\n /**\n * @description Fetches and merges translations for the specified language.\n * @summary Loads translation resources, merges them recursively, and includes library keys.\n *\n * @param {string} lang - The language code for the translations to load.\n * @returns {Observable<TranslationObject>} - An observable that emits the merged translation object.\n */\n getTranslation(lang: string): Observable<TranslationObject> {\n const libKeys: KeyValue = libLanguage[lang] || libLanguage['en'] || {};\n const httpRequests$ = forkJoin(\n this.resources.map(config =>\n this.http.get<TranslationObject>(`${config.prefix}${lang}${this.getSuffix(config.suffix || '.json')}`)\n )\n );\n\n /**\n * @description Recursively merges two translation objects.\n * @summary Combines the properties of the source object into the target object.\n *\n * @param {KeyValue} target - The target object to merge into.\n * @param {KeyValue} source - The source object to merge from.\n * @returns {KeyValue} - The merged object.\n */\n function recursiveMerge(target: KeyValue, source: KeyValue): KeyValue {\n for (const key of Object.keys(source)) {\n if (source[key] instanceof Object) {\n if (!target[key]) Object.assign(target, { [key]: {} });\n recursiveMerge(target[key], source[key]);\n } else {\n Object.assign(target, { [key]: source[key] });\n }\n }\n return target;\n }\n\n return httpRequests$.pipe(\n map(res => {\n const merged = {\n ...libKeys,\n ...res.reduce((acc: KeyValue, current: KeyValue) => {\n for (const key in current) {\n let value = current[key] || {};\n if (libKeys[key]) {\n value = { ...libKeys[key], ...recursiveMerge(libKeys[key] as KeyValue, current[key] as KeyValue) };\n }\n acc[key] = value;\n }\n return acc;\n }, {}),\n };\n return merged;\n })\n );\n }\n}\n\n/**\n * @description Custom implementation of TranslateParser for interpolation.\n * @summary Extends TranslateParser to support string formatting with parameters.\n */\nexport class I18nParser extends TranslateParser {\n /**\n * @description Interpolates a translation string with parameters.\n * @summary Replaces placeholders in the translation string with parameter values.\n *\n * @param {string} value - The translation string to interpolate.\n * @param {object | string} [params={}] - The parameters to replace placeholders with.\n * @returns {string} - The interpolated translation string.\n */\n interpolate(value: string, params: object | string = {}): string {\n if (typeof params === Primitives.STRING) {\n params = { '0': params };\n }\n return sf(value, ...Object.values(params));\n }\n}\n\n/**\n * @description Provides the internationalization (i18n) configuration for the application.\n * @summary Configures the translation service with a fallback language, default language, custom parser, and loader.\n *\n * @param {RootTranslateServiceConfig} [config={fallbackLang: 'en', lang: 'en'}] - The configuration for the translation service, including fallback and default languages.\n * @param {I18nResourceConfigType} [resources=[]] - The translation resources to be used by the loader.\n * @param {boolean} [versionedSuffix=false] - Whether to append a versioned suffix to resource URLs.\n * @returns {Array} - An array of providers for the translation service and loader.\n */\nexport function provideI18n(\n config: RootTranslateServiceConfig = { fallbackLang: 'en', lang: 'en' },\n resources: I18nResourceConfigType = [],\n versionedSuffix: boolean = false\n) {\n return [\n provideHttpClient(),\n provideTranslateService({\n fallbackLang: config.fallbackLang,\n lang: config.lang,\n parser: provideTranslateParser(I18nParser),\n loader: {\n provide: TranslateLoader,\n useFactory: I18nLoaderFactory,\n deps: [HttpClient],\n },\n }),\n provideI18nLoader(resources, versionedSuffix),\n ];\n}\n","/**\n * @module NgxMediaService\n * @description Provides utilities for managing media-related features such as color scheme detection,\n * window resize observation, and SVG injection.\n * @summary\n * This module exposes the `NgxMediaService` class, which includes methods for observing the\n * application's color scheme, handling window resize events, and dynamically injecting SVG content\n * into the DOM. It leverages Angular's dependency injection system and RxJS for reactive programming.\n *\n * Key exports:\n * - {@link NgxMediaService}: The main service class providing media-related utilities.\n */\n\nimport { ElementRef, Injectable, NgZone, inject } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { fromEvent, Subject, Observable, BehaviorSubject, merge, of, timer } from 'rxjs';\nimport { distinctUntilChanged, map, shareReplay, takeUntil, tap, switchMap } from 'rxjs/operators';\nimport { IWindowResizeEvent } from '../engine/interfaces';\nimport { WindowColorScheme } from '../engine/types';\nimport { getWindow, getWindowDocument } from '../utils/helpers';\nimport { AngularEngineKeys, WindowColorSchemes } from '../engine/constants';\n\n\n\n\n/**\n * @description Service for managing media-related features in an Angular application.\n * @summary\n * The `NgxMediaService` provides utilities for observing and managing media-related features\n * such as color scheme detection, window resize events, and dynamic SVG injection. It leverages\n * Angular's dependency injection system and RxJS for reactive programming.\n *\n * @class NgxMediaService\n * @example\n * // Inject the service into a component\n * constructor(private mediaService: NgxMediaService) {}\n *\n * // Observe the current color scheme\n * this.mediaService.colorScheme$.subscribe(scheme => {\n * console.log('Current color scheme:', scheme);\n * });\n *\n * // Observe window resize events\n * this.mediaService.resize$.subscribe(dimensions => {\n * console.log('Window dimensions:', dimensions);\n * });\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class NgxMediaService {\n\n /**\n * @description Subject used to signal the destruction of the service.\n * @summary\n * This subject is used to complete observables and clean up resources when the service is destroyed.\n * It is utilized with the `takeUntil` operator to manage subscriptions.\n */\n private readonly destroy$ = new Subject<void>();\n\n /**\n * @description BehaviorSubject to track the window's dimensions.\n * @summary\n * This subject holds the current dimensions of the window (width and height) and emits updates\n * whenever the window is resized. It is used to provide the `resize$` observable.\n */\n private resizeSubject = new BehaviorSubject<IWindowResizeEvent>({\n width: this._window.innerWidth,\n height: this._window.innerHeight\n });\n\n /**\n * @description Angular's NgZone service for running code outside Angular's zone.\n * @summary\n * This service is used to optimize performance by running certain operations outside\n * Angular's zone and bringing updates back into the zone when necessary.\n */\n private readonly angularZone: NgZone = inject(NgZone);\n\n /**\n * @description Angular's HttpClient service for making HTTP requests.\n * @summary\n * This service is used to fetch resources such as SVG files for injection into the DOM.\n */\n // private http = inject(HttpClient);\n\n /**\n * @description Tracks the current color scheme of the application.\n * @summary\n * This property holds the current color scheme (light, dark, or undefined) and is updated\n * whenever the color scheme changes.\n */\n private currentSchema: WindowColorScheme = WindowColorSchemes.undefined;\n\n /**\n * @description Observable that emits the current color scheme of the application.\n * @summary\n * This observable emits the current color scheme (light or dark) and updates whenever\n * the system's color scheme preference changes or the `DARK_PALETTE_CLASS` is toggled.\n */\n readonly colorScheme$: Observable<WindowColorScheme> = this.colorSchemeObserver();\n\n /**\n * @description Observable that emits the current dimensions of the window.\n * @summary\n * This observable emits the current dimensions of the window (width and height) and updates\n * whenever the window is resized.\n */\n readonly resize$: Observable<IWindowResizeEvent> = this.resizeSubject.asObservable();\n\n /**\n * @description Retrieves the global `window` object.\n * @summary\n * This getter provides access to the global `window` object, ensuring it is properly typed.\n *\n * @return {Window} The global `window` object.\n */\n private get _window(): Window {\n return getWindow() as Window;\n }\n\n /**\n * @description Retrieves the global `document` object.\n * @summary\n * This getter provides access to the global `document` object, ensuring it is properly typed.\n *\n * @return {Document} The global `document` object.\n */\n private get _document(): Document {\n return getWindowDocument() as Document;\n }\n\n /**\n * @description Observes window resize events and emits the updated dimensions.\n * @summary\n * This method listens for window resize events and emits the new dimensions\n * (width and height) through the `resize$` observable. The resize events are\n * processed outside Angular's zone to improve performance, and updates are\n * brought back into the Angular zone to ensure change detection.\n *\n * @return {Observable<IWindowResizeEvent>} An observable that emits the window dimensions on resize.\n * @function windowResizeObserver\n * @example\n * mediaService.windowResizeObserver().subscribe(dimensions => {\n * console.log('Window dimensions:', dimensions);\n * });\n */\n windowResizeObserver(): Observable<IWindowResizeEvent> {\n const win = this._window;\n this.angularZone.runOutsideAngular(() => {\n fromEvent(win, 'resize')\n .pipe(\n distinctUntilChanged(),\n takeUntil(this.destroy$),\n shareReplay(1)\n )\n .subscribe(() => {\n const dimensions: IWindowResizeEvent = {\n width: win.innerWidth,\n height: win.innerHeight\n };\n // update within the zone to reflect in Angular\n this.angularZone.run(() => this.resizeSubject.next(dimensions));\n });\n });\n\n return this.resize$;\n }\n\n /**\n * @description Observes the color scheme of the application.\n * @summary\n * This method observes changes in the system's color scheme preference (light or dark)\n * and the presence of the `DARK_PALETTE_CLASS` on the document's root element.\n * Optionally, it can toggle the dark mode class on a specific component.\n *\n * @param {ElementRef | HTMLElement} [component] - Optional component to toggle the dark mode class on.\n * @return {Observable<WindowColorScheme>} An observable that emits the current color scheme (`dark` or `light`).\n * @function colorSchemeObserver\n * @example\n * // Observe the color scheme globally\n * mediaService.colorSchemeObserver().subscribe(scheme => {\n * console.log('Current color scheme:', scheme);\n * });\n *\n * // Observe and toggle dark mode on a specific component\n * const component = document.querySelector('.my-component');\n * mediaService.colorSchemeObserver(component).subscribe();\n */\n colorSchemeObserver(component?: ElementRef | HTMLElement): Observable<WindowColorScheme> {\n const win = this._window;\n const doc = this._document;\n const documentElement = doc.documentElement;\n const mediaFn = win.matchMedia(`(prefers-color-scheme: ${WindowColorSchemes.dark})`);\n\n if(component) {\n this.colorScheme$.subscribe((schema: WindowColorScheme) => {\n this.toggleClass(\n component,\n AngularEngineKeys.DARK_PALETTE_CLASS,\n schema === WindowColorSchemes.dark ? true : false\n );\n });\n }\n\n return merge(\n of(mediaFn.matches ? WindowColorSchemes.dark: WindowColorSchemes.light),\n // observe media query changes\n new Observable<WindowColorScheme>(observer => {\n this.angularZone.runOutsideAngular(() => {\n const mediaQuery = mediaFn;\n const subscription = fromEvent<MediaQueryListEvent>(mediaQuery, 'change')\n .pipe(map(event => (event.matches ? WindowColorSchemes.dark: WindowColorSchemes.light)))\n .subscribe(value => {\n this.angularZone.run(() => observer.next(value));\n });\n return () => subscription.unsubscribe();\n });\n }),\n // observe ngx-dcf-palettedark class changes\n new Observable<WindowColorScheme>(observer => {\n this.angularZone.runOutsideAngular(() => {\n const observerConfig = { attributes: true, attributeFilter: ['class'] };\n const mutationObserver = new MutationObserver(() => {\n const theme = documentElement.classList.contains(AngularEngineKeys.DARK_PALETTE_CLASS) ?\n WindowColorSchemes.dark: WindowColorSchemes.light;\n this.angularZone.run(() => observer.next(theme));\n });\n mutationObserver.observe(documentElement, observerConfig);\n // this.angularZone.run(() => observer.next(theme));\n\n // this.angularZone.run(() => observer.next(theme));\n return () => mutationObserver.disconnect();\n });\n })\n ).pipe(\n distinctUntilChanged(),\n tap(scheme => {\n const shouldAdd = scheme === WindowColorSchemes.dark;\n if (shouldAdd) {\n // always add when the emitted scheme is dark\n this.toggleClass(documentElement, AngularEngineKeys.DARK_PALETTE_CLASS, true);\n } else {\n // remove the class only if the previously stored schema was dark\n if (this.currentSchema === WindowColorSchemes.dark) {\n this.toggleClass(documentElement, AngularEngineKeys.DARK_PALETTE_CLASS, false);\n }\n }\n // store the latest schema value\n this.currentSchema = scheme;\n }),\n takeUntil(this.destroy$),\n shareReplay(1)\n );\n }\n\n /**\n * @description Observes the scroll state of the active page.\n * @summary\n * This method observes the scroll position of the active page's content and emits a boolean\n * indicating whether the scroll position exceeds the specified offset. It waits for a delay\n * before starting the observation to allow page transitions to complete.\n *\n * @param {number} offset - The scroll offset to compare against.\n * @param {number} [awaitDelay=500] - The delay in milliseconds before starting the observation.\n * @return {Observable<boolean>} An observable that emits `true` if the scroll position exceeds the offset, otherwise `false`.\n * @function observePageScroll\n * @example\n * mediaService.observePageScroll(100).subscribe(isScrolled => {\n * console.log('Page scrolled past 100px:', isScrolled);\n * });\n */\n observePageScroll(offset: number, awaitDelay: number = 500): Observable<boolean> {\n // await delay for page change to complete\n return timer(awaitDelay)\n .pipe(\n switchMap(\n () => new Observable<boolean>(observer => {\n const activeContent = this._document.querySelector('ion-router-outlet .ion-page:not(.ion-page-hidden) ion-content') as HTMLIonContentElement;\n if (!(activeContent && typeof (activeContent as HTMLIonContentElement).getScrollElement === 'function'))\n return this.angularZone.run(() => observer.next(false));\n\n (activeContent as HTMLIonContentElement).getScrollElement().then((element: HTMLElement) => {\n const emitScrollState = () => {\n const scrollTop = element.scrollTop || 0;\n this.angularZone.run(() => observer.next(scrollTop > offset));\n };\n element.addEventListener('scroll', emitScrollState);\n emitScrollState();\n return () => element.removeEventListener('scroll', emitScrollState);\n });\n\n })\n ),\n distinctUntilChanged(),\n takeUntil(this.destroy$),\n shareReplay(1)\n );\n }\n\n /**\n * @description Loads an SVG file and injects it into a target element.\n * @summary\n * This method fetches an SVG file from the specified path and injects its content\n * into the provided target element. The operation is performed outside Angular's\n * zone to improve performance, and the DOM update is brought back into the Angular\n * zone to ensure change detection.\n *\n * @param {string} path - The path to the SVG file.\n * @param {HTMLElement} target - The target element to inject the SVG content into.\n * @return {void}\n * @function loadSvgObserver\n * @example\n * const targetElement = document.getElementById('svg-container');\n * mediaService.loadSvgObserver('/assets/icons/icon.svg', targetElement);\n */\n loadSvgObserver(http: HttpClient, path: string, target: HTMLElement): void {\n this.angularZone.runOutsideAngular(() => {\n const svg$ = http.get(path, { responseType: 'text' }).pipe(\n takeUntil(this.destroy$),\n shareReplay(1)\n );\n svg$.subscribe(svg => {\n this.angularZone.run(() => {\n target.innerHTML = svg;\n });\n });\n });\n }\n\n /**\n * @description Determines if the current theme is dark mode.\n * @summary\n * Observes the `colorScheme$` observable and checks if the `DARK_PALETTE_CLASS` is present\n * on the document's root element or if the emitted color scheme is `dark`.\n *\n * @return {Observable<boolean>} An observable that emits `true` if dark mode is active, otherwise `false`.\n * @function isDarkMode\n * @example\n * mediaService.isDarkMode().subscribe(isDark => {\n * console.log('Dark mode active:', isDark);\n * });\n */\n isDarkMode(): Observable<boolean> {\n const documentElement = this._document.documentElement;\n return this.colorScheme$.pipe(\n map(scheme => documentElement.classList.contains(AngularEngineKeys.DARK_PALETTE_CLASS) || scheme === WindowColorSchemes.dark),\n distinctUntilChanged(),\n shareReplay(1),\n takeUntil(this.destroy$)\n );\n }\n\n /**\n * @description Toggles dark mode for a specific component.\n * @summary\n * Subscribes to the `colorScheme$` observable and adds or removes the `DARK_PALETTE_CLASS`\n * on the provided component based on the emitted color scheme.\n *\n * @param {ElementRef | HTMLElement} component - The target component to toggle dark mode on.\n * @return {void}\n * @function setDarkMode\n * @example\n * const component = document.querySelector('.my-component');\n * mediaService.setDarkMode(component);\n */\n setDarkMode(component: ElementRef | HTMLElement): void {\n this.colorScheme$.subscribe((scheme) => {\n this.toggleClass(\n component,\n AngularEngineKeys.DARK_PALETTE_CLASS,\n scheme === WindowColorSchemes.dark ? true : false\n );\n });\n }\n\n /**\n * @description Add or remove a CSS class on one or multiple elements.\n * @summary\n * Accepts an ElementRef, HTMLElement, or array of mixed elements and will add\n * or remove the provided `className` depending on the `add` flag. Operates\n * defensively: resolves ElementRef.nativeElement when needed and ignores\n * falsy entries.\n *\n * @param {(ElementRef | HTMLElement | unknown[])} component - Single element,\n * ElementRef, or array of elements to update.\n * @param {string} className - CSS class name to add or remove.\n * @param {boolean} [add=true] - Whether to add (true) or remove (false) the class.\n * @return {void}\n * @function toggleClass\n * @example\n * // Add a class to a single element\n * mediaService.toggleClass(element, 'active', true);\n *\n * // Remove a class from multiple elements\n * mediaService.toggleClass([element1, element2], 'hidden', false);\n */\n toggleClass(component: ElementRef | HTMLElement | unknown[], className: string, add: boolean = true): void {\n const components = Array.isArray(component) ? component : [component];\n components.forEach(element => {\n if ((element as ElementRef)?.nativeElement)\n element = (element as ElementRef).nativeElement;\n if(element instanceof HTMLElement) {\n switch (add) {\n case true:\n (element as HTMLElement).classList.add(className);\n break;\n case false:\n (element as HTMLElement).classList.remove(className);\n break;\n }\n }\n });\n }\n\n /**\n * @description Clean up internal subscriptions and observers used by the service.\n * @summary\n * Triggers completion of the internal `destroy$` subject so that any\n * Observables created with `takeUntil(this.destroy$)` will complete and\n * resources are released.\n *\n * @return {void}\n * @function destroy\n */\n destroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n}\n","/**\n * @module lib/engine/NgxComponentDirective\n * @description Base decaf component abstraction providing shared inputs and utilities.\n * @summary NgxComponentDirective is the abstract foundation for Decaf components and provides common\n * inputs (model, mapper, pk, props), logging, repository resolution, and event dispatch helpers.\n * It centralizes shared behavior for child components and simplifies integration with the rendering engine.\n * @link {@link NgxComponentDirective}\n */\nimport {\n Directive,\n ElementRef,\n EventEmitter,\n Inject,\n inject,\n Input,\n Output,\n SimpleChanges,\n ViewChild,\n OnChanges,\n ChangeDetectorRef,\n Renderer2,\n OnDestroy,\n} from '@angular/core';\nimport { Router } from '@angular/router';\nimport { Location } from '@angular/common';\nimport { TranslateService } from '@ngx-translate/core';\nimport { firstValueFrom } from 'rxjs';\nimport { Model, ModelConstructor, Primitives } from '@decaf-ts/decorator-validation';\nimport { CrudOperations, InternalError, OperationKeys } from '@decaf-ts/db-decorators';\nimport { LoggedClass, Logger } from '@decaf-ts/logging';\nimport { DecafRepository, FunctionLike, KeyValue } from './types';\nimport { IBaseCustomEvent, ICrudFormEvent, IModelPageCustomEvent } from './interfaces';\nimport { NgxEventHandler } from './NgxEventHandler';\nimport { getLocaleContext } from '../i18n/Loader';\nimport { NgxRenderingEngine } from './NgxRenderingEngine';\nimport { getModelAndRepository, CPTKN } from '../for-angular-common.module';\nimport { AngularEngineKeys, BaseComponentProps } from './constants';\nimport { generateRandomValue, getWindow, setOnWindow } from '../utils';\nimport { EventIds } from '@decaf-ts/core';\nimport { NgxMediaService } from '../services/NgxMediaService';\nimport { DecafComponent, UIFunctionLike, UIKeys } from '@decaf-ts/ui-decorators';\nimport { Constructor } from '@decaf-ts/decoration';\n\ntry {\n const win = getWindow();\n if (!win?.[AngularEngineKeys.LOADED]) new NgxRenderingEngine();\n setOnWindow(AngularEngineKeys.LOADED, true);\n} catch (e: unknown) {\n throw new Error(`Failed to load rendering engine: ${e}`);\n}\n\n/**\n * @description Base directive for Decaf components in Angular applications.\n * @summary Abstract base class that provides common functionality for all Decaf components.\n * This directive establishes a foundation for component development by offering shared inputs\n * (model, mapper, pk, props), logging infrastructure, repository access, event handling, and\n * internationalization support. It implements OnChanges to respond to input property changes\n * and includes utilities for navigation, localization, and dynamic property binding. All Decaf\n * components should extend this directive to inherit its foundational capabilities.\n * @class NgxComponentDirective\n * @extends {LoggedClass}\n * @implements {OnChanges}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n@Directive({host: {'[attr.id]': 'uid'}})\nexport abstract class NgxComponentDirective extends DecafComponent implements OnChanges, OnDestroy {\n\n\n /**\n * @description Reference to the component's native DOM element.\n * @summary Provides direct access to the native DOM element of the component through Angular's\n * ViewChild decorator. This reference can be used to manipulate the DOM element directly,\n * apply custom styles, or access native element properties and methods. The element is\n * identified by the 'component' template reference variable.\n * @type {ElementRef}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @ViewChild('component', { read: ElementRef, static: true })\n component!: ElementRef;\n\n /**\n * @description Flag to enable or disable dark mode support for the component.\n * @summary When enabled, the component will automatically detect the system's dark mode\n * preference using the media service and apply appropriate styling classes. This flag\n * controls whether the component should respond to dark mode changes and apply the\n * dark palette class to its DOM element. By default, dark mode support is disabled.\n * @protected\n * @type {boolean}\n * @default false\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n protected override enableDarkMode: boolean = true;\n\n /**\n * @description Flag to enable or disable dark mode support for the component.\n * @summary When enabled, the component will automatically detect the system's dark mode\n * preference using the media service and apply appropriate styling classes. This flag\n * controls whether the component should respond to dark mode changes and apply the\n * dark palette class to its DOM element. By default, dark mode support is disabled.\n * @protected\n * @type {boolean}\n * @default false\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n protected override isDarkMode: boolean = false;\n\n /**\n * @description Name identifier for the component instance.\n * @summary Provides a string identifier that can be used to name or label the component\n * instance. This name can be used for debugging purposes, logging, or to identify specific\n * component instances within a larger application structure. It serves as a human-readable\n * identifier that helps distinguish between multiple instances of the same component type.\n * @type {string}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override name!: string;\n\n /**\n * @description Parent component identifier for hierarchical component relationships.\n * @summary Specifies the identifier of the parent component in a hierarchical component structure.\n * This property establishes a parent-child relationship between components, allowing for\n * proper nesting and organization of components within a layout. It can be used to track\n * component dependencies and establish component hierarchies for rendering and event propagation.\n * @type {string | undefined}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override childOf!: string | undefined;\n\n /**\n * @description Unique identifier for the component instance.\n * @summary A unique identifier automatically generated for each component instance.\n * This UID is used for DOM element identification, component tracking, and debugging purposes.\n * By default, it generates a random 16-character value, but it can be explicitly set via input.\n * @type {string | number}\n * @default generateRandomValue(16)\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override uid?: string | number;\n\n /**\n * @description Data model or model name for component operations.\n * @summary The data model that this component will use for CRUD operations. This can be provided\n * as a Model instance, a model constructor, or a string representing the model's registered name.\n * When set, this property provides the component with access to the model's schema, validation rules,\n * and metadata needed for rendering and data operations.\n * @type {Model | string | undefined}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override model!: Model | string | undefined;\n\n /**\n * @description Primary key value of the current model instance.\n * @summary Specifies the primary key value for the current model record being displayed or\n * manipulated by the component. This identifier is used for CRUD operations that target\n * specific records, such as read, update, and delete operations. The value corresponds to\n * the field designated as the primary key in the model definition.\n * @type {EventIds}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override modelId?: EventIds;\n\n @Input()\n override value: unknown;\n\n /**\n * @description Primary key field name for the data model.\n * @summary Specifies which field in the model should be used as the primary key.\n * This is typically used for identifying unique records in operations like update and delete.\n * If not explicitly set, it defaults to the repository's configured primary key or 'id'.\n * @type {string}\n * @default 'id'\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override pk!: string;\n\n /**\n * @description Field mapping configuration object or function.\n * @summary Defines how fields from the data model should be mapped to properties used by the component.\n * This allows for flexible data binding between the model and the component's display logic. Can be\n * provided as a static object mapping or as a function for dynamic mapping transformations.\n * @type {Record<string, string> | FunctionLike | Record<string, FunctionLike>}\n * @default {}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n mapper: Record<string, string> | FunctionLike | Record<string, FunctionLike> = {};\n\n /**\n * @description Available CRUD operations for this component instance.\n * @summary Defines which CRUD operations (Create, Read, Update, Delete) are available\n * for this component. This affects which operations can be performed on the data and\n * which operation buttons are displayed in the UI. By default, only READ operations are enabled.\n * @type {CrudOperations[]}\n * @default [OperationKeys.READ]\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n operations: CrudOperations[] = [OperationKeys.READ];\n\n /**\n * @description The CRUD operation type to be performed on the model.\n * @summary Specifies which operation (Create, Read, Update, Delete) this component instance\n * should perform. This determines the UI behavior, form configuration, and available actions.\n * The operation affects form validation, field availability, and the specific repository\n * method called during data submission.\n *\n * @type {OperationKeys}\n * @default OperationKeys.READ\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override operation: OperationKeys | undefined = OperationKeys.READ;\n\n /**\n * @description Row position in a grid-based layout system.\n * @summary Specifies the row position of this component when rendered within a grid-based layout.\n * This property is used for positioning components in multi-row, multi-column layouts and helps\n * establish the component's vertical placement within the grid structure.\n * @type {number}\n * @default 1\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n row: number = 1;\n\n /**\n * @description Column position in a grid-based layout system.\n * @summary Specifies the column position of this component when rendered within a grid-based layout.\n * This property is used for positioning components in multi-row, multi-column layouts and helps\n * establish the component's horizontal placement within the grid structure.\n * @type {number}\n * @default 1\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n col: number = 1;\n\n /**\n * @description Additional CSS class names for component styling.\n * @summary Allows custom CSS classes to be added to the component's root element.\n * These classes are appended to any automatically generated classes based on other\n * component properties. Multiple classes can be provided as a space-separated string.\n * This provides a way to customize the component's appearance beyond the built-in styling options.\n * @type {string}\n * @default \"\"\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n className: string = '';\n\n\n /**\n * @description Angular change detection service for manual change detection control.\n * @summary Injected service that provides manual control over change detection cycles.\n * This is essential for ensuring that programmatic DOM changes (like setting accordion\n * attributes) are properly reflected in the component's state and trigger appropriate\n * view updates when modifications occur outside the normal Angular change detection flow.\n * @protected\n * @type {ChangeDetectorRef}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);\n\n /**\n * @description Media service instance for responsive design and media query management.\n * @summary Provides access to media query functionality for detecting and responding to\n * different screen sizes and device capabilities. This service enables components to adapt\n * their behavior and presentation based on viewport dimensions, orientation, and other\n * media features. It manages media query listeners and provides utilities for responsive\n * component rendering. The service is instantiated per component and should be destroyed\n * via ngOnDestroy to prevent memory leaks.\n * @protected\n * @type {NgxMediaService}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected mediaService: NgxMediaService = inject(NgxMediaService);\n\n /**\n * @description Angular Renderer2 service for platform-agnostic DOM manipulation.\n * @summary Injected service that provides a safe, platform-agnostic way to manipulate DOM elements.\n * This service ensures proper handling of DOM operations across different platforms and environments,\n * including server-side rendering and web workers, without direct DOM access.\n * @protected\n * @type {Renderer2}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected renderer: Renderer2 = inject(Renderer2);\n\n /**\n * @description Translation service for application internationalization.\n * @summary Injected service that provides translation capabilities for UI text.\n * Used to translate button labels, validation messages, and other text content based\n * on the current locale setting, enabling multilingual support throughout the application.\n * @protected\n * @type {TranslateService}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected translateService: TranslateService = inject(TranslateService);\n\n /**\n * @description Event emitter for custom component events.\n * @summary Emits custom events that occur within child components or the component itself.\n * This allows parent components to listen for and respond to user interactions or\n * state changes. Events are passed up the component hierarchy to enable coordinated\n * behavior across the application.\n * @type {EventEmitter<IBaseCustomEvent>}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Output()\n listenEvent: EventEmitter<IBaseCustomEvent> =\n new EventEmitter<IBaseCustomEvent>();\n\n /**\n * @description Event emitter for custom component events.\n * @summary Emits custom events that occur within child components or the component itself.\n * This allows parent components to listen for and respond to user interactions or\n * state changes. Events are passed up the component hierarchy to enable coordinated\n * behavior across the application.\n * @type {EventEmitter<IBaseCustomEvent>}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Output()\n refreshEvent: EventEmitter<IBaseCustomEvent|boolean> = new EventEmitter<IBaseCustomEvent|boolean>();\n\n\n /**\n * @description Angular Router instance for programmatic navigation.\n * @summary Injected Router service used for programmatic navigation between routes\n * in the application. This service enables navigation to different views and operations,\n * handles route parameters, and manages the browser's navigation history.\n * @protected\n * @type {Router}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n override router: Router = inject(Router);\n\n /**\n * @description Current locale identifier for component internationalization.\n * @summary Specifies the locale code (e.g., 'en-US', 'pt-BR') used for translating UI text\n * and formatting data according to regional conventions. This property can be set to override\n * the default application locale for this specific component instance, enabling per-component\n * localization when needed.\n * @type {string | undefined}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override locale?: string;\n\n /**\n * @description Configuration for list item rendering behavior.\n * @summary Defines how list items should be rendered in the component.\n * This property holds a configuration object that specifies the tag name\n * and other properties needed to render list items correctly. The tag property\n * identifies which component should be used to render each item in a list.\n * Additional properties can be included to customize the rendering behavior.\n * @type {Record<string, FieldDefinition>}\n * @default {tag: \"\"}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override item: Record<string, unknown> = { tag: '' };\n\n\n /**\n * @description Dynamic properties configuration for runtime customization.\n * @summary Contains key-value pairs of dynamic properties that can be applied to the component\n * at runtime. This flexible configuration object allows for dynamic property assignment without\n * requiring explicit input bindings for every possible configuration option. Properties from\n * this object are parsed and applied to the component instance through the parseProps method,\n * enabling customizable component behavior based on external configuration.\n * @type {Record<string, unknown>}\n * @default {}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override props: Record<string, unknown> = {};\n\n /**\n * @description Base route path for component navigation.\n * @summary Defines the base route path used for navigation actions related to this component.\n * This is often used as a prefix for constructing navigation URLs when transitioning between\n * different operations or views. The route helps establish the component's position in the\n * application's routing hierarchy.\n * @type {string}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override route?: string = \"\";\n\n /**\n * @description Controls whether borders are displayed around the component.\n * @summary Boolean flag that determines if the component should be visually outlined with borders.\n * When true, borders are shown to visually separate the component from surrounding content.\n *\n * @type {boolean}\n * @default false\n */\n @Input()\n override borders: boolean = false;\n\n /**\n * @description Angular Location service.\n * @summary Injected service that provides direct access to the browser's URL and history.\n * Unlike the Router, Location allows for low-level manipulation of the browser's history stack\n * and URL path, such as programmatically navigating back or forward, or updating the URL without\n * triggering a route change. This is useful for scenarios where you need to interact with the\n * browser history or URL outside of Angular's routing system, such as closing modals, handling\n * popstate events, or supporting custom navigation logic.\n *\n * @private\n * @type {Location}\n */\n protected override location: Location = inject(Location);\n\n /**\n * @description Flag indicating if the component is rendered as a child of a modal dialog.\n * @summary Determines whether this component instance is being displayed within a modal\n * context. This flag affects component behavior such as navigation patterns, event handling,\n * and lifecycle management. When true, the component may use different navigation strategies\n * (e.g., closing the modal instead of browser navigation) and adjust its layout to fit modal\n * constraints. This is typically set by parent modal containers when instantiating child components.\n * @protected\n * @type {boolean}\n * @default false\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n isModalChild: boolean = false;\n\n @Input()\n protected override handlers: Record<string, UIFunctionLike> = {};\n\n @Input()\n protected override events: Record<string, UIFunctionLike> = {};\n\n\n /**\n * @description Indicates whether a refresh operation is in progress.\n * @summary When true, the component is currently fetching new data. This is used\n * to control loading indicators and prevent duplicate refresh operations from\n * being triggered simultaneously.\n *\n * @type {boolean}\n * @default false\n */\n refreshing: boolean = false;\n\n /**\n * @description Constructor for NgxComponentDirective.\n * @summary Initializes the directive by setting up the component name, locale root,\n * and logger. Calls the parent LoggedClass constructor and configures localization\n * context. The component name and locale root can be optionally injected via the\n * CPTKN token, otherwise defaults are used.\n * @param {string} [componentName] - Optional component name for identification and logging\n * @param {string} [localeRoot] - Optional locale root key for internationalization\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n\n // eslint-disable-next-line @angular-eslint/prefer-inject\n constructor(@Inject(CPTKN) componentName?: string, @Inject(CPTKN) localeRoot?: string)\n {\n super();\n this.componentName = componentName || 'NgxComponentDirective';\n this.localeRoot = localeRoot;\n if (!this.localeRoot && this.componentName)\n this.localeRoot = this.componentName;\n if (this.localeRoot)\n this.getLocale(this.localeRoot);\n this.uid = `${this.componentName}-${generateRandomValue(8)}`;\n }\n\n /**\n * @description Cleanup lifecycle hook invoked when the directive is destroyed.\n * @summary Ensures any resources allocated by the directive's media service are\n * released (DOM listeners, timers, subscriptions, etc.). Implementations should\n * keep `mediaService.destroy()` idempotent; calling it here prevents leaks when\n * components are torn down.\n * @returns {void}\n */\n ngOnDestroy(): Promise<void> | void {\n this.mediaService.destroy();\n }\n\n //TODO: Pass to ui decoretators\n async refresh(... args: unknown[]): Promise<void> {\n this.log.for(this.refresh).debug(`Refresh called with args: ${args}`);\n this.refreshEvent.emit(true);\n }\n\n /**\n * @description Getter for the current locale context identifier.\n * @summary Returns the current locale identifier by calling the getLocale method.\n * This property provides convenient access to the component's active locale setting.\n * @returns {string} The current locale identifier\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n get localeContext(): string {\n return this.getLocale();\n }\n\n /**\n * @description Getter for the data repository instance.\n * @summary Lazily initializes and returns the DecafRepository instance for the current model.\n * This getter ensures the repository is created only when needed and reused for subsequent\n * access. It also automatically sets the primary key field if not explicitly configured.\n * @protected\n * @returns {DecafRepository<Model>} The repository instance for the current model\n * @throws {InternalError} If repository initialization fails\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n override get repository(): DecafRepository<Model> | undefined {\n try {\n if (!this._repository) {\n this._repository = getModelAndRepository(this.model as Model)?.repository;\n if (this.model && !this.pk)\n this.pk = Model.pk(this._repository?.class as Constructor<Model>) as string;\n }\n } catch (error: unknown) {\n throw new InternalError((error as Error)?.message || (error as string));\n }\n return this._repository as DecafRepository<Model>;\n }\n\n override set repository(repository: DecafRepository<Model> | undefined) {\n this._repository = repository;\n }\n\n /**\n * @description Angular lifecycle hook for handling input property changes.\n * @summary Responds to changes in component input properties, specifically monitoring changes\n * to the model, locale root, and component name properties. When the model changes, it triggers\n * model initialization and locale context updates. When locale-related properties change,\n * it updates the component's locale setting accordingly.\n * @param {SimpleChanges} changes - Object containing the changed properties with their previous and current values\n * @return {void}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n async ngOnChanges(changes: SimpleChanges): Promise<void> {\n if (changes[BaseComponentProps.MODEL]) {\n const { currentValue } = changes[BaseComponentProps.MODEL];\n if (currentValue) this.getModel(currentValue);\n this.locale = this.localeContext;\n if (!this.initialized) this.initialized = true;\n }\n\n // if (changes[UIKeys.HANDLERS]) {\n // const { currentValue, previousValue } = changes[UIKeys.HANDLERS];\n // if (currentValue && typeof currentValue !== previousValue) {\n // for(const key in currentValue) {\n // const event = currentValue[key]();\n // if (event && typeof event === 'function') {\n // const clazz = new event();\n // this.handlers[key] = clazz[key].bind(this);\n // console.log(this.handlers);\n // }\n // }\n // }\n // }\n\n if (changes[UIKeys.EVENTS]) {\n const { currentValue, previousValue } = changes[UIKeys.EVENTS];\n if (currentValue && currentValue !== previousValue) {\n if(!this._repository)\n this._repository = this.repository;\n for(const key in currentValue) {\n const event = currentValue[key]();\n if (event && typeof event === 'function') {\n try {\n const clazz = new event();\n this.events[key] = clazz[key].bind(this);\n if (event[key] instanceof Promise) {\n await clazz[key].bind(this)();\n } else {\n clazz[key].bind(this)();\n }\n } catch (error: unknown) {\n this.log.for(this.ngOnChanges).warn(`Error occurred while processing event \"${key}\": ${(error as Error)?.message || error as string}`);\n }\n }\n }\n }\n }\n if (changes[BaseComponentProps.LOCALE_ROOT] || changes[BaseComponentProps.COMPONENT_NAME])\n this.locale = this.localeContext;\n\n if (this.enableDarkMode) this.checkDarkMode();\n }\n\n /**\n * @description Translates text phrases using the translation service.\n * @summary Provides a promise-based wrapper around the translation service to translate\n * UI text based on the current locale. Supports both single phrases and arrays of phrases,\n * and accepts optional parameters for template interpolation. When a string parameter is\n * provided, it's automatically converted to an object format for the translation service.\n * @protected\n * @param {string | string[]} phrase - The translation key or array of keys to translate\n * @param {object | string} [params] - Optional parameters for interpolation in translated text\n * @return {Promise<string>} A promise that resolves to the translated text\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected override async translate(phrase: string | string[], params?: object | string): Promise<string> {\n if (typeof params === Primitives.STRING)\n params = {\"0\": params};\n return await firstValueFrom(this.translateService.get(phrase, (params || {}) as object));;\n }\n\n\n protected checkDarkMode(): void {\n this.mediaService.isDarkMode().subscribe((isDark) => {\n this.isDarkMode = isDark;\n this.mediaService.toggleClass(\n [this.component],\n AngularEngineKeys.DARK_PALETTE_CLASS,\n this.isDarkMode\n );\n });\n }\n\n /**\n * @description Retrieves or sets the locale context for the component.\n * @summary Gets the locale identifier from the locale context system. If a locale parameter\n * is provided, it updates the localeRoot property and resolves the new locale context.\n * If no locale is currently set, it initializes it from the localeRoot.\n * @protected\n * @param {string} [locale] - Optional locale identifier to set\n * @return {string} The current locale identifier\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected getLocale(locale?: string): string {\n if (locale || !this.locale) {\n if (locale) this.localeRoot = locale;\n if (this.localeRoot)\n this.locale = getLocaleContext(this.localeRoot as string);\n }\n return this.locale as string;\n }\n\n /**\n * @description Retrieves or generates the route path for the component.\n * @summary Gets the navigation route associated with this component. If no route is explicitly\n * set and a model is available, it automatically generates a route based on the model's\n * class name using the pattern `/model/{ModelName}`. Returns an empty string if neither\n * a route nor a model is available.\n * @return {string} The route path for this component\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n getRoute(): string {\n if (!this.route && this.model instanceof Model)\n this.route = `/model/${this.model?.constructor.name}`;\n return this.route || '';\n }\n\n /**\n * @description Resolves and initializes a model from various input formats.\n * @summary Accepts a model in multiple formats (string name, Model instance, or ModelConstructor)\n * and resolves it to a Model instance. When a string is provided, it looks up the model\n * by name in the Model registry. After resolution, it delegates to setModelDefinitions\n * to complete the model initialization and configuration.\n * @template M - The model type extending from Model\n * @param {string | Model | ModelConstructor<M>} model - The model to resolve and initialize\n * @return {void}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n getModel<M extends Model>(model: string | Model | ModelConstructor<M>): void {\n if (!(model instanceof Model) && typeof model === Primitives.STRING)\n model = Model.get(model as string) as ModelConstructor<M>;\n this.setModelDefinitions(this.model as Model);\n }\n\n /**\n * @description Configures component properties based on model decorators and metadata.\n * @summary Extracts rendering configuration from the model's decorators using the rendering\n * engine. This includes props, item configuration, and child component definitions. It sets\n * up the mapper for field transformations, configures the item renderer with appropriate\n * properties, and establishes the route for navigation. This method bridges the model's\n * decorator metadata with the component's runtime configuration.\n * @param {Model} model - The model instance to extract definitions from\n * @return {void}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n setModelDefinitions(model: Model): void {\n if (model instanceof Model) {\n this.getRoute();\n this.model = model;\n const engine = NgxRenderingEngine.get() as unknown as NgxRenderingEngine\n const field = engine.getDecorators(this.model as Model, {});\n const { props, item, children } = field;\n this.props = Object.assign(\n props || {},\n { children: children || [] },\n this.props\n );\n if (item?.props?.['mapper']) this.mapper = item?.props!['mapper'] || {};\n this.item = {\n tag: item?.tag || '',\n ...item?.props,\n ...(this.mapper ? { mapper: this.mapper } : {}),\n ...{ route: item?.props?.['route'] || this.route },\n } as KeyValue;\n }\n }\n\n /**\n * @description Parses and applies properties from the props object to the component instance.\n * @summary This method iterates through the properties of the provided instance object\n * and applies any matching properties from the component's props configuration to the\n * component instance. This allows for dynamic property assignment based on configuration\n * stored in the props object, enabling flexible component customization without requiring\n * explicit property binding for every possible configuration option.\n * The method performs a safe property assignment by checking if each key from the instance\n * exists in the props object before applying it. This prevents accidental property\n * overwriting and ensures only intended properties are modified.\n * @param {KeyValue} instance - The component instance object to process\n * @param {string[]} [skip=[]] - Array of property names to skip during parsing\n * @return {void}\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant D as NgxComponentDirective\n * participant P as Props Object\n *\n * C->>D: parseProps(instance, skip)\n * D->>D: Get Object.keys(instance)\n * loop For each key in instance\n * D->>D: Check if key in skip array\n * alt Key not in skip\n * D->>P: Check if key exists in this.props\n * alt Key exists in props\n * D->>D: Set this[key] = this.props[key]\n * D->>P: delete this.props[key]\n * else Key not in props\n * Note over D: Skip this key\n * end\n * end\n * end\n * @protected\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected parseProps(instance: KeyValue, skip: string[] = []): void {\n Object.keys(instance).forEach((key) => {\n if (Object.keys(this.props).includes(key) && !skip.includes(key)) {\n (this as KeyValue)[key] = this.props[key];\n delete this.props[key];\n }\n });\n }\n\n /**\n * @description Tracks items in ngFor loops for optimal change detection performance.\n * @summary Provides a tracking function for Angular's *ngFor directive to optimize rendering\n * performance. This method generates unique identifiers for list items based on their index\n * and content, allowing Angular to efficiently track changes and minimize DOM manipulations\n * during list updates. The tracking function is essential for maintaining component state\n * and preventing unnecessary re-rendering of unchanged items.\n * @protected\n * @param {number} index - The index of the item in the list\n * @param {KeyValue | string | number} item - The item data to track\n * @return {string | number} A unique identifier for the item\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n protected trackItemFn(\n index: number,\n item: KeyValue | string | number\n ): string | number {\n return `${index}-${item}`;\n }\n\n /**\n * @description Handles custom events from child components or DOM elements.\n * @summary Processes custom events by extracting event handlers and delegating to appropriate\n * handler classes. Supports both CustomEvent format with detail property and direct event\n * objects. If specific handlers are defined in the event, it instantiates the handler class\n * and invokes its handle method. If no handler is found or defined, the event is emitted\n * up the component hierarchy via the listenEvent output.\n * @param {IBaseCustomEvent | ICrudFormEvent | CustomEvent} event - The event to handle\n * @return {Promise<void>} A promise that resolves when event handling is complete\n * @mermaid\n * sequenceDiagram\n * participant C as Child Component\n * participant D as NgxComponentDirective\n * participant H as Event Handler\n * participant P as Parent Component\n *\n * C->>D: handleEvent(event)\n * alt Event is CustomEvent\n * D->>D: Extract event.detail\n * end\n * D->>D: Get event name and handlers\n * alt Handlers defined\n * alt Handler exists for event\n * D->>H: new Handler(router)\n * D->>H: handle(event)\n * H-->>D: return result\n * else No handler found\n * D->>D: log.debug(\"No handler found\")\n * end\n * else No handlers\n * D->>P: listenEvent.emit(event)\n * end\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n\tasync handleEvent(event: IBaseCustomEvent | ICrudFormEvent | CustomEvent, repository?: DecafRepository<Model>): Promise<void> {\n let name = \"\";\n const log = this.log.for(this.handleEvent);\n if (event instanceof CustomEvent) {\n if (!event.detail) return log.debug(`No handler for event ${name}`);\n name = event.detail?.name;\n event = event.detail;\n }\n const handlers = (event as ICrudFormEvent)?.['handlers'] as\n | Record<string, NgxEventHandler>\n | undefined;\n name = name || (event as IBaseCustomEvent)?.['name'];\n if (handlers && Object.keys(handlers || {})?.length) {\n if (!handlers[name])\n return log.debug(`No handler found for event ${name}`);\n try {\n const clazz = new (handlers as KeyValue)[name]();\n const handler = clazz.handle.bind(this);\n //const clazz = new event();\n // this.events[key] = clazz[key].bind(this);\n\n const result = handler(event);\n return (result instanceof Promise) ?\n await result : result;\n } catch (e: unknown) {\n log.error(`Failed to handle ${name} event`, e as Error);\n }\n }\n this.listenEvent.emit(event as IBaseCustomEvent | ICrudFormEvent);\n }\n\n\n // passed for ui decorators\n // async submit(...args: unknown[]): Promise<any> {\n // this.log.for(this.submit).info(`submit for ${this.componentName} with ${JSON.stringify(args)}`);\n // }\n\n /**\n * @description Determines if a specific operation is allowed in the current context.\n * @summary This method checks if an operation is included in the list of available\n * CRUD operations and if it's not the current operation (unless the current operation\n * is CREATE). This is used to enable/disable or show/hide operation buttons in the UI.\n * Returns false if the operations array is undefined or the operation is not in the list.\n * @param {string} operation - The operation to check\n * @return {boolean} True if the operation is allowed, false otherwise\n * @mermaid\n * sequenceDiagram\n * participant D as NgxComponentDirective\n * participant U as UI\n *\n * U->>D: isAllowed(operation)\n * alt operations is undefined\n * D-->>U: Return false\n * else\n * D->>D: Check if operation is in operations\n * D->>D: Check if operation is not current operation\n * D-->>U: Return result\n * end\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n isAllowed(operation: string): boolean {\n if (!this.operations) return false;\n return (\n this.operations.includes(operation as CrudOperations) &&\n this.operation !== OperationKeys.CREATE &&\n ((this.operation || '').toLowerCase() !== operation || !this.operation)\n );\n }\n\n /**\n * @description Navigates to a different operation for the current model.\n * @summary This method constructs a navigation URL based on the component's base route,\n * the requested operation, and optionally a model ID. It then uses the Angular router\n * service to navigate to the constructed URL. This is typically used when switching\n * between different CRUD operations (create, read, update, delete) on a model.\n * The URL format is: {route}/{operation}/{id?}\n * @param {string} operation - The operation to navigate to (e.g., 'create', 'read', 'update', 'delete')\n * @param {string} [id] - Optional model ID to include in the navigation URL\n * @return {Promise<boolean>} A promise that resolves to true if navigation was successful\n * @mermaid\n * sequenceDiagram\n * participant U as UI\n * participant D as NgxComponentDirective\n * participant R as Router\n *\n * U->>D: Click operation button\n * D->>D: changeOperation(operation, id)\n * D->>D: Construct navigation URL\n * Note over D: URL: {route}/{operation}/{id?}\n * D->>R: navigateByUrl(page)\n * R->>R: Navigate to new route\n * R-->>D: Return navigation result\n * D-->>U: Display new operation view\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n async changeOperation(operation: string, id?: string): Promise<boolean> {\n let page = `${this.route}/${operation}/`.replace('//', '/');\n if (!id) id = this.modelId as string;\n if (this.modelId) page = `${page}${this.modelId || id}`;\n return this.router.navigateByUrl(page);\n }\n}\n","import {\n Directive,\n ElementRef,\n EnvironmentInjector,\n EventEmitter,\n inject,\n Input,\n OnChanges,\n OnDestroy,\n TemplateRef,\n Type,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n IRenderedModel,\n AngularDynamicOutput,\n IBaseCustomEvent\n} from './interfaces';\nimport { FormParent, KeyValue } from './types';\nimport { NgxRenderingEngine } from './NgxRenderingEngine';\n\nimport { NgxComponentDirective } from './NgxComponentDirective';\n\n@Directive()\nexport class NgxRenderableComponentDirective extends NgxComponentDirective\n implements OnChanges, OnDestroy, IRenderedModel {\n\n /**\n * @description Injector used for dependency injection in the dynamic component.\n * @summary This injector is used when creating the dynamic component to provide it with\n * access to the application's dependency injection system. It ensures that the dynamically\n * created component can access the same services and dependencies as statically created\n * components.\n *\n * @type {EnvironmentInjector}\n * @memberOf NgxRenderableComponentDirective\n */\n protected injector: EnvironmentInjector = inject(EnvironmentInjector);\n\n\n /**\n * @description Reference to the container where the dynamic component will be rendered.\n * @summary This ViewContainerRef provides the container where the dynamically created\n * component will be inserted into the DOM. It's marked as static to ensure it's available\n * during the ngOnInit lifecycle hook when the component is created.\n *\n * @type {ViewContainerRef}\n * @memberOf NgxRenderableComponentDirective\n */\n\n @ViewChild('componentOuter', { static: true, read: ViewContainerRef })\n protected vcr!: ViewContainerRef;\n\n @ViewChild('componentInner', { read: TemplateRef, static: true })\n inner?: TemplateRef<unknown>;\n\n /**\n * @description Global properties to pass to the rendered component.\n * @summary This input property allows passing a set of properties to the dynamically\n * rendered component. These properties will be mapped to the component's inputs if they\n * match. Properties that don't match any input on the target component will be filtered out\n * with a warning.\n *\n * @type {Record<string, unknown>}\n * @default {}\n * @memberOf NgxComponentDirective\n */\n @Input()\n globals: Record<string, unknown> = {};\n\n /**\n * @description Repository model for data operations.\n * @summary The data model repository that this component will use for CRUD operations.\n * This provides a connection to the data layer for retrieving and manipulating data.\n *\n * @type {Model| undefined}\n * @memberOf NgxComponentDirective\n */\n @Input()\n parentForm!: FormParent | ElementRef<unknown> | undefined;\n\n\n @Input()\n projectable: boolean = true;\n\n\n @Input()\n rendererId?: string;\n\n protected output?: AngularDynamicOutput;\n\n protected instance!: KeyValue | undefined;\n\n protected readonly JSON = JSON;\n\n // @Output()\n // listenEvent: EventEmitter<IBaseCustomEvent> =\n // new EventEmitter<IBaseCustomEvent>();\n\n /**\n * @description Cleans up resources when the component is destroyed.\n * @summary Performs cleanup operations when the component is being destroyed by Angular.\n * This includes unsubscribing from all event emitters of the dynamic component and\n * destroying the rendering engine instance to prevent memory leaks.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant C as ComponentRendererComponent\n * participant R as NgxRenderingEngine\n *\n * A->>C: ngOnDestroy()\n * alt component exists\n * C->>C: unsubscribeEvents()\n * C->>R: destroy()\n * end\n *\n * @return {Promise<void>} A promise that resolves when cleanup is complete\n * @memberOf NgxComponentDirective\n */\n override async ngOnDestroy(): Promise<void> {\n super.ngOnDestroy();\n if (this.instance) {\n this.unsubscribeEvents();\n await NgxRenderingEngine.destroy();\n }\n this.output = undefined;\n }\n\n\n /**\n * @description Subscribes to events emitted by the dynamic component.\n * @summary This method sets up subscriptions to all EventEmitter properties of the\n * dynamically created component. When an event is emitted by the dynamic component,\n * it is captured and re-emitted through the listenEvent output property with additional\n * metadata about the event source.\n *\n * @mermaid\n * sequenceDiagram\n * participant C as ComponentRendererComponent\n * participant D as Dynamic Component\n * participant P as Parent Component\n *\n * C->>C: subscribeEvents()\n * C->>D: Get instance properties\n * loop For each property\n * C->>C: Check if property is EventEmitter\n * alt is EventEmitter\n * C->>D: Subscribe to event\n * D-->>C: Event emitted\n * C->>P: Re-emit event with metadata\n * end\n * end\n *\n * @private\n * @return {void}\n * @memberOf NgxComponentDirective\n */\n protected async subscribeEvents(component?: Type<unknown>): Promise<void> {\n if(!component)\n component = this?.output?.component;\n if(!this.instance && component)\n this.instance = component;\n if (this.instance && component) {\n const componentKeys = Object.keys(this.instance);\n for (const key of componentKeys) {\n const value = this.instance[key];\n if (value instanceof EventEmitter)\n (this.instance as KeyValue)[key].subscribe(async (event: Partial<IBaseCustomEvent>) => {\n await this.handleEvent({\n component: component.name || '',\n name: key,\n ...event,\n } as IBaseCustomEvent);\n });\n }\n }\n }\n\n\n /**\n * @description Unsubscribes from all events of the dynamic component.\n * @summary This method cleans up event subscriptions when the component is being destroyed.\n * It iterates through all properties of the dynamic component instance and unsubscribes\n * from any EventEmitter properties to prevent memory leaks and unexpected behavior after\n * the component is destroyed.\n *\n * @mermaid\n * sequenceDiagram\n * participant C as ComponentRendererComponent\n * participant D as Dynamic Component\n *\n * C->>C: unsubscribeEvents()\n * C->>D: Get instance properties\n * loop For each property\n * C->>C: Check if property is EventEmitter\n * alt is EventEmitter\n * C->>D: Unsubscribe from event\n * end\n * end\n *\n * @private\n * @return {void}\n * @memberOf NgxComponentDirective\n */\n protected unsubscribeEvents(): void {\n if (this.instance) {\n const componentKeys = Object.keys(this.instance);\n for (const key of componentKeys) {\n const value = this.instance[key];\n if (value instanceof EventEmitter)\n this.instance[key].unsubscribe();\n }\n }\n }\n}\n","import {\n Component,\n ComponentMirror,\n Injector,\n Input,\n OnDestroy,\n OnInit,\n reflectComponentType,\n TemplateRef,\n Type\n} from '@angular/core';\n/**\n * @module module:lib/components/component-renderer/component-renderer.component\n * @description Component renderer module.\n * @summary Provides `ComponentRendererComponent` which renders dynamic child\n * components based on configuration or data. Useful for rendering custom\n * fields, nested components or templated content at runtime.\n *\n * @link {@link ComponentRendererComponent}\n */\nimport { NgComponentOutlet } from '@angular/common';\n\nimport { NgxRenderingEngine } from '../../engine/NgxRenderingEngine';\nimport { KeyValue } from '../../engine/types';\nimport { AngularEngineKeys, BaseComponentProps } from '../../engine/constants';\nimport { NgxRenderableComponentDirective } from '../../engine/NgxRenderableComponentDirective';\n\n/**\n * @description Dynamic component renderer for Decaf Angular applications.\n * @summary This component provides a flexible way to dynamically render Angular components\n * at runtime based on a tag name. It handles the creation, property binding, and event\n * subscription for dynamically loaded components. This is particularly useful for\n * building configurable UIs where components need to be determined at runtime.\n *\n * @component {ComponentRendererComponent}\n * @example\n * <ngx-decaf-component-renderer\n * [tag]=\"tag\"\n * [globals]=\"globals\"\n * (listenEvent)=\"listenEvent($event)\">\n * </ngx-decaf-component-renderer>\n *\n * @mermaid\n * classDiagram\n * class ComponentRendererComponent {\n * +ViewContainerRef vcr\n * +string tag\n * +Record~string, unknown~ globals\n * +EnvironmentInjector injector\n * +ComponentRef~unknown~ component\n * +EventEmitter~IBaseCustomEvent~ listenEvent\n * +ngOnInit()\n * +ngOnDestroy()\n * +ngOnChanges(changes)\n * -createComponent(tag, globals)\n * -subscribeEvents()\n * -unsubscribeEvents()\n * }\n * ComponentRendererComponent --|> OnInit\n * ComponentRendererComponent --|> OnChanges\n * ComponentRendererComponent --|> OnDestroy\n *\n * @implements {OnInit}\n * @implements {OnChanges}\n * @implements {OnDestroy}\n */\n@Component({\n selector: 'ngx-decaf-component-renderer',\n templateUrl: './component-renderer.component.html',\n styleUrls: ['./component-renderer.component.scss'],\n imports: [NgComponentOutlet],\n standalone: true,\n host: {'[attr.id]': 'uid'},\n})\nexport class ComponentRendererComponent extends NgxRenderableComponentDirective implements OnInit, OnDestroy {\n\n /**\n * @description The tag name of the component to be dynamically rendered.\n * @summary This input property specifies which component should be rendered by providing\n * its registered tag name. The tag must correspond to a component that has been registered\n * with the NgxRenderingEngine. This is a required input as it determines which component\n * to create.\n *\n * @type {string}\n * @required\n * @memberOf ComponentRendererComponent\n */\n @Input({ required: true })\n tag!: string;\n\n @Input()\n children: KeyValue[] = [];\n\n @Input()\n override projectable: boolean = true;\n\n @Input()\n parent: undefined | KeyValue = undefined;\n\n\n /**\n * @description Initializes the component after Angular first displays the data-bound properties.\n * @summary Sets up the component by creating the dynamic component specified by the tag input.\n * This method is called once when the component is initialized and triggers the dynamic\n * component creation process with the provided tag name and global properties.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant C as ComponentRendererComponent\n * participant R as NgxRenderingEngine\n *\n * A->>C: ngOnInit()\n * C->>C: createComponent(tag, globals)\n * C->>R: components(tag)\n * R-->>C: Return component constructor\n * C->>C: Process component inputs\n * C->>C: Create component instance\n * C->>C: subscribeEvents()\n *\n * @return {void}\n * @memberOf ComponentRendererComponent\n */\n ngOnInit(): void {\n if (!this.parent) {\n this.createComponent(this.tag, this.globals);\n } else {\n this.createParentComponent();\n }\n }\n\n /**\n * @description Creates and renders a dynamic component.\n * @summary This method handles the creation of a dynamic component based on the provided tag.\n * It retrieves the component constructor from the rendering engine, processes its inputs,\n * filters out unmapped properties, creates the component instance, and sets up event subscriptions.\n *\n * @param {string} tag - The tag name of the component to create\n * @param {KeyValue} globals - Global properties to pass to the component\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant C as ComponentRendererComponent\n * participant R as NgxRenderingEngine\n * participant V as ViewContainerRef\n *\n * C->>R: components(tag)\n * R-->>C: Return component constructor\n * C->>C: reflectComponentType(component)\n * C->>C: Process input properties\n * C->>C: Filter unmapped properties\n * C->>V: clear()\n * C->>R: createComponent(component, props, metadata, vcr, injector, [])\n * R-->>C: Return component reference\n * C->>C: subscribeEvents()\n *\n * @private\n * @memberOf ComponentRendererComponent\n */\n private createComponent(tag: string, globals: KeyValue = {}): void {\n const component = NgxRenderingEngine.components(tag)\n ?.constructor as Type<unknown>;\n const metadata = reflectComponentType(component);\n const componentInputs = (metadata as ComponentMirror<unknown>).inputs;\n const props = globals?.['item'] || globals?.['props'] || {};\n if (props?.['tag'])\n delete props['tag'];\n if (props?.[AngularEngineKeys.CHILDREN] && !this.children.length)\n this.children = props[AngularEngineKeys.CHILDREN] as KeyValue[];\n props[AngularEngineKeys.CHILDREN] = this.children || [];\n const inputKeys = Object.keys(props);\n const unmappedKeys: string[] = [];\n\n for (const input of inputKeys) {\n if (!inputKeys.length) break;\n const prop = componentInputs.find(\n (item: { propName: string }) => item.propName === input,\n );\n if (!prop) {\n delete props[input];\n unmappedKeys.push(input);\n }\n }\n\n function hasProperty(key: string): boolean {\n return Object.values(componentInputs).some(({propName}) => propName === key);\n }\n\n const hasChildrenInput = hasProperty(AngularEngineKeys.CHILDREN);\n if (!this.projectable && hasChildrenInput)\n props[AngularEngineKeys.CHILDREN] = this.children;\n\n const hasRootForm = hasProperty(BaseComponentProps.PARENT_FORM);\n if (hasRootForm && this.parentForm)\n props[BaseComponentProps.PARENT_FORM] = this.parentForm;\n\n props['className'] = (props['className'] ?\n props['className'] + ' ' + this.className : this.className || \"\");\n\n this.vcr.clear();\n // const projectable = (this.children?.length && this.projectable);\n // const template = projectable ? this.vcr.createEmbeddedView(this.inner as TemplateRef<unknown>, this.injector).rootNodes : [];\n this.instance = NgxRenderingEngine.createComponent(\n component,\n props,\n this.injector as Injector,\n metadata as ComponentMirror<unknown>,\n this.vcr,\n [],\n );\n this.subscribeEvents(component);\n }\n\n private createParentComponent() {\n const { component, inputs } = this.parent as KeyValue;\n const metadata = reflectComponentType(component) as ComponentMirror<unknown>;\n const template = this.projectable ? this.vcr.createEmbeddedView(this.inner as TemplateRef<unknown>, this.injector).rootNodes : [];\n this.instance = NgxRenderingEngine.createComponent(\n component,\n inputs,\n this.injector,\n metadata,\n this.vcr,\n template,\n );\n this.subscribeEvents(component);\n }\n}\n","<!-- Keep to avoid id conflicts -->\n\n<ng-template #componentOuter></ng-template>\n\n<ng-template #componentInner>\n @if (parent?.children?.length) {\n @for(child of parent.children; track child) {\n @if (!child.children?.length) {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n } @else {\n <ngx-decaf-component-renderer [parent]=\"child\"> </ngx-decaf-component-renderer>\n }\n }\n }\n @if (projectable) {\n @if (children?.length) {\n @for(child of children; track child) {\n @if (child.children?.length) {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n } @else {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n }\n }\n\n</ng-template>\n\n","/**\n * @module lib/engine/NgxFormFieldDirective\n * @description Base directive for CRUD form fields in Decaf Angular applications.\n * @summary Provides the NgxFormFieldDirective abstract class that implements ControlValueAccessor\n * and FieldProperties to enable form field integration with Angular's reactive forms system.\n * This directive handles form control lifecycle, validation, multi-entry forms, and CRUD operations.\n */\nimport { CrudOperationKeys, FieldProperties, RenderingError } from '@decaf-ts/ui-decorators';\nimport { FormParent, KeyValue, PossibleInputTypes } from './types';\nimport { CrudOperations, InternalError, OperationKeys } from '@decaf-ts/db-decorators';\nimport { ControlValueAccessor, FormArray, FormControl, FormGroup } from '@angular/forms';\nimport { Directive, Inject, Input, OnChanges, SimpleChanges } from '@angular/core';\nimport { NgxFormService } from '../services/NgxFormService';\nimport { sf } from '@decaf-ts/decorator-validation';\nimport { ComponentEventNames } from './constants';\nimport { FunctionLike } from './types';\nimport { NgxComponentDirective } from './NgxComponentDirective';\nimport { CPTKN } from '../for-angular-common.module';\n\n/**\n * @description Abstract base directive for CRUD form fields in Angular applications.\n * @summary Provides the foundation for all form field components in Decaf applications by implementing\n * Angular's ControlValueAccessor interface and FieldProperties for validation. This directive manages\n * form control integration, validation state, multi-entry forms (FormArrays), and CRUD operation context.\n * It handles form group lifecycle, error messaging, change detection, and parent-child form relationships.\n * Extend this class to create custom form field components that seamlessly integrate with Angular's\n * reactive forms and Decaf's validation system.\n * @class NgxFormFieldDirective\n * @extends {NgxComponentDirective}\n * @implements {ControlValueAccessor}\n * @implements {FieldProperties}\n * @example\n * ```typescript\n * @Component({\n * selector: 'app-text-field',\n * templateUrl: './text-field.component.html',\n * providers: [{\n * provide: NG_VALUE_ACCESSOR,\n * useExisting: forwardRef(() => TextFieldComponent),\n * multi: true\n * }]\n * })\n * export class TextFieldComponent extends NgxFormFieldDirective {\n * constructor() {\n * super();\n * }\n * }\n * ```\n */\n@Directive()\nexport abstract class NgxFormFieldDirective extends NgxComponentDirective implements OnChanges, ControlValueAccessor, FieldProperties {\n\n /**\n * @description Index of the currently active form group in a form array.\n * @summary When working with multiple form groups (form arrays), this indicates\n * which form group is currently active or being edited. This is used to manage\n * focus and data binding in multi-entry scenarios.\n * @type {number}\n * @default 0\n * @public\n */\n @Input()\n activeFormGroupIndex: number = 0;\n\n\n @Input({ required: true })\n override operation: CrudOperations = OperationKeys.CREATE;\n\n /**\n * @description Parent form container for this field.\n * @summary Reference to the parent FormGroup or FormArray that contains this field.\n * When this field is part of a multi-entry structure, this contains the FormArray\n * with all form groups. This enables management of multiple instances of the same\n * field structure within a single form.\n * @type {FormParent}\n * @public\n */\n @Input()\n parentForm!: FormParent;\n\n /**\n * @description Field mapping configuration for options.\n * @summary Defines how fields from the data model should be mapped to properties used by the component.\n * This allows for flexible data binding between the model and the component's display logic.\n * Can be either a key-value mapping object or a function that performs the mapping.\n * @type {KeyValue | FunctionLike}\n * @public\n */\n @Input()\n optionsMapper: KeyValue | FunctionLike = {};\n\n /**\n * @description Angular FormGroup instance for the field.\n * @summary The FormGroup that contains this field's FormControl. Used for managing\n * the field's validation state and value within the reactive forms structure.\n * @type {FormGroup | undefined}\n * @public\n */\n formGroup!: FormGroup | undefined;\n\n /**\n * @description Angular FormControl instance for this field.\n * @summary The FormControl that manages this field's value, validation state, and user interactions.\n * @type {FormControl}\n * @public\n */\n formControl!: FormControl;\n\n /**\n * @description Dot-separated path to this field in the form structure.\n * @summary Used to locate this field within nested form structures.\n * @type {string}\n * @public\n */\n path!: string;\n\n /**\n * @description The input type of this field.\n * @summary Determines the HTML input type or component type to render.\n * @type {PossibleInputTypes}\n * @public\n */\n type!: PossibleInputTypes ;\n\n /**\n * @description Whether the field is disabled.\n * @summary When true, the field cannot be edited by the user.\n * @type {boolean}\n * @public\n */\n disabled?: boolean;\n\n /**\n * @description Page number for multi-page forms.\n * @summary Indicates which page this field belongs to in a multi-page form structure.\n * @type {number}\n * @public\n */\n page!: number;\n\n // Validation properties\n\n /**\n * @description Date/time format string for parsing and display.\n * @type {string}\n * @public\n */\n format?: string;\n\n /**\n * @description Controls field visibility based on CRUD operations.\n * @summary Can be a boolean or an array of operation keys where the field should be hidden.\n * @type {boolean | CrudOperationKeys[]}\n * @public\n */\n hidden?: boolean | CrudOperationKeys[];\n\n /**\n * @description Maximum value or date allowed.\n * @type {number | Date}\n * @public\n */\n max?: number | Date;\n\n /**\n * @description Maximum length for text input.\n * @type {number}\n * @public\n */\n maxlength?: number;\n\n /**\n * @description Minimum value or date allowed.\n * @type {number | Date}\n * @public\n */\n min?: number | Date;\n\n /**\n * @description Minimum length for text input.\n * @type {number}\n * @public\n */\n minlength?: number;\n\n /**\n * @description Regex pattern for validation.\n * @type {string | undefined}\n * @public\n */\n pattern?: string | undefined;\n\n /**\n * @description Whether the field is read-only.\n * @type {boolean}\n * @public\n */\n readonly?: boolean;\n\n /**\n * @description Whether the field is required.\n * @type {boolean}\n * @public\n */\n required?: boolean;\n\n /**\n * @description Step value for numeric inputs.\n * @type {number}\n * @public\n */\n step?: number;\n\n /**\n * @description Field name that this field's value must equal.\n * @type {string}\n * @public\n */\n equals?: string;\n\n /**\n * @description Field name that this field's value must differ from.\n * @type {string}\n * @public\n */\n different?: string;\n\n /**\n * @description Field name that this field's value must be less than.\n * @type {string}\n * @public\n */\n lessThan?: string;\n\n /**\n * @description Field name that this field's value must be less than or equal to.\n * @type {string}\n * @public\n */\n lessThanOrEqual?: string;\n\n /**\n * @description Field name that this field's value must be greater than.\n * @type {string}\n * @public\n */\n greaterThan?: string;\n\n /**\n * @description Field name that this field's value must be greater than or equal to.\n * @type {string}\n * @public\n */\n greaterThanOrEqual?: string;\n\n /**\n * @description Current value of the field.\n * @summary Can be a string, number, date, or array of strings for multi-select fields.\n * @type {string | number | Date | string[]}\n * @public\n */\n override value!: string | number | Date | string[];\n\n /**\n * @description Whether the field supports multiple values.\n * @summary When true, the field is rendered as part of a FormArray structure.\n * @type {boolean}\n * @public\n */\n multiple!: boolean;\n\n /**\n * @description Flag tracking if validation error event has been dispatched.\n * @summary Prevents duplicate validation error events from being dispatched.\n * @type {boolean}\n * @private\n */\n private validationErrorEventDispatched: boolean = false;\n\n /**\n * @description Reference to the parent HTML element.\n * @summary Used for DOM manipulation and event handling.\n * @type {HTMLElement}\n * @protected\n */\n protected parent?: HTMLElement;\n\n // eslint-disable-next-line @angular-eslint/prefer-inject\n constructor(@Inject(CPTKN) componentName: string = \"ComponentCrudField\") {\n super(componentName);\n }\n\n\n /**\n * @description Gets the currently active form group based on context.\n * @summary Returns the appropriate FormGroup based on whether this field supports\n * multiple values. For single-value fields, returns the main form group.\n * For multi-value fields, returns the form group at the active index from the parent FormArray.\n * If no formGroup is set, returns the parent of the formControl.\n * @return {FormGroup} The currently active FormGroup for this field\n * @public\n */\n get activeFormGroup(): FormGroup {\n if (!this.formGroup)\n return this.formControl.parent as FormGroup;\n\n if (this.multiple) {\n if (this.formGroup instanceof FormArray)\n return this.formGroup.at(this.activeFormGroupIndex) as FormGroup;\n return this.formGroup;\n }\n\n return this.formGroup as FormGroup;\n }\n\n /**\n * @description String formatting utility function.\n * @summary Provides access to the sf (string format) function for formatting error messages\n * and other string templates. Used primarily for localizing and parameterizing validation messages.\n * @type {function(string, ...string): string}\n * @public\n */\n sf = sf;\n\n /**\n * @description Callback function invoked when the field value changes.\n * @summary Function registered by Angular's forms system through registerOnChange.\n * Called automatically when the field's value is updated to notify the form of the change.\n * @type {function(): unknown}\n * @public\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: () => unknown = () => {};\n\n /**\n * @description Callback function invoked when the field is touched.\n * @summary Function registered by Angular's forms system through registerOnTouched.\n * Called when the field is blurred or otherwise marked as touched.\n * @type {function(): unknown}\n * @public\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onTouch: () => unknown = () => {};\n\n /**\n * @description Writes a value to the form field.\n * @summary Part of Angular's ControlValueAccessor interface. Sets the field's value\n * when the form programmatically updates it. This is called by Angular forms when\n * the model value changes.\n * @param {string} obj - The value to be set\n * @return {void}\n * @public\n */\n writeValue(obj: string): void {\n this.value = obj;\n }\n\n /**\n * @description Registers the onChange callback function.\n * @summary Part of Angular's ControlValueAccessor interface. Stores the function\n * that Angular forms provides to be called when the field value changes.\n * @param {function(): unknown} fn - The function to be called on change\n * @return {void}\n * @public\n */\n registerOnChange(fn: () => unknown): void {\n this.onChange = fn;\n }\n\n /**\n * @description Registers the onTouched callback function.\n * @summary Part of Angular's ControlValueAccessor interface. Stores the function\n * that Angular forms provides to be called when the field is touched/blurred.\n * @param {function(): unknown} fn - The function to be called on touch\n * @return {void}\n * @public\n */\n registerOnTouched(fn: () => unknown): void {\n this.onTouch = fn;\n }\n\n /**\n * @description Sets the disabled state of the field.\n * @summary Part of Angular's ControlValueAccessor interface. Called by Angular forms\n * when the disabled state of the control changes.\n * @param {boolean} isDisabled - Whether the field should be disabled\n * @return {void}\n * @public\n */\n setDisabledState?(isDisabled: boolean): void {\n this.disabled = isDisabled;\n }\n\n /**\n * @description Performs setup after the view has been initialized.\n * @summary Retrieves and returns the parent HTML element based on the current CRUD operation.\n * For READ and DELETE operations, returns the immediate parent element. For CREATE and UPDATE\n * operations, finds the parent div element and registers it with the form service.\n * @return {HTMLElement} The parent element of the field\n * @throws {RenderingError} If unable to retrieve parent form element for CREATE/UPDATE operations\n * @throws {InternalError} If the operation is invalid\n * @public\n */\n afterViewInit(): HTMLElement {\n this.checkDarkMode();\n let parent: HTMLElement;\n if (this.component?.nativeElement)\n this.isModalChild = this.component.nativeElement.closest('ion-modal') ? true : false;\n switch (this.operation) {\n case OperationKeys.READ:\n case OperationKeys.DELETE:\n return this.component.nativeElement.parentElement;\n case OperationKeys.CREATE:\n case OperationKeys.UPDATE:\n try {\n parent = NgxFormService.getParentEl(this.component.nativeElement, 'div');\n } catch (e: unknown) {\n throw new RenderingError(`Unable to retrieve parent form element for the ${this.operation}: ${e instanceof Error ? e.message : e}`);\n }\n // NgxFormService.register(parent.id, this.formGroup, this as AngularFieldDefinition);\n return parent;\n default:\n throw new InternalError(`Invalid operation: ${this.operation}`);\n }\n }\n\n /**\n * @description Angular lifecycle hook for detecting input property changes.\n * @summary Overrides the parent ngOnChanges to handle changes to activeFormGroupIndex and value.\n * When activeFormGroupIndex changes in a multiple field scenario, updates the active form group\n * and form control. When value changes, updates the form control value. Delegates to parent\n * implementation for initial change detection.\n * @param {SimpleChanges} changes - Object containing the changed properties\n * @return {void}\n * @public\n */\n override async ngOnChanges(changes: SimpleChanges): Promise<void> {\n if (!this.initialized)\n await super.ngOnChanges(changes);\n if (changes['activeFormGroupIndex'] && this.multiple &&\n !changes['activeFormGroupIndex'].isFirstChange() && changes['activeFormGroupIndex'].currentValue !== this.activeFormGroupIndex) {\n\n this.activeFormGroupIndex = changes['activeFormGroupIndex'].currentValue;\n this.formGroup = this.activeFormGroup;\n this.formControl = this.formGroup.get(this.name) as FormControl;\n }\n if (changes['value'] && !changes['value'].isFirstChange()\n && (changes['value'].currentValue !== undefined && changes['value'].currentValue !== this.value))\n this.setValue(changes['value'].currentValue);\n }\n\n /**\n * @description Cleanup logic when the component is destroyed.\n * @summary Unregisters the form group from the form service to prevent memory leaks\n * and clean up form references.\n * @return {void}\n * @public\n */\n onDestroy(): void {\n if (this.formGroup)\n NgxFormService.unregister(this.formGroup);\n }\n\n /**\n * @description Sets the value of the form control.\n * @summary Updates the form control's value and triggers validation. This is used\n * when the value needs to be programmatically updated from outside the form control.\n * @param {unknown} value - The value to set\n * @return {void}\n * @public\n */\n setValue(value: unknown): void {\n this.formControl.setValue(value);\n this.formControl.updateValueAndValidity();\n }\n\n handleModalChildChanges() {\n if (this.isModalChild)\n this.changeDetectorRef.detectChanges();\n }\n\n /**\n * @description Retrieves validation error messages for the field.\n * @summary Checks the form control for validation errors and returns formatted error messages.\n * If errors exist, dispatches a validation error event to parent accordion components.\n * Error messages are translated and formatted with relevant field properties.\n * @param {HTMLElement} parent - The parent HTML element used to find accordion components\n * @return {string | void} Formatted error message string, or void if no errors\n * @public\n */\n getErrors(parent: HTMLElement): string | void {\n const formControl = this.formControl;\n if (formControl) {\n const accordionComponent = parent.closest('ngx-decaf-fieldset')?.querySelector('ion-accordion-group');\n if ((!formControl.pristine || formControl.touched) && !formControl.valid) {\n const errors: Record<string, string>[] = Object.keys(formControl.errors ?? {}).map(key => ({\n key: key,\n message: key,\n }));\n if (errors.length) {\n if (accordionComponent && !this.validationErrorEventDispatched) {\n const validationErrorEvent = new CustomEvent(ComponentEventNames.VALIDATION_ERROR, {\n detail: {fieldName: this.name, hasErrors: true},\n bubbles: true\n });\n accordionComponent.dispatchEvent(validationErrorEvent);\n this.validationErrorEventDispatched = true;\n }\n }\n for(const error of errors) {\n const instance = this as KeyValue;\n return `* ${ this.translateService.instant(`errors.${error?.['message']}`, {\"0\": `${instance[error?.['key']] ?? \"\"}`})}`;\n }\n\n }\n }\n }\n}\n","import { apply, metadata } from '@decaf-ts/decoration';\nimport { NgxRenderingEngine } from './NgxRenderingEngine';\nimport { AngularEngineKeys } from './constants';\nimport { Constructor, Metadata } from '@decaf-ts/decoration';\nimport { InternalError } from '@decaf-ts/db-decorators';\nimport { reflectComponentType, Type } from '@angular/core';\n\n/**\n * @description Marks an Angular component as dynamically loadable\n * @summary Decorator that registers an Angular component with the NgxRenderingEngine for dynamic loading.\n * This decorator must be applied before the @Component decorator to properly extract component metadata.\n * It adds metadata to the component class and registers it with the rendering engine using its selector.\n * @function Dynamic\n * @return {Function} A decorator function that can be applied to Angular component classes\n * @mermaid\n * sequenceDiagram\n * participant C as Component Class\n * participant D as Dynamic Decorator\n * participant R as NgxRenderingEngine\n * participant M as Angular Metadata\n * C->>D: Apply decorator\n * D->>M: reflectComponentType()\n * M-->>D: Return component metadata\n * alt No metadata found\n * D->>D: Throw InternalError\n * else Metadata found\n * D->>R: registerComponent(selector, constructor)\n * D->>C: Apply metadata\n * end\n * @category Decorators\n */\nexport function Dynamic() {\n return apply(\n (original: object) => {\n const metadata = reflectComponentType(original as Type<unknown>);\n\n if (!metadata)\n throw new InternalError(\n `Could not find Component metadata. @Dynamic decorator must come above @Component`\n );\n\n NgxRenderingEngine.registerComponent(\n metadata.selector,\n original as unknown as Constructor<unknown>\n );\n },\n metadata(\n Metadata.key(AngularEngineKeys.REFLECT, AngularEngineKeys.DYNAMIC),\n true\n )\n );\n}\n\n\n// export interface UICustomEvents {\n// render: () => HandlerLike;\n// init: () => FunctionLike;\n// }\n\n// export function uion(event: string, handler: FunctionLike) {\n// return (target: any, propertyKey?: any) => {\n// const metadata = {\n// [event]: handler,\n// };\n// propMetadata(getUIAttributeKey(propertyKey, 'handlers'), metadata)(\n// target,\n// propertyKey\n// );\n// };\n// // return (model: unknown, property: unknown) => {\n// // const meta: UIHandlerMetadata = {\n// // [event]: handler,\n// // };\n// // return metadata(\n// // getUIAttributeKey(property as string, 'on'),\n// // meta\n// // )(model, property);\n// // };\n// }\n\n\n// export function uionrender(handler: FunctionLike) {\n// return uion(\"render\", handler);\n// }\n\n// @uion(op, handler)\n\n// @uionrender(handler){\n// return uion(\"redenr\", handler)\n// }\n","/**\n * @module module:lib/components/model-renderer/model-renderer.component\n * @description Model renderer component module.\n * @summary Exposes `ModelRendererComponent` which dynamically renders UI components\n * from model definitions using the `NgxRenderingEngine`. It handles model changes,\n * event subscription and lifecycle for the rendered output.\n *\n * @link {@link ModelRendererComponent}\n */\n\nimport {\n Component,\n Input,\n SimpleChanges\n} from '@angular/core';\nimport { Model, sf } from '@decaf-ts/decorator-validation';\nimport { AngularEngineKeys, BaseComponentProps } from '../../engine/constants';\nimport { AngularDynamicOutput } from '../../engine/interfaces';\nimport { Renderable } from '@decaf-ts/ui-decorators';\nimport { NgxRenderableComponentDirective } from '../../engine/NgxRenderableComponentDirective';\n\n/**\n * @description Component for rendering dynamic models\n * @summary This component is responsible for dynamically rendering models,\n * handling model changes, and managing event subscriptions for the rendered components.\n * It uses the NgxRenderingEngine to render the models and supports both string and Model inputs.\n * @class\n * @template M - Type extending Model\n * @param {Injector} injector - Angular Injector for dependency injection\n * @example\n * <ngx-decaf-model-renderer\n * [model]=\"myModel\"\n * [globals]=\"globalVariables\"\n * (listenEvent)=\"handleEvent($event)\">\n * </ngx-decaf-model-renderer>\n * @mermaid\n * sequenceDiagram\n * participant App\n * participant ModelRenderer\n * participant RenderingEngine\n * participant Model\n * App->>ModelRenderer: Input model\n * ModelRenderer->>Model: Parse if string\n * Model-->>ModelRenderer: Parsed model\n * ModelRenderer->>RenderingEngine: Render model\n * RenderingEngine-->>ModelRenderer: Rendered output\n * ModelRenderer->>ModelRenderer: Subscribe to events\n * ModelRenderer-->>App: Emit events\n */\n@Component({\n standalone: true,\n imports: [],\n selector: 'ngx-decaf-model-renderer',\n templateUrl: './model-renderer.component.html',\n styleUrl: './model-renderer.component.scss',\n host: {'[attr.id]': 'uid'}\n\n})\nexport class ModelRendererComponent<M extends Model>\n extends NgxRenderableComponentDirective {\n\n /**\n * @description Set if render content projection is allowed\n * @default true\n */\n @Input()\n override projectable: boolean = true;\n\n // private injector: Injector = inject(Injector);\n\n // constructor() {}\n\n /**\n * @description Refreshes the rendered model\n * @param {string | M} model - The model to be rendered\n */\n override async refresh(model: string | M): Promise<void> {\n model =\n typeof model === 'string'\n ? (Model.build({}, model) as M)\n : model;\n this.output = (model as unknown as Renderable).render<AngularDynamicOutput>(\n this.globals || {},\n this.vcr,\n this.injector,\n this.inner,\n this.projectable\n );\n if (this.output?.inputs)\n this.rendererId = sf(\n AngularEngineKeys.RENDERED_ID,\n (this.output.inputs as Record<string, unknown>)['rendererId'] as string,\n );\n this.instance = this.output?.component;\n this.subscribeEvents();\n }\n\n /**\n * @description Lifecycle hook that is called when data-bound properties of a directive change\n * @param {SimpleChanges} changes - Object containing changes\n */\n override async ngOnChanges(changes: SimpleChanges): Promise<void> {\n if (changes[BaseComponentProps.MODEL]) {\n const { currentValue } = changes[BaseComponentProps.MODEL];\n this.refresh(currentValue);\n }\n }\n\n\n}\n"," <!-- Keep to avoid id conflicts -->\n <div class=\"dcf-hidden\" [id]=\"uid\"></div>\n\n <ng-template #componentOuter></ng-template>\n <!-- <ng-template #inner>\n <div class=\"dcf-grid dcf-grid-small dcf-model-renderer-component dcf-child-width-1-1\" [id]=\"rendererId || ''\">\n @for (child of output?.children; track child) {\n @if (child?.children?.length) {\n <ngx-decaf-component-renderer [parent]=\"child\" />\n } @else {\n <ng-container\n #childComponents\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n </div>\n </ng-template> -->\n","/**\n * @module module:lib/engine/NgxParentComponentDirective\n * @description Directive base for parent container components used by the rendering system.\n * @summary Provides NgxParentComponentDirective which offers inputs for children metadata,\n * column/row configuration and parent component wiring used by layout and container components.\n *\n * @link {@link NgxParentComponentDirective}\n */\nimport { Directive, Input, OnInit } from '@angular/core';\nimport { NgxComponentDirective } from './NgxComponentDirective';\nimport { FormParent, KeyValue } from './types';\nimport { FieldDefinition, IPagedComponentProperties, UIMediaBreakPoints, UIMediaBreakPointsType, UIModelMetadata } from '@decaf-ts/ui-decorators';\nimport { Model } from '@decaf-ts/decorator-validation';\nimport { IComponentProperties } from './interfaces';\nimport { Subscription, timer } from 'rxjs';\n\n/**\n * @description Layout component for creating responsive grid layouts in Angular applications.\n * @summary This component provides a flexible grid system that can be configured with dynamic\n * rows and columns. It supports responsive breakpoints and can render child components within\n * the grid structure. The component extends NgxComponentDirective to inherit common functionality\n * and integrates with the model and component renderer systems.\n *\n * @class NgxParentComponentDirective\n * @extends {NgxComponentDirective}\n * @implements {OnInit}\n */\n@Directive()\nexport class NgxParentComponentDirective extends NgxComponentDirective implements OnInit {\n\n /**\n * @description Unique identifier for the current record.\n * @summary A unique identifier for the current record being displayed or manipulated.\n * This is typically used in conjunction with the primary key for operations on specific records.\n *\n * @type {string | number}\n */\n @Input()\n page: number = 1;\n\n\n /**\n * @description Unique identifier for the current record.\n * @summary A unique identifier for the current record being displayed or manipulated.\n * This is typically used in conjunction with the primary key for operations on specific records.\n *\n * @type {string | number}\n */\n @Input()\n pages: number | IPagedComponentProperties[] = 1;\n\n\n /**\n * @description Array of UI model metadata for the currently active page.\n * @summary Contains only the UI model metadata for fields that should be displayed\n * on the currently active page. This is a filtered subset of the children array,\n * updated whenever the user navigates between pages.\n *\n * @type { UIModelMetadata | UIModelMetadata[] | FieldDefinition | FieldDefinition[] | undefined }\n */\n activePage: UIModelMetadata | UIModelMetadata[] | FieldDefinition | FieldDefinition[] | undefined = undefined;\n\n\n /**\n * @description The currently active page number.\n * @summary Tracks which page of the multi-step form is currently being displayed.\n * This property is updated as users navigate through the form steps using\n * the next/back buttons or programmatic navigation.\n *\n * @type {number}\n */\n activeIndex: number = 1;\n\n /**\n * @description The parent form object that represents the parent-child relationship in the form hierarchy.\n * @summary This input binds the parent form object to the directive, enabling hierarchical form structures.\n * It allows the directive to interact with the parent form and manage child components effectively.\n *\n * @type {FormParent}\n */\n @Input()\n parentForm!: FormParent;\n\n\n /**\n * @description Array of UI model metadata for all form fields.\n * @summary Contains the complete collection of UI model metadata that defines\n * the structure, validation, and presentation of form fields across all pages.\n * Each metadata object contains information about field type, validation rules,\n * page assignment, and display properties.\n *\n * @type {UIModelMetadata[]}\n */\n @Input()\n children: UIModelMetadata[] | IComponentProperties[] | FieldDefinition[] | KeyValue[] = [];\n\n\n /**\n * @description Number of columns or array of column definitions for the grid layout.\n * @summary Defines the column structure of the grid. When a number is provided, it creates\n * that many equal-width columns. When an array is provided, each element can define specific\n * column properties or sizing. This allows for flexible grid layouts that can adapt to\n * different content requirements.\n *\n * @type {(number | string[])}\n * @default 1\n */\n @Input()\n cols: number | string[] = 1;\n\n /**\n * @description Number of rows or array of row definitions for the grid layout.\n * @summary Defines the row structure of the grid. When a number is provided, it creates\n * that many equal-height rows. When an array is provided, each element can define specific\n * row properties or sizing. This provides control over vertical spacing and content organization.\n *\n * @type {(number | string[])}\n * @default 1\n */\n @Input()\n rows: number | KeyValue[] | string[] = 1;\n\n /**\n * @description Defines the body style of the card.\n * @summary Specifies the appearance of the card body, allowing customization\n * between default, small, or blank styles. This input is used to control the\n * visual presentation of the card content.\n * @type {'default' | 'small' | 'blank'}\n * @default 'default'\n */\n @Input()\n cardBody: 'default' | 'small' | 'blank' = 'default';\n\n /**\n * @description Specifies the type of the card.\n * @summary Determines the card's visual style, such as clear or shadowed.\n * This input allows for flexible styling of the card component to match\n * different design requirements.\n * @type {'clear' | 'shadow'}\n * @default 'clear'\n */\n @Input()\n cardType: 'clear' | 'shadow' = 'clear';\n\n\n /**\n * @description Media breakpoint for responsive behavior.\n * @summary Determines the responsive breakpoint at which the layout should adapt.\n * This affects how the grid behaves on different screen sizes, allowing for\n * mobile-first or desktop-first responsive design patterns. The breakpoint\n * is automatically processed to ensure compatibility with the UI framework.\n *\n * @type {UIMediaBreakPointsType}\n * @default 'medium'\n */\n @Input()\n breakpoint?: UIMediaBreakPointsType | string = UIMediaBreakPoints.MEDIUM;\n\n\n /**\n * @description Determines if the layout should match the parent container's size or configuration.\n * @summary Boolean flag that controls whether the component should adapt its layout to match its parent.\n * When true, the component will attempt to align or size itself according to the parent container.\n *\n * @type {boolean}\n * @default true\n */\n @Input()\n match: boolean = true;\n\n\n /**\n * @description Preloads card placeholders for rendering.\n * @summary Used to create an array of placeholder elements for card components,\n * typically to reserve space or trigger rendering logic before actual data is loaded.\n *\n * @type {any[]}\n * @default [undefined]\n */\n preloadCards: string[] = new Array(1);\n\n\n /**\n * @description Subscription for timer-based operations.\n * @summary Manages the timer subscription used for asynchronous operations\n * like updating active children after page transitions. This subscription\n * is cleaned up in ngOnDestroy to prevent memory leaks.\n *\n * @private\n * @type {Subscription}\n * @memberOf SteppedFormComponent\n */\n protected timerSubscription!: Subscription;\n\n async ngOnInit(model?: Model | string): Promise<void> {\n if (model)\n this.model = model as unknown as string;\n if (this.model && !this.repository)\n this._repository = this.repository;\n }\n\n override ngOnDestroy(): Promise<void> | void {\n super.ngOnDestroy();\n if (this.timerSubscription)\n this.timerSubscription.unsubscribe();\n }\n\n protected getActivePage(page: number): UIModelMetadata | UIModelMetadata[] | FieldDefinition | undefined {\n const content = this.children[page] as FieldDefinition;\n this.activePage = undefined;\n this.preloadCards = [... new Array(1)];\n this.timerSubscription = timer(25).subscribe(() =>\n this.activePage = {... this.children[page] as FieldDefinition }\n );\n this.activeIndex = page;\n if(content)\n return content;\n return undefined;\n }\n}\n","import { Component, EnvironmentInjector, EventEmitter, inject, Input, OnInit, Output, ViewChild} from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { OverlayEventDetail} from \"@ionic/core\";\n\nimport {\n IonButton,\n IonButtons,\n IonContent,\n IonHeader,\n IonModal,\n IonSpinner,\n IonTitle,\n IonToolbar,\n ModalOptions\n} from '@ionic/angular/standalone';\nimport { ModelRendererComponent } from '../model-renderer/model-renderer.component';\nimport * as allIcons from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { NgxRenderingEngine } from '../../engine/NgxRenderingEngine';\nimport { Dynamic } from '../../engine/decorators';\nimport { KeyValue, SelectOption } from '../../engine/types';\nimport { IBaseCustomEvent } from '../../engine/interfaces';\nimport {ActionRoles, DefaultModalOptions} from '../../engine/constants';\nimport { NgxParentComponentDirective } from '../../engine/NgxParentComponentDirective';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { OperationKeys } from '@decaf-ts/db-decorators';\nimport { Primitives } from '@decaf-ts/decorator-validation';\nimport { ComponentRendererComponent } from '../component-renderer/component-renderer.component';\n\n/**\n * @description Modal component for displaying dynamic content in a modal dialog.\n * @summary This component provides a flexible and reusable modal dialog implementation\n * for Angular applications. It supports dynamic content rendering, customizable options,\n * and event handling for modal lifecycle events. The modal can be used for various purposes,\n * such as displaying forms, lightboxes, or selection dialogs.\n *\n * @class ModalComponent\n * @example\n * ```typescript\n * <ngx-decaf-modal [isOpen]=\"true\" [title]=\"'Example Modal'\"></ngx-decaf-modal>\n * ```\n * @mermaid\n * sequenceDiagram\n * participant User\n * participant ModalComponent\n * User->>ModalComponent: Open modal\n * ModalComponent->>ModalController: Initialize modal\n * ModalController-->>ModalComponent: Modal options set\n * User->>ModalComponent: Interact with modal\n * ModalComponent->>ModalController: Handle dismiss event\n */\n\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-modal',\n templateUrl: 'modal.component.html',\n styleUrls: ['modal.component.scss'],\n standalone: true,\n imports: [IonModal, ComponentRendererComponent, ModelRendererComponent, TranslatePipe, IonSpinner, IonButton, IonButtons, IonContent, IonHeader, IonTitle, IonToolbar],\n host: {'[attr.id]': 'uid'},\n})\n/**\n * @description A reusable modal component that wraps Ionic's IonModal functionality.\n * @summary Provides a flexible modal dialog implementation with support for custom content, positioning, fullscreen mode, and lightbox mode. Extends NgxParentComponentDirective to inherit common component functionality.\n *\n * @extends {NgxParentComponentDirective}\n * @implements {OnInit}\n *\n * @example\n * ```typescript\n * // Basic usage in template\n * <app-modal\n * [isOpen]=\"showModal\"\n * [title]=\"'Confirmation'\"\n * [inlineContent]=\"'Are you sure?'\"\n * (willDismissEvent)=\"handleDismiss($event)\">\n * </app-modal>\n *\n * // Programmatic usage\n * const modal = await modalComponent.create({ title: 'Settings' });\n * ```\n *\n * @remarks\n * - The modal supports inline content that can be positioned at the top or bottom\n * - Fullscreen and lightbox modes are available for different display needs\n * - The component automatically sanitizes HTML content for security\n * - Modal dismissal can be handled through cancel or confirm actions\n * - Global configuration can be passed through the globals input\n *\n * @public\n */\nexport class ModalComponent extends NgxParentComponentDirective implements OnInit {\n\n @ViewChild('component')\n modal!: IonModal;\n\n /**\n * @description Title of the modal dialog.\n * @summary Specifies the title text displayed in the modal header.\n * @type {string | undefined}\n */\n @Input()\n title?: string;\n\n /**\n * @description Determines whether the modal is open.\n * @summary Controls the visibility of the modal dialog. When set to true, the modal is displayed.\n * @type {boolean}\n * @default false\n */\n @Input()\n isOpen: boolean = false;\n\n /**\n * @description Tag identifier for the modal.\n * @summary Provides a unique tag for identifying the modal instance.\n * @type {string | undefined}\n */\n @Input()\n tag?: string;\n\n /**\n * @description Options for configuring the modal.\n * @summary Allows customization of modal behavior and appearance through the ModalOptions interface.\n * @type {ModalOptions | undefined}\n */\n @Input()\n options?: ModalOptions;\n\n /**\n * @description Global key-value pairs for modal configuration.\n * @summary Stores global settings that can be accessed within the modal instance.\n * @type {KeyValue | undefined}\n */\n @Input()\n globals?: KeyValue;\n\n /**\n * @description Inline content to be displayed in the modal.\n * @summary Specifies the HTML or SafeHtml content to be rendered inside the modal.\n * @type {string | SafeHtml | undefined}\n */\n @Input()\n inlineContent?: string | SafeHtml;\n\n /**\n * @description Position of the inline content within the modal.\n * @summary Determines whether the inline content is displayed at the top or bottom of the modal.\n * @type {'top' | 'bottom'}\n * @default 'bottom'\n */\n @Input()\n inlineContentPosition: 'top' | 'bottom' = 'bottom';\n\n /**\n * @description Enables fullscreen mode for the modal.\n * @summary When set to true, the modal occupies the entire screen.\n * @type {boolean}\n * @default false\n */\n @Input()\n fullscreen: boolean = false;\n\n /**\n * @description Enables lightbox mode for the modal.\n * @summary When set to true, the modal is displayed as a lightbox.\n * @type {boolean}\n * @default false\n */\n @Input()\n lightBox: boolean = false;\n\n\n /**\n * @description Event emitted when the modal is about to be dismissed.\n * @summary Emits an OverlayEventDetail object containing details about the dismiss event.\n * @type {EventEmitter<OverlayEventDetail>}\n */\n @Output()\n willDismissEvent: EventEmitter<OverlayEventDetail> = new EventEmitter<OverlayEventDetail>();\n\n /**\n * @description Sanitizer instance for bypassing security and sanitizing HTML content.\n * @summary Used to sanitize dynamic HTML content, ensuring it is safe to render in the DOM.\n * @type {DomSanitizer}\n */\n domSanitizer: DomSanitizer = inject(DomSanitizer);\n\n constructor() {\n super(\"ModalComponent\");\n addIcons(allIcons);\n }\n\n /**\n * @description Lifecycle hook that initializes the modal component.\n * @summary Sets up the modal controller and sanitizes inline content if provided.\n *\n * @returns {Promise<void>} - A promise that resolves when initialization is complete.\n */\n override async ngOnInit(): Promise<void> {\n if (this.inlineContent && typeof this.inlineContent === Primitives.STRING) {\n this.inlineContent = this.domSanitizer.bypassSecurityTrustHtml(this.inlineContent as string);\n }\n }\n\n /**\n * @description Initializes the modal with the provided options.\n * @summary Merges default options with user-provided options and sets global configuration.\n *\n * @param {KeyValue} [options={}] - Additional options for modal initialization.\n * @returns {Promise<void>} - A promise that resolves when initialization is complete.\n */\n override async initialize(options: KeyValue = {}): Promise<void> {\n this.options = Object.assign({}, DefaultModalOptions, this.options, options);\n this.globals = Object.assign({}, this.globals || {}, { isModalChild: true });\n this.initialized = true;\n }\n\n /**\n * @description Creates and presents the modal.\n * @summary Initializes the modal with the provided properties and displays it.\n *\n * @param {KeyValue} [props={}] - Properties to initialize the modal.\n * @returns {Promise<ModalComponent>} - A promise that resolves with the modal instance.\n */\n async create(props: KeyValue = {}): Promise<ModalComponent> {\n await this.initialize(props);\n await this.present();\n return this;\n }\n\n /**\n * @description Presents the modal.\n * @summary Sets the modal's visibility to true and triggers change detection.\n *\n * @returns {Promise<void>} - A promise that resolves when the modal is presented.\n */\n async present(): Promise<void> {\n this.isOpen = true;\n this.changeDetectorRef.detectChanges();\n }\n\n /**\n * @description Handles custom events for the modal.\n * @summary Stops event propagation and triggers confirm or cancel actions based on event data.\n *\n * @param {IBaseCustomEvent} event - The custom event to handle.\n * @returns {Promise<void>} - A promise that resolves when the event is handled.\n */\n override async handleEvent(event: IBaseCustomEvent): Promise<void> {\n if (event instanceof Event) {\n event.stopImmediatePropagation();\n }\n await (event?.data ? this.confirm(event) : this.cancel());\n }\n\n /**\n * @description Handles the modal dismiss event.\n * @summary This method is triggered when the modal is about to be dismissed. It emits the `willDismissEvent` with the event details.\n *\n * @param {CustomEvent<OverlayEventDetail>} event - The dismiss event containing overlay details.\n * @returns {Promise<OverlayEventDetail>} - A promise that resolves with the overlay event details.\n */\n async handleWillDismiss(event: CustomEvent<OverlayEventDetail>): Promise<OverlayEventDetail> {\n const { detail } = event;\n this.willDismissEvent.emit(event as OverlayEventDetail);\n return detail;\n }\n\n /**\n * @description Cancels the modal and dismisses it with a cancel action.\n * @summary This method is used to programmatically close the modal with a cancel action.\n *\n * @returns {Promise<void>} - A promise that resolves when the modal is dismissed.\n */\n async cancel(): Promise<void> {\n await (this.modal as IonModal).dismiss(undefined, ActionRoles.cancel);\n }\n\n /**\n * @description Confirms the modal and dismisses it with a confirm action.\n * @summary This method is used to programmatically close the modal with a confirm action, passing optional event data.\n *\n * @param {IBaseCustomEvent} event - The custom event containing data to pass during confirmation.\n * @returns {Promise<void>} - A promise that resolves when the modal is dismissed.\n */\n async confirm(event: IBaseCustomEvent): Promise<void> {\n await (this.modal as IonModal).dismiss(event?.data || undefined, ActionRoles.confirm);\n }\n}\n\n/**\n * @description Retrieves a modal component instance.\n * @summary Creates and initializes a modal component with the provided properties and options.\n *\n * @param {Partial<ModalComponent>} [props={}] - Properties to initialize the modal component.\n * @param {Partial<ModalOptions>} [modalProps={}] - Additional modal options.\n * @param {EnvironmentInjector} [injector] - Optional environment injector for dependency injection.\n * @returns {Promise<IonModal>} - A promise that resolves with the modal instance.\n */\nexport async function getNgxModalComponent(props: Partial<ModalComponent> = {}, modalProps: Partial<ModalOptions> = {}, injector?: EnvironmentInjector): Promise<IonModal> {\n const { globals } = { ...props };\n if (!globals || !globals?.['operation']) {\n props.globals = { ...(globals || {}), operation: OperationKeys.CREATE };\n }\n const component = await (NgxRenderingEngine.createComponent(ModalComponent, props, injector || undefined) as ModalComponent).create(modalProps);\n return component.modal;\n}\n\n/**\n * @description Presents a lightbox modal with inline content.\n * @summary Displays a modal in lightbox mode with the specified content and properties.\n *\n * @param {string | SafeHtml} inlineContent - The content to display in the lightbox modal.\n * @param {Partial<ModalComponent>} [props={}] - Properties to initialize the modal component.\n * @param {EnvironmentInjector} [injector] - Optional environment injector for dependency injection.\n * @returns {Promise<void>} - A promise that resolves when the modal is presented.\n */\nexport async function presentNgxLightBoxModal(inlineContent: string | SafeHtml, props: Partial<ModalComponent> = {}, injector?: EnvironmentInjector): Promise<void> {\n return (await getNgxModalComponent({ props, ...{ inlineContent, lightBox: true } }, {}, injector || undefined)).present();\n}\n\n/**\n * @description Retrieves a modal for selecting options.\n * @summary Creates and initializes a modal component for displaying a list of selectable options.\n *\n * @param {SelectOption[]} options - The list of options to display in the modal.\n * @param {EnvironmentInjector} [injector] - Optional environment injector for dependency injection.\n * @returns {Promise<IonModal>} - A promise that resolves with the modal instance.\n */\nexport async function getNgxSelectOptionsModal(options: SelectOption[], injector?: EnvironmentInjector): Promise<IonModal> {\n const props = {\n tag: 'ngx-decaf-list',\n globals: {\n data: options,\n item: { tag: true },\n pk: 'value',\n mapper: { title: 'text', uid: 'value' },\n },\n };\n return (await getNgxModalComponent(props, {}, injector || undefined));\n}\n","<ion-modal\n [id]=\"uid\"\n [isOpen]=\"isOpen\"\n (willDismiss)=\"handleWillDismiss($event)\"\n [backdropDismiss]=\"options?.backdropDismiss\"\n [showBackdrop]=\"options?.showBackdrop\"\n [animated]=\"options?.animated\"\n [canDismiss]=\"options?.canDismiss\"\n [class.dcf-fullscreen-modal]=\"fullscreen\"\n [class.dcf-lightbox-modal]=\"lightBox\"\n class=\"dcf-modal-component\"\n #component\n>\n <ng-template>\n <ion-header [transparent]=\"lightBox\">\n <ion-toolbar>\n @if (title) {\n <ion-title>{{ title | translate }}</ion-title>\n }\n <ion-buttons slot=\"end\">\n <ion-button size=\"small\" type=\"button\" class=\"dcf-button-close\" (click)=\"cancel()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n\n <ion-content>\n <section class=\"dcf-modal-body\">\n @if (!tag && !model && !inlineContent) {\n <div class=\"dcf-loading-container\">\n <ion-spinner name=\"crescent\" color=\"primary\"></ion-spinner>\n </div>\n } @else {\n @if (inlineContent && inlineContentPosition === \"top\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n @if (model) {\n <ngx-decaf-model-renderer\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"globals\"\n />\n }\n @if(tag && globals) {\n <ngx-decaf-component-renderer\n [tag]=\"tag\"\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"{props: globals}\"\n />\n }\n @if (inlineContent && inlineContentPosition === \"bottom\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n }\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n","/**\n * @module module:lib/components/crud-field/crud-field.component\n * @description CRUD field component module.\n * @summary Exposes `CrudFieldComponent`, a dynamic form field used in CRUD forms supporting\n * many input types, validation and integration with `NgxFormFieldDirective` utilities.\n *\n * @link {@link CrudFieldComponent}\n */\n\nimport {\n AfterViewInit,\n Component,\n CUSTOM_ELEMENTS_SCHEMA,\n ElementRef,\n HostListener,\n Input,\n OnDestroy,\n OnInit,\n ViewChild\n} from '@angular/core';\nimport { FormArray, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { TranslatePipe} from '@ngx-translate/core';\nimport { AutocompleteTypes, CheckboxCustomEvent, SelectInterface } from '@ionic/core';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport {\n IonCheckbox,\n IonInput,\n IonItem,\n IonLabel,\n IonRadio,\n IonRadioGroup,\n IonSelect,\n IonSelectOption,\n IonText,\n IonTextarea,\n} from '@ionic/angular/standalone';\nimport { CrudOperationKeys, HTML5InputTypes } from '@decaf-ts/ui-decorators';\nimport { addIcons } from 'ionicons';\nimport { chevronDownOutline, chevronUpOutline } from 'ionicons/icons';\nimport { getModelAndRepository } from '../../for-angular-common.module';\nimport { CrudFieldOption, FieldUpdateMode, KeyValue, FunctionLike, PossibleInputTypes, StringOrBoolean, FormParent, SelectOption } from '../../engine/types';\nimport { dataMapper, generateRandomValue } from '../../utils';\nimport { NgxFormFieldDirective } from '../../engine/NgxFormFieldDirective';\nimport { Dynamic } from '../../engine/decorators';\nimport { getLocaleContextByKey } from '../../i18n/Loader';\nimport { getNgxSelectOptionsModal } from '../modal/modal.component';\nimport { ActionRoles } from '../../engine/constants';\n\n/**\n * @description A dynamic form field component for CRUD operations.\n * @summary The CrudFieldComponent is a versatile form field component that adapts to different\n * input types and CRUD operations. It extends NgxFormFieldDirective to inherit form handling capabilities\n * and implements lifecycle hooks to properly initialize, render, and clean up. This component\n * supports various input types (text, number, date, select, etc.), validation rules, and styling\n * options, making it suitable for building dynamic forms for create, read, update, and delete\n * operations.\n *\n * @param {CrudOperations} operation - The CRUD operation being performed (create, read, update, delete)\n * @param {string} name - The field name, used as form control identifier\n * @param {PossibleInputTypes} type - The input type (text, number, date, select, etc.)\n * @param {string|number|Date} value - The initial value of the field\n * @param {boolean} disabled - Whether the field is disabled\n * @param {string} label - The display label for the field\n * @param {string} placeholder - Placeholder text when field is empty\n * @param {string} format - Format pattern for the field value\n * @param {boolean} hidden - Whether the field should be hidden\n * @param {number|Date} max - Maximum allowed value\n * @param {number} maxlength - Maximum allowed length\n * @param {number|Date} min - Minimum allowed value\n * @param {number} minlength - Minimum allowed length\n * @param {string} pattern - Validation pattern\n * @param {boolean} readonly - Whether the field is read-only\n * @param {boolean} required - Whether the field is required\n * @param {number} step - Step value for number inputs\n * @param {FormGroup} formGroup - The parent form group\n * @param {StringOrBoolean} translatable - Whether field labels should be translated\n *\n * @component CrudFieldComponent\n * @example\n * <ngx-decaf-crud-field\n * operation=\"create\"\n * name=\"firstName\"\n * type=\"text\"\n * label=\"<NAME>\"\n * placeholder=\"<NAME>\"\n * [value]=\"model.firstName\"\n * [disabled]=\"model.readOnly\">\n *\n *\n * @memberOf module:for-angular\n */\n@Dynamic()\n@Component({\n standalone: true,\n imports: [\n ReactiveFormsModule,\n TranslatePipe,\n IonInput,\n IonItem,\n IonCheckbox,\n IonRadioGroup,\n IonRadio,\n IonSelect,\n IonSelectOption,\n IonLabel,\n IonText,\n IonTextarea\n ],\n selector: 'ngx-decaf-crud-field',\n templateUrl: './crud-field.component.html',\n styleUrl: './crud-field.component.scss',\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n host: {'[attr.id]': 'uid', '[attr.class]': 'className'},\n})\nexport class CrudFieldComponent extends NgxFormFieldDirective implements OnInit, OnDestroy, AfterViewInit {\n\n /**\n * @description The CRUD operation being performed.\n * @summary Specifies which CRUD operation (Create, Read, Update, Delete) the field is being used for.\n * This affects how the field behaves and is rendered. For example, fields might be read-only in\n * 'read' mode but editable in 'create' or 'update' modes.\n *\n * @type {CrudOperations}\n * @memberOf CrudFieldComponent\n */\n @Input({ required: true })\n override operation!: CrudOperations;\n\n /**\n * @summary The flat field name used as the form control identifier in immediate parent FormGroup.\n * @description\n * Specifies the name of the field, which is used as the FormControl identifier in immediate parent FormGroup.\n * This value must be unique within the immediate parent FormGroup context and should not contain dots or nesting.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input({ required: true })\n override name!: string;\n\n\n @Input()\n override className: string = 'dcf-width-1-1';\n\n /**\n * @summary The full field path used for form control resolution.\n * @description Specifies the hierarchical path of the field, used to resolve its location within the parent FormGroup (or nested FormGroups).\n * It is used as the identifier in the rendered HTML, and may include nesting (e.g., 'address.billing.street') and\n * should match the structure of the data model\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input({ required: true })\n override path!: string;\n\n /**\n * @description The parent field path, if this field is nested.\n * @summary Specifies the full dot-delimited path of the parent field. This is only set when the field is nested.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n /**\n * @description The parent field path for nested field structures.\n * @summary Specifies the full dot-delimited path of the parent field when this field\n * is part of a nested structure. This is used for hierarchical form organization\n * and proper form control resolution in complex form structures.\n *\n * @type {string}\n * @default ''\n * @memberOf CrudFieldComponent\n */\n @Input()\n override childOf: string = '';\n\n /**\n * @description The input type of the field.\n * @summary Defines the type of input to render, such as text, number, date, select, etc.\n * This determines which Ionic form component will be used to render the field and how\n * the data will be formatted and validated.\n *\n * @type {PossibleInputTypes}\n * @memberOf CrudFieldComponent\n */\n @Input({ required: true })\n override type!: PossibleInputTypes;\n\n /**\n * @description The initial value of the field.\n * @summary Sets the initial value of the form field. This can be a string, number, or Date\n * depending on the field type. For select fields, this should match one of the option values.\n *\n * @type {string | number | Date}\n * @default ''\n * @memberOf CrudFieldComponent\n */\n @Input()\n override value: string | number | Date | string[] = '';\n\n /**\n * @description Whether the field is disabled.\n * @summary When true, the field will be rendered in a disabled state, preventing user interaction.\n * Disabled fields are still included in the form model but cannot be edited by the user.\n *\n * @type {boolean}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override disabled?: boolean;\n\n /**\n * @description The display label for the field.\n * @summary The text label displayed alongside the field to identify it to the user.\n * This label can be translated if the translatable property is set to true.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input({ required: true })\n label!: string;\n\n /**\n * @description Placeholder text when field is empty.\n * @summary Text that appears in the input when it has no value. This provides a hint to the user\n * about what kind of data is expected. The placeholder disappears when the user starts typing.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input()\n placeholder!: string;\n\n /**\n * @description Format pattern for the field value.\n * @summary Specifies a format pattern for the field value, which can be used for date formatting,\n * number formatting, or other type-specific formatting requirements.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override format?: string;\n\n /**\n * @description Whether the field should be hidden.\n * @summary When true, the field will not be visible in the UI but will still be part of the form model.\n * This is useful for fields that need to be included in form submission but should not be displayed to the user.\n *\n * @type {boolean}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override hidden: boolean | CrudOperationKeys[] = false;\n\n /**\n * @description Maximum allowed value for the field.\n * @summary For number inputs, this sets the maximum allowed numeric value.\n * For date inputs, this sets the latest allowed date.\n *\n * @type {number | Date}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override max?: number | Date;\n\n /**\n * @description Maximum allowed length for text input.\n * @summary For text inputs, this sets the maximum number of characters allowed.\n * This is used for validation and may also be used to limit input in the UI.\n *\n * @type {number}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override maxlength?: number;\n\n /**\n * @description Minimum allowed value for the field.\n * @summary For number inputs, this sets the minimum allowed numeric value.\n * For date inputs, this sets the earliest allowed date.\n *\n * @type {number | Date}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override min?: number | Date;\n\n /**\n * @description Minimum allowed length for text input.\n * @summary For text inputs, this sets the minimum number of characters required.\n * This is used for validation to ensure the input meets a minimum length requirement.\n *\n * @type {number}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override minlength?: number;\n\n /**\n * @description Validation pattern for text input.\n * @summary A regular expression pattern used to validate text input.\n * The input value must match this pattern to be considered valid.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override pattern?: string;\n\n /**\n * @description Whether the field is read-only.\n * @summary When true, the field will be rendered in a read-only state. Unlike disabled fields,\n * read-only fields are still focusable but cannot be modified by the user.\n *\n * @type {boolean}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override readonly: boolean = false;\n\n /**\n * @description Whether the field is required.\n * @summary When true, the field must have a value for the form to be valid.\n * Required fields are typically marked with an indicator in the UI.\n *\n * @type {boolean}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override required?: boolean;\n\n /**\n * @description Step value for number inputs.\n * @summary For number inputs, this sets the increment/decrement step when using\n * the up/down arrows or when using a range slider.\n *\n * @type {number}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override step?: number;\n\n /**\n * @description Field name for equality validation comparison.\n * @summary Specifies another field name that this field's value must be equal to for validation.\n * This is commonly used for password confirmation fields or other scenarios where\n * two fields must contain the same value.\n *\n * @type {string | undefined}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override equals?: string;\n\n /**\n * @description Field name for inequality validation comparison.\n * @summary Specifies another field name that this field's value must be different from for validation.\n * This is used to ensure that two fields do not contain the same value, which might be\n * required for certain business rules or security constraints.\n *\n * @type {string | undefined}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override different?: string;\n\n /**\n * @description Field name for less-than validation comparison.\n * @summary Specifies another field name that this field's value must be less than for validation.\n * This is commonly used for date ranges, numeric ranges, or other scenarios where\n * one field must have a smaller value than another.\n *\n * @type {string | undefined}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override lessThan?: string;\n\n /**\n * @description Field name for less-than-or-equal validation comparison.\n * @summary Specifies another field name that this field's value must be less than or equal to\n * for validation. This provides inclusive upper bound validation for numeric or date comparisons.\n *\n * @type {string | undefined}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override lessThanOrEqual?: string;\n\n /**\n * @description Field name for greater-than validation comparison.\n * @summary Specifies another field name that this field's value must be greater than for validation.\n * This is commonly used for date ranges, numeric ranges, or other scenarios where\n * one field must have a larger value than another.\n *\n * @type {string | undefined}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override greaterThan?: string;\n\n /**\n * @description Field name for greater-than-or-equal validation comparison.\n * @summary Specifies another field name that this field's value must be greater than or equal to\n * for validation. This provides inclusive lower bound validation for numeric or date comparisons.\n *\n * @type {string | undefined}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override greaterThanOrEqual?: string;\n\n /**\n * @description Alignment of the field content.\n * @summary Controls the horizontal alignment of the field content.\n * This affects how the content is positioned within the field container.\n *\n * @type {'start' | 'center'}\n * @memberOf CrudFieldComponent\n */\n @Input()\n alignment?: 'start' | 'center';\n\n /**\n * @description Initial checked state for checkbox or toggle inputs.\n * @summary For checkbox or toggle inputs, this sets the initial checked state.\n * When true, the checkbox or toggle will be initially checked.\n *\n * @type {boolean}\n * @memberOf CrudFieldComponent\n */\n @Input()\n checked?: boolean;\n\n /**\n * @description Justification of items within the field.\n * @summary Controls how items are justified within the field container.\n * This is particularly useful for fields with multiple elements, such as radio groups.\n *\n * @type {'start' | 'end' | 'space-between'}\n * @memberOf CrudFieldComponent\n */\n @Input()\n justify?: 'start' | 'end' | 'space-between';\n\n /**\n * @description Text for the cancel button in select inputs.\n * @summary For select inputs with a cancel button, this sets the text displayed on the cancel button.\n * This is typically used in select dialogs to provide a way for users to dismiss the selection without making a change.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input()\n cancelText?: string;\n\n /**\n * @description Interface style for select inputs.\n * @summary Specifies the interface style for select inputs, such as 'alert', 'action-sheet', or 'popover'.\n * This determines how the select options are presented to the user.\n *\n * @type {SelectInterface}\n * @memberOf CrudFieldComponent\n */\n @Input()\n interface: SelectInterface = 'popover';\n\n /**\n * @description Options for select or radio inputs.\n * @summary Provides the list of options for select or radio inputs. Each option can have a value and a label.\n * This is used to populate the dropdown or radio group with choices.\n *\n * @type {CrudFieldOption[]}\n * @memberOf CrudFieldComponent\n */\n @Input()\n options!: FunctionLike | CrudFieldOption[] | KeyValue[];\n\n /**\n * @description Mode of the field.\n * @summary Specifies the visual mode of the field, such as 'ios' or 'md'.\n * This affects the styling and appearance of the field to match the platform style.\n *\n * @type {'ios' | 'md'}\n * @memberOf CrudFieldComponent\n */\n @Input()\n mode?: 'ios' | 'md';\n\n /**\n * @description Spellcheck attribute for text inputs.\n * @summary Enables or disables spellchecking for text inputs.\n * When true, the browser will check the spelling of the input text.\n *\n * @type {boolean}\n * @default false\n * @memberOf CrudFieldComponent\n */\n @Input()\n spellcheck: boolean = false;\n\n /**\n * @description Input mode for text inputs.\n * @summary Hints at the type of data that might be entered by the user while editing the element.\n * This can affect the virtual keyboard layout on mobile devices.\n *\n * @type {'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search'}\n * @default 'none'\n * @memberOf CrudFieldComponent\n */\n @Input()\n inputmode:\n | 'none'\n | 'text'\n | 'tel'\n | 'url'\n | 'email'\n | 'numeric'\n | 'decimal'\n | 'search' = 'none';\n\n /**\n * @description Autocomplete behavior for the field.\n * @summary Specifies whether and how the browser should automatically complete the input.\n * This can improve user experience by suggesting previously entered values.\n *\n * @type {AutocompleteTypes}\n * @default 'off'\n * @memberOf CrudFieldComponent\n */\n @Input()\n autocomplete: AutocompleteTypes = 'off';\n\n /**\n * @description Fill style for the field.\n * @summary Determines the fill style of the field, such as 'outline' or 'solid'.\n * This affects the border and background of the field.\n *\n * @type {'outline' | 'solid'}\n * @default 'outline'\n * @memberOf CrudFieldComponent\n */\n @Input()\n fill: 'outline' | 'solid' = 'outline';\n\n /**\n * @description Placement of the label relative to the field.\n * @summary Specifies where the label should be placed relative to the field.\n * Options include 'start', 'end', 'floating', 'stacked', and 'fixed'.\n *\n * @type {'start' | 'end' | 'floating' | 'stacked' | 'fixed'}\n * @default 'floating'\n * @memberOf CrudFieldComponent\n */\n @Input()\n labelPlacement: 'start' | 'end' | 'floating' | 'stacked' | 'fixed' =\n 'floating';\n\n /**\n * @description Update mode for the field.\n * @summary Determines when the field value should be updated in the form model.\n * Options include 'change', 'blur', and 'submit'.\n *\n * @type {FieldUpdateMode}\n * @default 'change'\n * @memberOf CrudFieldComponent\n */\n @Input()\n updateOn: FieldUpdateMode = 'change';\n\n /**\n * @description Reference to the field component.\n * @summary Provides a reference to the field component element, allowing direct access to its properties and methods.\n *\n * @type {ElementRef}\n * @memberOf CrudFieldComponent\n */\n @ViewChild('component', { read: ElementRef })\n override component!: ElementRef;\n\n /**\n * @description Parent form group.\n * @summary References the parent form group to which this field belongs.\n * This is necessary for integrating the field with Angular's reactive forms.\n *\n * @type {FormGroup}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override formGroup: FormGroup | undefined;\n\n\n /**\n * @description Angular FormControl instance for this field.\n * @summary The specific FormControl instance that manages this field's state, validation,\n * and value. This provides direct access to Angular's reactive forms functionality\n * for this individual field within the broader form structure.\n *\n * @type {FormControl}\n * @memberOf CrudFieldComponent\n */\n @Input()\n override formControl!: FormControl;\n\n /**\n * @description Indicates if this field supports multiple values.\n * @summary When true, this field can handle multiple values, typically used in\n * multi-select scenarios or when the field is part of a form array structure\n * that allows multiple entries of the same field type.\n *\n * @type {boolean}\n * @default false\n * @memberOf CrudFieldComponent\n */\n @Input()\n override multiple: boolean = false;\n\n /**\n * @description Unique identifier for the current record.\n * @summary A unique identifier for the current record being displayed or manipulated.\n * This is typically used in conjunction with the primary key for operations on specific records.\n *\n * @type {string | number}\n */\n @Input()\n override uid: string = generateRandomValue(12);\n\n\n @Input()\n override page!: number;\n\n /**\n * @description Translatability of field labels.\n * @summary Indicates whether the field labels should be translated based on the current language settings.\n * This is useful for applications supporting multiple languages.\n *\n * @type {StringOrBoolean}\n * @default true\n * @memberOf CrudFieldComponent\n */\n @Input()\n translatable: StringOrBoolean = true;\n\n /**\n * @description Component initialization lifecycle method.\n * @summary Initializes the field component based on the operation type and field configuration.\n * For READ and DELETE operations, removes the form group to make fields read-only.\n * For other operations, sets up icons, configures multi-value support if needed,\n * and sets default values for radio buttons if no value is provided.\n *\n * @returns {void}\n * @memberOf CrudFieldComponent\n */\n async ngOnInit(): Promise<void> {\n this.options = await this.getOptions();\n addIcons({chevronDownOutline, chevronUpOutline});\n if (Array.isArray(this.hidden) && !(this.hidden as string[]).includes(this.operation)) {\n this.hidden = false;\n }\n if ([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation)) {\n this.formGroup = undefined;\n } else {\n if (!this.parentForm && this.formGroup instanceof FormGroup || this.formGroup instanceof FormArray)\n this.parentForm = (this.formGroup.root || this.formControl.root) as FormParent;\n if (this.multiple) {\n this.formGroup = this.activeFormGroup as FormGroup;\n if (!this.parentForm)\n this.parentForm = this.formGroup.parent as FormArray;\n this.formControl = (this.formGroup as FormGroup).get(this.name) as FormControl;\n }\n if (!this.value && (this.options as []).length)\n this.setValue((this.options as CrudFieldOption[])[0].value);\n\n if (this.type === HTML5InputTypes.CHECKBOX) {\n if(this.labelPlacement === 'floating')\n this.labelPlacement = 'end';\n if (Array.isArray(this.value))\n this.setValue(this.value);\n }\n }\n }\n\n /**\n * Returns a list of options for select or radio inputs, with their `text` property\n * localized if it does not already include the word 'options'. The localization key\n * is generated from the component's label, replacing 'label' with 'options'.\n *\n * @returns {CrudFieldOption[]} The array of parsed and localized options.\n * @memberOf CrudFieldComponent\n */\n async getOptions(): Promise<CrudFieldOption[]> {\n if (!this.options)\n return [];\n if (this.options instanceof Function) {\n if (this.options.name === 'options')\n this.options = this.options() as FunctionLike;\n const fnName = (this.options as FunctionLike)?.name;\n if (fnName) {\n if (fnName === 'function') {\n this.options = (this.options as FunctionLike)() as KeyValue[];\n } else {\n const repo = getModelAndRepository((this.options as KeyValue)?.['name']);\n if(repo) {\n const {repository} = repo;\n this.options = await repository.select().execute();\n }\n\n }\n }\n }\n if (this.optionsMapper) {\n if (this.optionsMapper instanceof Function || typeof this.optionsMapper === 'function') {\n const mapper = this.optionsMapper as (option: KeyValue) => CrudFieldOption;\n this.options = (this.options as (CrudFieldOption | KeyValue)[]).map((option: KeyValue) => {\n return mapper(option);\n });\n } else if (Object.keys(this.optionsMapper).length > 0) {\n this.options = dataMapper(this.options as KeyValue[], this.optionsMapper as Record<string, string>);\n }\n }\n const options = (this.options as CrudFieldOption[]).map(async(option) => {\n const text = await this.translate((!option.text.includes('options') ?\n getLocaleContextByKey(`${this.label.toLowerCase().replace('label', 'options')}`, option.text)\n : option.text));\n return {\n value: option.value,\n text: text.includes('.options') ? option.text : text\n };\n });\n this.options = await Promise.all(options);\n if (this.options.length > 10 && this.interface === 'popover')\n this.interface = 'modal';\n return this.options as CrudFieldOption[];\n }\n\n\n async openSelectOptions(event: Event, selectInterface: SelectInterface): Promise<void> {\n if(selectInterface === 'modal') {\n event.preventDefault();\n event.stopImmediatePropagation();\n const modal = await getNgxSelectOptionsModal(this.options as SelectOption[]);\n const {data, role} = await modal.onWillDismiss();\n if(role === ActionRoles.confirm && data !== this.value)\n this.setValue(data);\n }\n }\n\n\n /**\n * @description Component after view initialization lifecycle method.\n * @summary Calls the parent afterViewInit method for READ and DELETE operations.\n * This ensures proper initialization of read-only fields that don't require\n * form functionality but still need view setup.\n *\n * @returns {Promise<void>}\n * @memberOf CrudFieldComponent\n */\n async ngAfterViewInit(): Promise<void> {\n if (this.type === HTML5InputTypes.RADIO && !this.value)\n this.setValue((this.options as CrudFieldOption[])[0].value); // TODO: migrate to RenderingEngine\n }\n\n\n /**\n * @description Component cleanup lifecycle method.\n * @summary Performs cleanup operations for READ and DELETE operations by calling\n * the parent onDestroy method. This ensures proper resource cleanup for\n * read-only field components.\n *\n * @returns {void}\n * @memberOf CrudFieldComponent\n */\n override ngOnDestroy(): void {\n super.ngOnDestroy();\n if ([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation))\n this.onDestroy();\n }\n\n toggleOptionSelection(val: string, event: CheckboxCustomEvent) {\n const { checked } = event.detail;\n let value = Array.isArray(this.formControl.value) ? this.formControl.value : [];\n if (checked) {\n if (!value.includes(val))\n value = [...value, val];\n } else {\n value = value.filter(v => v !== val);\n }\n this.setValue(value);\n this.formControl.updateValueAndValidity();\n }\n\n\n isOptionChecked(value: string): boolean {\n if (!this.formControl.value || !Array.isArray(this.formControl.value))\n return false;\n return this.formControl.value.includes(value);\n }\n\n\n /**\n * @description Handles fieldset group update events from parent fieldsets.\n * @summary Processes events triggered when an existing group needs to be updated.\n * Updates the active form group index and refreshes the form group and form control\n * references to point to the group being edited.\n *\n * @param {CustomEvent} event - The fieldset update group event containing update details\n * @returns {void}\n * @memberOf CrudFieldComponent\n */\n @HostListener('window:fieldsetUpdateGroupEvent', ['$event'])\n handleFieldsetUpdateGroupEvent(event: CustomEvent): void {\n const {formGroup, index} = event.detail;\n this.activeFormGroupIndex = index;\n this.formGroup = formGroup;\n this.formControl = (this.formGroup as FormGroup).get(this.name) as FormControl;\n this.value = this.formControl.value;\n }\n}\n","@if (operation === 'read' || operation === 'delete') {\n <ng-container>\n <div>\n <ion-item [class]=\"'dcf-input-item ' + operation\" #component>\n <ion-label>\n {{ label | translate }}<br />\n @if (value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n @if (['checkbox'].includes(type)) {\n <ion-icon aria-hidden=\"true\" class=\"dcf-margin-small-top\" [color]=\"!isDarkMode ? 'primary' : 'light'\" size=\"large\" name=\"checkmark-circle-outline\"></ion-icon>\n } @else {\n <br />\n }\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n @if (formControl) {\n <ng-container [formGroup]=\"multiple ? activeFormGroup : formControl.parent\">\n <div\n [id]=\"uid\" #container\n [class]=\"'dcf-input-item ' + (operation || 'create')\"\n [class.dcf-field-required]=\"required\"\n [class.dcf-field-readonly]=\"readonly\"\n >\n @if (type === 'textarea') {\n <ion-textarea\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [inputmode]=\"inputmode\"\n [spellcheck]=\"spellcheck\"\n [rows]=\"rows\"\n [labelPlacement]=\"labelPlacement\"\n [value]=\"value\"\n [fill]=\"fill\"\n [errorText]=\"getErrors(container)\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [label]=\"label | translate\"\n #component>\n </ion-textarea>\n }\n @else if (type === 'checkbox') {\n @if (!options?.length) {\n <ion-item class=\"dcf-width-1-1\" [hidden]=\"hidden\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify || 'start'\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span>{{label | translate}}</span>\n </ion-checkbox>\n\n </ion-item>\n } @else {\n <div class=\"dcf-checkbox-group\">\n <label class=\"dcf-label\" [for]=\"path\">{{ label | translate }}</label>\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-item class=\"dcf-width-1-1\" [button]=\"true\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"option.text\"\n [mode]=\"'md'\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"option.value\"\n [readonly]=\"readonly\"\n [checked]=\"isOptionChecked(option.value)\"\n (ionChange)=\"toggleOptionSelection(option.value, $event)\"\n #component>\n <span>{{ $index + 1 }}. {{ option?.text | translate }}</span>\n </ion-checkbox>\n </ion-item>\n }\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n }\n\n }\n @else if (type === 'radio' && options?.length) {\n <ion-radio-group class=\"dcf-width-1-1\" [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track $index) {\n <ion-item>\n <ion-radio\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [errorText]=\"getErrors(container)\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ option?.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if (type === 'select') {\n <div>\n <ion-select\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [interface]=\"interface\"\n [mode]=\"'md'\"\n [hidden]=\"hidden || !options?.length\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"label | translate\"\n [value]=\"value\"\n (click)=\"openSelectOptions($event, interface)\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [interface]=\"interface\" #component>\n @if (options?.length) {\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n }\n </ion-select>\n <div class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></div>\n @if (!options?.length) {\n <ion-text color=\"danger\">\n * {{ 'errors.empty_options' | translate:{'0': name} }}\n </ion-text>\n }\n </div>\n }\n @else {\n <ion-input\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [type]=\"type\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [max]=\"max !== undefined ? max : null\"\n [min]=\"min !== undefined ? min : null\"\n [pattern]=\"pattern !== undefined ? pattern : null\"\n [step]=\"step !== undefined ? step : null\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [label]=\"label | translate\" #component />\n }\n </div>\n </ng-container>\n } @else {\n <div>\n <p class=\"dcf-error\">\n {{ 'errors.form.control' | translate:{'0': name} }}\n </p>\n </div>\n }\n\n}\n\n","import { AfterViewInit, Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from \"@angular/core\";\nimport { FormArray, FormGroup } from \"@angular/forms\";\nimport { CrudOperations, OperationKeys } from \"@decaf-ts/db-decorators\";\nimport { Model } from \"@decaf-ts/decorator-validation\";\nimport { NgxFormService } from \"../services/NgxFormService\";\nimport { ICrudFormEvent, IFormElement } from \"./interfaces\";\nimport { FieldUpdateMode, FormParent, HTMLFormTarget } from \"./types\";\nimport { ICrudFormOptions, IRenderedModel } from \"./interfaces\";\nimport { ActionRoles, ComponentEventNames } from \"./constants\";\nimport { NgxParentComponentDirective } from \"./NgxParentComponentDirective\";\nimport { NgxFormFieldDirective } from \"./NgxFormFieldDirective\";\nimport { generateRandomValue } from \"../utils\";\nimport { timer } from \"rxjs\";\nimport { FieldDefinition, UIFunctionLike, UIModelMetadata } from \"@decaf-ts/ui-decorators\";\n\n@Directive()\nexport abstract class NgxFormDirective extends NgxParentComponentDirective implements OnInit, AfterViewInit, IFormElement, OnDestroy, IRenderedModel {\n\n\n /**\n * @description Reactive form group associated with this fieldset.\n * @summary The FormGroup instance that contains all form controls within this fieldset.\n * Used for form validation, value management, and integration with Angular's reactive forms.\n *\n * @type {FormGroup}\n */\n @Input()\n parentFormId!: string;\n\n /**\n * @description Indicates whether this form is being used inside a modal dialog.\n * @summary When true, the form may alter its submit/reset behavior to integrate\n * with modal lifecycle (for example, emitting cancel events instead of\n * navigating back). Useful for components rendered inside Ionic/Angular\n * modal containers where navigation/back behavior differs from standard pages.\n *\n * Typical effects:\n * - `handleReset` will emit a cancel event instead of performing a navigation\n * - `ngAfterViewInit` checks for modal context to adjust change detection\n *\n * @type {boolean}\n * @default false\n */\n @Input()\n modalForm: boolean = false;\n\n\n /**\n * @description Reference to the reactive form DOM element.\n * @summary ViewChild reference that provides direct access to the form's DOM element.\n * This enables programmatic manipulation of the form element and access to native\n * HTML form properties and methods when needed.\n *\n * @type {ElementRef}\n */\n @ViewChild('component', { static: false, read: ElementRef })\n override component!: ElementRef;\n\n\n /**\n * @description Field update trigger mode for form validation.\n * @summary Determines when form field validation should be triggered. Options include\n * 'change', 'blur', or 'submit'. This affects the user experience by controlling\n * when validation feedback is shown to the user during form interaction.\n *\n * @type {FieldUpdateMode}\n * @default 'change'\n */\n @Input()\n updateOn: FieldUpdateMode = 'change';\n\n /**\n * @description Form submission target specification.\n * @summary Specifies where to display the response after form submission, similar\n * to the HTML form target attribute. Options include '_self', '_blank', '_parent',\n * '_top', or a named frame. Controls the browser behavior for form responses.\n *\n * @type {HTMLFormTarget}\n * @default '_self'\n */\n @Input()\n target: HTMLFormTarget = '_self';\n\n /**\n * @description HTTP method or submission strategy for the form.\n * @summary Defines how the form should be submitted. 'get' and 'post' correspond\n * to standard HTTP methods for traditional form submission, while 'event' uses\n * Angular event-driven submission for single-page application workflows.\n *\n * @type {'get' | 'post' | 'event'}\n * @default 'event'\n */\n @Input()\n method: 'get' | 'post' | 'event' = 'event';\n\n /**\n * @description Configuration options for the CRUD form behavior.\n * @summary Contains various configuration settings that control form rendering,\n * validation, and behavior. These options are merged with default settings\n * during component initialization to customize the form's functionality.\n *\n * @type {ICrudFormOptions}\n */\n @Input()\n options!: ICrudFormOptions;\n\n\n /**\n * @description Optional action identifier for form submission context.\n * @summary Specifies a custom action name that will be included in the submit event.\n * If not provided, defaults to the standard submit event constant. Used to\n * distinguish between different types of form submissions within the same component.\n *\n * @type {string | undefined}\n */\n @Input()\n action?: string;\n\n /**\n * @description The current CRUD operation being performed.\n * @summary Specifies the type of operation this form is handling (CREATE, READ, UPDATE, DELETE).\n * This is a required input that determines form behavior, validation rules, and available actions.\n * The operation affects form state, button visibility, and submission logic.\n *\n * @type {CrudOperations}\n * @required\n */\n @Input({ required: true })\n override operation: CrudOperations = OperationKeys.CREATE;\n\n /**\n * @description Custom event handlers for form actions.\n * @summary A record of event handler functions keyed by event names that can be\n * triggered during form operations. These handlers provide extensibility for\n * custom business logic and can be invoked for various form events and actions.\n *\n * @type {Record<string, UIFunctionLike>}\n */\n @Input()\n override handlers!: Record<string, UIFunctionLike>;\n\n /**\n * @description Angular reactive FormGroup for form state management.\n * @summary The FormGroup instance that manages all form controls, validation,\n * and form state. This is the main interface for accessing form values and\n * controlling form behavior. May be undefined for read-only operations.\n *\n * @type {FormGroup | undefined}\n */\n @Input()\n formGroup: FormParent | undefined = undefined;\n\n /**\n * @description Unique identifier for the form renderer.\n * @summary A unique string identifier used to register and manage this form\n * instance within the NgxFormService. This ID is also used as the HTML id\n * attribute for the form element, enabling DOM queries and form management.\n *\n * @type {string}\n */\n @Input()\n rendererId!: string;\n\n\n /**\n * @description Event emitter for form submission events.\n * @summary Emits ICrudFormEvent objects when the form is submitted, providing\n * form data, component information, and any associated handlers to parent\n * components. This enables decoupled handling of form submission logic.\n *\n * @type {EventEmitter<ICrudFormEvent>}\n */\n @Output()\n submitEvent: EventEmitter<ICrudFormEvent> = new EventEmitter<ICrudFormEvent>();\n\n /**\n * @description Unique identifier for the current record instance.\n * @summary This property holds a unique string value that identifies the specific record being managed by the form.\n * It is automatically generated if not provided, ensuring each form instance has a distinct identifier.\n * The uid is used for tracking, referencing, and emitting events related to the current record, and may be used\n * in conjunction with the primary key for CRUD operations.\n *\n * @type {string}\n * @default Randomly generated 12-character string\n */\n @Input()\n allowClear: boolean = true;\n\n @Input()\n override match: boolean = false;\n\n // protected override enableDarkMode: boolean = true;\n\n // /**\n // * @description Angular change detection service.\n // * @summary Injected service that provides manual control over change detection cycles.\n // * This is essential for ensuring that programmatic DOM changes (like setting accordion\n // * attributes) are properly reflected in the component's state and trigger appropriate\n // * view updates when modifications occur outside the normal Angular change detection flow.\n // *\n // * @protected\n // * @type {ChangeDetectorRef}\n // * @memberOf CrudFormComponent\n // */\n // protected changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);\n\n // /**\n // * @description Angular Renderer2 service for safe DOM manipulation.\n // * @summary Injected service that provides a safe, platform-agnostic way to manipulate DOM elements.\n // * This service ensures proper handling of DOM operations across different platforms and environments,\n // * including server-side rendering and web workers.\n // *\n // * @protected\n // * @type {Renderer2}\n // * @memberOf CrudFormComponent\n // */\n // protected renderer: Renderer2 = inject(Renderer2);\n\n // /**\n // * @description Translation service for internationalization.\n // * @summary Injected service that provides translation capabilities for UI text.\n // * Used to translate button labels and validation messages based on the current locale.\n // *\n // * @protected\n // * @type {TranslateService}\n // * @memberOf CrudFormComponent\n // */\n // protected translateService: TranslateService = inject(TranslateService);\n\n\n protected activeFormGroupIndex: number = 0;\n\n get activeFormGroup(): FormParent {\n return this.getFormArrayIndex(this.activeFormGroupIndex) as FormParent;\n }\n\n /**\n * @description Component initialization lifecycle method.\n * @summary Initializes the component by setting up the logger, configuring form state\n * based on the operation type, and merging configuration options. For READ and DELETE\n * operations, the formGroup is set to undefined since these operations don't require\n * form input. Configuration options are merged with default settings.\n *\n * @returns {Promise<void>}\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n override async ngOnInit(model?: Model | string): Promise<void> {\n if(!this.uid)\n this.uid = generateRandomValue(12);\n // dont call super.ngOnInit to model conflicts\n if (this.operation === OperationKeys.READ || this.operation === OperationKeys.DELETE)\n this.formGroup = undefined;\n this.initialized = true;\n }\n\n async ngAfterViewInit(): Promise<void> {\n if (this.isModalChild)\n this.changeDetectorRef.detectChanges();\n }\n\n /**\n * @description Component cleanup lifecycle method.\n * @summary Performs cleanup operations when the component is destroyed.\n * Unregisters the FormGroup from the NgxFormService to prevent memory leaks\n * and ensure proper resource cleanup.\n *\n * @returns {void}\n */\n override ngOnDestroy(): void {\n super.ngOnDestroy();\n if (this.formGroup)\n NgxFormService.unregister(this.formGroup);\n }\n\n getFormArrayIndex(index: number): FormParent | undefined {\n if (!(this.formGroup instanceof FormArray) && this.formGroup) {\n if (this.formGroup.disabled)\n (this.formGroup as FormParent).enable();\n return this.formGroup;\n }\n\n const formGroup = (this.formGroup as FormArray).at(index) as FormGroup;\n if(formGroup.disabled)\n (formGroup as FormParent).enable();\n if (formGroup) {\n if (this.children.length) {\n const children = [... this.children];\n this.children = [];\n this.changeDetectorRef.detectChanges();\n this.children = [... children.map(child => {\n const props = (child.props || {}) as NgxFormFieldDirective;\n const name = props.name;\n const control = formGroup.get(name);\n child.props.value = control?.value;\n child.props.formGroup = formGroup;\n child.props.activeFormGroupIndex = index;\n child.props.formControl = control;\n return child;\n })];\n this.changeDetectorRef.detectChanges();\n }\n }\n return formGroup || undefined;\n }\n\n\n /**\n * @description Handles form reset or navigation back functionality.\n * @summary Provides different reset behavior based on the current operation.\n * For CREATE and UPDATE operations, resets the form to its initial state.\n * For READ and DELETE operations, navigates back in the browser history\n * since these operations don't have modifiable form data to reset.\n *\n * @returns {void}\n */\n handleReset(): void {\n if (this.isModalChild) {\n this.submitEvent.emit({\n data: null,\n component: this.componentName,\n name: ActionRoles.cancel,\n });\n return;\n }\n if (![OperationKeys.DELETE, OperationKeys.READ].includes(this.operation) && this.allowClear)\n return NgxFormService.reset(this.formGroup as FormGroup);\n this.location.back();\n }\n\n override async submit(event?: SubmitEvent, eventName?: string, componentName?: string): Promise<boolean | void> {\n if (event) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n const isValid = NgxFormService.validateFields(this.formGroup as FormGroup);\n if (this.isModalChild)\n this.changeDetectorRef.detectChanges();\n if (!isValid) {\n return false;\n }\n const data = NgxFormService.getFormData(this.formGroup as FormGroup);\n this.submitEvent.emit({\n data,\n component: componentName || this.componentName,\n name: eventName || this.action || ComponentEventNames.SUBMIT,\n handlers: this.handlers,\n });\n }\n\n /**\n * @description Updates the active form group and children for the specified page.\n * @summary Extracts the FormGroup for the given page from the FormArray and filters\n * the children to show only fields belonging to that page. Uses a timer to ensure\n * proper Angular change detection when updating the activeContent.\n *\n * @param {number} page - The page number to activate\n * @return {UIModelMetadata | UIModelMetadata[] | FieldDefinition | undefined}\n *\n * @private\n * @mermaid\n * sequenceDiagram\n * participant S as SteppedFormComponent\n * participant F as FormArray\n * participant T as Timer\n *\n * S->>F: Extract FormGroup at index (page - 1)\n * F-->>S: Return page FormGroup\n * S->>S: Set activeContent = undefined\n * S->>T: timer(10).subscribe()\n * T-->>S: Filter children for active page\n * S->>S: Set activeContent\n *\n * @memberOf SteppedFormComponent\n */\n protected override getActivePage(page: number): UIModelMetadata | UIModelMetadata[] | FieldDefinition | undefined {\n if (!(this.formGroup instanceof FormArray))\n this.formGroup = this.formGroup?.parent as FormArray;\n this.formGroup = (this.formGroup as FormArray).at(page - 1) as FormGroup;\n this.activePage = undefined;\n this.timerSubscription = timer(10).subscribe(() =>\n this.activePage = (this.children as UIModelMetadata[]).filter(c => c.props?.['page'] === page)\n );\n if(this.activePage)\n return this.activePage;\n return undefined;\n }\n\n}\n","/**\n * @module lib.components.card\n * @description Reusable Card UI component module.\n * @summary\n * Exports the `CardComponent`, a standalone Angular component built on Ionic's `IonCard` primitives.\n * The component exposes inputs to control visual style, content and layout and integrates with\n * the application's media service to react to dark-mode changes. See {@link CardComponent}.\n */\nimport { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';\nimport { Color } from '@ionic/core';\nimport { IonCard, IonCardContent, IonCardHeader, IonCardTitle , IonCardSubtitle } from '@ionic/angular/standalone';\nimport { Dynamic } from '../../engine/decorators';\nimport { NgxComponentDirective, } from '../../engine/NgxComponentDirective';\nimport { SafeHtml } from '@angular/platform-browser';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { AngularEngineKeys } from '../../engine/constants';\n\n/**\n * @description Reusable, presentational card UI component for use across the application.\n * @summary\n * CardComponent is a standalone Angular component built on Ionic's `IonCard` primitives.\n * It exposes several `@Input()` properties to control appearance and content:\n * `type`, `title`, `body`, `subtitle`, `color`, `separator`, `borders`, `inlineContent`, and `inlineContentPosition`.\n * The component integrates with the application's media service to react to dark-mode changes\n * and toggles the dark-palette CSS class on the host element accordingly.\n *\n * @param {('clear'|'shadow')} type - Visual rendering style for the card; 'clear' (default) or 'shadow'.\n * @param {string} title - Primary title text displayed in the card header.\n * @param {('small'|'default'|'blank')} body - Body size preset controlling padding/typography; defaults to 'default'.\n * @param {string} subtitle - Optional subtitle rendered under the title.\n * @param {Color} color - Ionic color token applied to the card header/title.\n * @param {boolean} separator - When true, renders a divider between header and body.\n * @param {boolean} borders - Controls whether borders are rendered; defaults to true.\n * @param {string|SafeHtml} inlineContent - Inline HTML/SafeHtml to render inside the body.\n * @param {('top'|'bottom')} inlineContentPosition - Where to render `inlineContent` relative to the body; defaults to 'bottom'.\n * @return {void}\n * @class CardComponent\n * @example\n * <ngx-decaf-card\n * [type]=\"'shadow'\"\n * [title]=\"'Account overview'\"\n * [subtitle]=\"'Summary for the current user'\"\n * [color]=\"'primary'\"\n * [separator]=\"true\"\n * [borders]=\"true\"\n * [inlineContent]=\"safeHtmlValue\"\n * inlineContentPosition=\"top\"\n * >\n * <!-- card content here -->\n * </ngx-decaf-card>\n *\n * @mermaid\n * sequenceDiagram\n * participant App as Consumer\n * participant Card as CardComponent\n * participant Media as MediaService\n * App->>Card: instantiate\n * Card->>Media: isDarkMode()\n * Media-->>Card: Observable<boolean> (isDark)\n * Card->>Card: toggleClass(..., isDark)\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-card',\n templateUrl: './card.component.html',\n styleUrls: ['./card.component.scss'],\n imports: [TranslatePipe, IonCard, IonCardHeader, IonCardContent, IonCardTitle, IonCardSubtitle],\n standalone: true,\n encapsulation: ViewEncapsulation.None,\n})\nexport class CardComponent extends NgxComponentDirective implements OnInit {\n\n /**\n * @description Visual rendering style for the card.\n * @summary Controls the card's surface treatment. Use 'clear' for a flat look or 'shadow' to add elevation.\n * @type {'clear'|'shadow'}\n * @default 'clear'\n */\n @Input()\n type: 'clear' | 'shadow' = 'clear';\n\n /**\n * @description Primary title text for the card header.\n * @summary Rendered prominently at the top of the card; consumers should pass a short, human-friendly string.\n * @type {string}\n * @default ''\n */\n @Input()\n title: string = '';\n\n /**\n * @description Body size preset for the card.\n * @summary Adjusts padding and typographic scale inside the card body. 'small' reduces spacing, 'blank' hides the body area.\n * @type {'small'|'default'|'blank'}\n * @default 'default'\n */\n @Input()\n body: 'small'| 'default' | 'blank' = 'default';\n\n /**\n * @description Optional subtitle shown below the title in the header area.\n * @summary Use for short secondary text such as an explanation or contextual note.\n * @type {string}\n * @default ''\n */\n @Input()\n subtitle: string = '';\n\n /**\n * @description Ionic color token applied to the card.\n * @summary When provided, the color token (for example 'primary' or 'tertiary') is applied to title/header elements where supported.\n * @type {Color}\n * @default ''\n */\n @Input()\n color: Color = '';\n\n /**\n * @description Toggle to render a visual separator between header and content.\n * @summary When true, a divider line (or equivalent styling) is rendered to separate the header from the body.\n * @type {boolean}\n * @default false\n */\n @Input()\n separator: boolean = false;\n\n /**\n * @description Controls whether the card renders borders.\n * @summary Set to false to remove borders for inline or transparent card designs. Marked `override` to explicitly shadow the base directive's value.\n * @type {boolean}\n * @default true\n */\n @Input()\n override borders: boolean = true;\n\n /**\n * @description Inline HTML or SafeHtml content to render inside the card body.\n * @summary Useful for short snippets of rich content provided by the consumer. When passing raw HTML prefer `SafeHtml` to avoid sanitization issues.\n * @type {string|SafeHtml}\n */\n @Input()\n inlineContent?: string | SafeHtml;\n\n /**\n * @description Position where `inlineContent` is rendered within the body.\n * @summary Pass 'top' to render inline content above the body or 'bottom' to render it below. Defaults to 'bottom'.\n * @type {'top'|'bottom'}\n */\n @Input()\n inlineContentPosition: 'top' | 'bottom' = 'bottom';\n\n /**\n * @description Internal component identifier used by the base `NgxComponentDirective`.\n * @summary Read-only-ish string identifying the concrete component class for instrumentation, styling helpers and debug logs.\n * @type {string}\n */\n protected override componentName: string = 'CardComponent';\n\n /**\n * @description Angular lifecycle hook: component initialization.\n * @summary\n * ngOnInit sets the component as initialized and subscribes to the application's media service\n * dark-mode observable. On each emission it updates the local isDarkMode flag and calls the\n * media service helper to toggle the dark-palette CSS class on the component host element.\n * The subscription uses the provided mediaService observable and performs side effects only.\n *\n * @return {void}\n */\n ngOnInit(): void {\n this.mediaService.isDarkMode().subscribe(isDark => {\n this.isDarkMode = isDark;\n this.mediaService.toggleClass(\n [this.component],\n AngularEngineKeys.DARK_PALETTE_CLASS,\n this.isDarkMode\n );\n });\n this.initialize();\n }\n}\n","<ion-card\n [class]=\"'dcf-card ' + className + ' ' + 'dcf-card-' + body\"\n [color]=\"color\"\n mode=\"md\"\n [class.dcf-card-separator]=\"separator\"\n [class.dcf-card-shadow]=\"type === 'shadow'\"\n [class.dcf-card-bordered]=\"borders\"\n [class.dcf-card-separator]=\"separator\"\n #component\n>\n @if (title || subtitle) {\n <ion-card-header>\n @if (title) {\n <ion-card-title>{{\n locale ? (title | translate) : title\n }}</ion-card-title>\n }\n @if (subtitle) {\n <ion-card-subtitle>{{\n locale ? (subtitle | translate) : subtitle\n }}</ion-card-subtitle>\n }\n </ion-card-header>\n }\n <ion-card-content>\n @if (inlineContent && inlineContentPosition === \"top\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n\n <ng-content slot=\"content\"></ng-content>\n\n @if (inlineContent && inlineContentPosition === \"bottom\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n </ion-card-content>\n</ion-card>\n","/**\n * @module module:lib/components/layout/layout.component\n * @description Layout component module.\n * @summary Provides `LayoutComponent` which offers a responsive grid layout\n * for arranging child components using configurable rows, columns and breakpoints.\n * Useful for building responsive UIs that render model and component renderers.\n *\n * @link {@link LayoutComponent}\n */\n\nimport { Component, Input, OnInit} from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Primitives } from '@decaf-ts/decorator-validation';\nimport { UIElementMetadata } from '@decaf-ts/ui-decorators';\nimport { NgxParentComponentDirective } from '../../engine/NgxParentComponentDirective';\nimport { KeyValue } from '../../engine/types';\nimport { IComponentProperties } from '../../engine/interfaces';\nimport { Dynamic } from '../../engine/decorators';\nimport { filterString } from '../../utils/helpers';\nimport { ComponentRendererComponent } from '../component-renderer/component-renderer.component';\nimport { ModelRendererComponent } from '../model-renderer/model-renderer.component';\nimport { LayoutGridGap } from '../../engine/types';\nimport { LayoutGridGaps } from '../../engine/constants';\nimport { CardComponent } from '../card/card.component';\n\n/**\n * @description Layout component for creating responsive grid layouts in Angular applications.\n * @summary This component provides a flexible grid system that can be configured with dynamic\n * rows and columns. It supports responsive breakpoints and can render child components within\n * the grid structure. The component extends NgxParentComponentDirective to inherit common functionality\n * and integrates with the model and component renderer systems.\n *\n * @class LayoutComponent\n * @extends {NgxParentComponentDirective}\n * @implements {OnInit}\n * @memberOf LayoutComponent\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-layout',\n templateUrl: './layout.component.html',\n styleUrls: ['./layout.component.scss'],\n imports: [TranslatePipe, CardComponent, ModelRendererComponent, ComponentRendererComponent],\n standalone: true,\n\n})\nexport class LayoutComponent extends NgxParentComponentDirective implements OnInit {\n\n /**\n * @description Media breakpoint for responsive behavior.\n * @summary Determines the responsive breakpoint at which the layout should adapt.\n * This affects how the grid behaves on different screen sizes, allowing for\n * mobile-first or desktop-first responsive design patterns. The breakpoint\n * is automatically processed to ensure compatibility with the UI framework.\n *\n * @type {UIMediaBreakPointsType}\n * @default 'medium'\n * @memberOf LayoutComponent\n */\n @Input()\n gap: LayoutGridGap = LayoutGridGaps.collapse;\n\n\n /**\n * @description Media breakpoint for responsive behavior.\n * @summary Determines the responsive breakpoint at which the layout should adapt.\n * This affects how the grid behaves on different screen sizes, allowing for\n * mobile-first or desktop-first responsive design patterns. The breakpoint\n * is automatically processed to ensure compatibility with the UI framework.\n *\n * @type {UIMediaBreakPointsType}\n * @default 'medium'\n * @memberOf LayoutComponent\n */\n @Input()\n grid: boolean = true;\n\n /**\n * @description Media breakpoint for responsive behavior.\n * @summary Determines the responsive breakpoint at which the layout should adapt.\n * This affects how the grid behaves on different screen sizes, allowing for\n * mobile-first or desktop-first responsive design patterns. The breakpoint\n * is automatically processed to ensure compatibility with the UI framework.\n *\n * @type {UIMediaBreakPointsType}\n * @default 'medium'\n * @memberOf LayoutComponent\n */\n @Input()\n flexMode: boolean = false;\n\n /**\n * @description Media breakpoint for responsive behavior.\n * @summary Determines the responsive breakpoint at which the layout should adapt.\n * This affects how the grid behaves on different screen sizes, allowing for\n * mobile-first or desktop-first responsive design patterns. The breakpoint\n * is automatically processed to ensure compatibility with the UI framework.\n *\n * @type {UIMediaBreakPointsType}\n * @default 'medium'\n * @memberOf LayoutComponent\n */\n @Input()\n rowCard: boolean = true;\n\n /**\n * @description Maximum number of columns allowed in the grid layout.\n * @summary Specifies the upper limit for the number of columns that can be displayed in the grid.\n * This ensures that the layout remains visually consistent and prevents excessive columns\n * from being rendered, which could disrupt the design.\n *\n * @type {number}\n * @default 6\n * @memberOf LayoutComponent\n */\n @Input()\n private maxColsLength: number = 6;\n\n /**\n * @description Creates an instance of LayoutComponent.\n * @summary Initializes a new LayoutComponent with the component name \"LayoutComponent\".\n * This constructor calls the parent NgxParentComponentDirective constructor to set up base\n * functionality and component identification.\n *\n * @memberOf LayoutComponent\n */\n constructor() {\n super('LayoutComponent')\n }\n\n /**\n * @description Getter that converts columns input to an array format.\n * @summary Transforms the cols input property into a standardized string array format.\n * When cols is a number, it creates an array with that many empty string elements.\n * When cols is already an array, it returns the array as-is. This normalization\n * ensures consistent handling of column definitions in the template.\n *\n * @type {string[]}\n * @readonly\n * @memberOf LayoutComponent\n */\n get _cols(): string[] {\n let cols = this.cols;\n if(typeof cols === Primitives.BOOLEAN) {\n cols = 1;\n this.flexMode = true;\n }\n if (typeof cols === Primitives.NUMBER)\n cols = Array.from({length: Number(cols)}, () => '');\n return cols as string[];\n }\n\n\n /**\n * @description Calculates the number of columns for a given row.\n * @summary Determines the effective number of columns in a row based on the row's column definitions,\n * the total number of columns in the layout, and the maximum allowed columns.\n *\n * @param {KeyValue | IComponentProperties} row - The row object containing column definitions.\n * @returns {number} The number of columns for the row, constrained by the layout's maximum column limit.\n * @memberOf LayoutComponent\n */\n getRowColsLength(row: KeyValue | IComponentProperties): number {\n let length: number = (row.cols as [])?.length ?? 1;\n const colsLength = (this.cols as [])?.length;\n const rowsLength = (typeof this.rows === Primitives.NUMBER ? this.rows : (this.rows as [])?.length) as number;\n if (length > this.maxColsLength)\n length = this.maxColsLength;\n\n if (length !== colsLength) {\n length = colsLength;\n if (this.flexMode) {\n length = row.cols.reduce((acc: number, curr: KeyValue) => {\n if (rowsLength > 1)\n return acc + (typeof curr['col'] === Primitives.NUMBER ? curr['col']: 1);\n return acc + (\n typeof curr['col'] === Primitives.NUMBER ? curr['col']:\n curr['col'] === 'full' ? 0 : curr['col']\n );\n }, 0);\n }\n }\n return length;\n }\n\n /**\n * @description Getter that converts rows input to an array format.\n * @summary Transforms the rows input property into a standardized string array format.\n * When rows is a number, it creates an array with that many empty string elements.\n * When rows is already an array, it returns the array as-is. This normalization\n * ensures consistent handling of row definitions in the template.\n *\n * @type {KeyValue[]}\n * @readonly\n * @memberOf LayoutComponent\n */\n get _rows(): KeyValue[] {\n let rows = this.rows;\n if (typeof rows === Primitives.NUMBER)\n rows = Array.from({length: Number(rows)}, () => ({title: ''})) as Partial<IComponentProperties>[];\n\n let rowsLength = (rows as string[]).length;\n if (rowsLength === 1 && this.flexMode) {\n this.children.forEach((child) => {\n const row = child?.['props'].row || 1;\n if (row > rowsLength) {\n rowsLength += 1;\n (rows as KeyValue[]).push({title: ''});\n }\n });\n\n this.rows = rowsLength;\n };\n return (rows as KeyValue[]).map((row, index) => {\n const rowsLength = this.rows;\n return {\n title: typeof row === Primitives.STRING ? row : row?.['title'] || \"\",\n cols: this.children.filter((child) => {\n let row = (child as UIElementMetadata).props?.['row'] ?? 1;\n if (row > rowsLength)\n row = rowsLength as number;\n child['col'] = (child as UIElementMetadata).props?.['col'] ?? (this.cols as string[])?.length ?? 1;\n if (row === index + 1)\n return child;\n })\n };\n }).map((row, index) => {\n const colsLength = this.getRowColsLength(row);\n row.cols = row.cols.map((c: KeyValue) => {\n let {col} = c;\n if (typeof col === Primitives.STRING)\n col = col === 'half' ? '1-2' : col === 'full' ? '1-1': col;\n\n if (!this.flexMode) {\n if (typeof col === Primitives.NUMBER) {\n col = (col === colsLength ?\n `1-1` : `${col}-${colsLength}`);\n }\n } else {\n\n if (typeof col === Primitives.NUMBER)\n col = (colsLength <= this.maxColsLength) ? `${col}-${colsLength}` : `${index + 1}-${col}`;\n col = ['2-4', '3-6'].includes(col) ? `1-2` : col;\n }\n col = `dcf-child-${col}-${this.breakpoint} dcf-width-${col}`;\n const childClassName = c?.['props']?.className || '';\n const colClass = `${col}@${this.breakpoint} ${filterString(childClassName ,'-width-')}`;\n // to prevent layout glitches, before send class to child component remove width classes\n if (c?.['props']?.className)\n c['props'].className = filterString(c?.['props']?.className ,'-width-', false);\n return Object.assign(c, {colClass});\n })\n return row;\n })\n }\n\n\n\n\n /**\n * @description Angular lifecycle hook that runs after component initialization.\n * @summary Called once, after the first ngOnChanges(). This method triggers the\n * component's initialization process, which includes property parsing and grid\n * setup. It ensures the component is properly configured before rendering.\n *\n * @memberOf LayoutComponent\n */\n override async ngOnInit(): Promise<void> {\n super.parseProps(this);\n\n if (this.breakpoint)\n this.breakpoint = `${this.breakpoint.startsWith('x') ? this.breakpoint.substring(0,2) : this.breakpoint.substring(0,1)}`.toLowerCase();\n this.cols = this._cols;\n this.rows = this._rows;\n // if (this._rows.length === 1)\n // this.match = false;\n // if (this._cols.length === 1)\n // this.grid = false;\n this.initialized = true;\n this.changeDetectorRef.detectChanges();\n }\n}\n","<section class=\"dcf-layout-container\">\n @if (initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n @if (row?.cols?.length) {\n <div\n [id]=\"uid\"\n [class]=\"\n (!grid\n ? 'dcf-layout-row '\n : 'dcf-layout-row dcf-grid ' + 'dcf-grid-' + gap) +\n ' ' +\n (className || '')\n \"\n [class.dcf-grid-match]=\"match\"\n [class.dcf-grid-bordered]=\"borders\"\n >\n @if (row?.title?.length) {\n <div class=\"dcf-width-1-1 dcf-grid-title\">\n <h3 class=\"\">{{ row.title | translate }}</h3>\n </div>\n }\n @for (\n child of row.cols;\n track trackItemFn($index, child.col);\n let colIndex = $index\n ) {\n\n <div\n [class]=\"'dcf-grid-col ' + child.colClass\"\n [class.dcf-first-column]=\"$index === 0\"\n [class.dcf-layout-separator]=\"child.props?.separator ?? false\"\n >\n <div>\n\n @if (child.tag === \"ngx-decaf-crud-form\") {\n\n <ngx-decaf-card\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ngx-decaf-card>\n } @else {\n\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [parentForm]=\"parentForm || child.parentForm || child?.formGroup\"\n [children]=\"child?.children || []\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{ props: child.props }\"\n />\n }\n </div>\n </div>\n }\n </div>\n }\n }\n }\n</section>\n","/**\n * @module module:lib/components/crud-form/crud-form.component\n * @description CRUD form component module.\n * @summary Provides `CrudFormComponent` — a wrapper that composes dynamic form\n * fields and layout to produce create/read/update/delete forms with validation\n * and submission handling.\n *\n * @link {@link CrudFormComponent}\n */\n\nimport {\n Component\n} from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { IonButton, IonIcon } from '@ionic/angular/standalone';\nimport { Dynamic } from '../../engine/decorators';\nimport { DefaultFormReactiveOptions, ComponentEventNames } from '../../engine/constants';\nimport { NgxFormDirective } from '../../engine/NgxFormDirective';\nimport { ComponentRendererComponent } from '../../components/component-renderer/component-renderer.component';\nimport { LayoutComponent } from '../layout/layout.component';\n\n\n@Dynamic()\n@Component({\n standalone: true,\n selector: 'ngx-decaf-crud-form',\n templateUrl: './crud-form.component.html',\n styleUrls: ['./crud-form.component.scss'],\n imports: [ReactiveFormsModule, LayoutComponent, ComponentRendererComponent, IonButton, IonIcon],\n host: {'[attr.id]': 'uid'},\n})\n\nexport class CrudFormComponent extends NgxFormDirective {\n\n constructor() {\n super('CrudFormComponent');\n }\n\n /**\n * @description Component initialization lifecycle method.\n * @summary Initializes the component by setting up the logger, configuring form state\n * based on the operation type, and merging configuration options. For READ and DELETE\n * operations, the formGroup is set to undefined since these operations don't require\n * form input. Configuration options are merged with default settings.\n *\n * @returns {Promise<void>}\n * @memberOf CrudFormComponent\n */\n override async ngOnInit(): Promise<void> {\n this.options = Object.assign(\n {},\n DefaultFormReactiveOptions,\n this.options || {},\n );\n await super.ngOnInit();\n }\n\n /**\n * @description Handles delete operations by emitting delete events.\n * @summary Processes delete requests by emitting a submit event with the\n * record's unique identifier as data. This allows parent components to\n * handle the actual deletion logic while maintaining separation of concerns.\n * The event includes the uid and standard component identification.\n *\n * @returns {void}\n * @memberOf CrudFormComponent\n */\n handleDelete(): void {\n this.submitEvent.emit({\n data: this.modelId,\n component: 'CrudFormComponent',\n name: ComponentEventNames.SUBMIT,\n });\n }\n}\n","@if (operation !== 'read' && operation !== 'delete') {\n <form\n [class]=\"'dcf-form-grid ' + operation\" #component\n [id]=\"rendererId\"\n [formGroup]=\"formGroup\"\n (ngSubmit)=\"submit($event)\"\n novalidate\n [target]=\"target\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n <ngx-decaf-layout\n [className]=\"'dcf-crud-form-grid dcf-grid-nested '\"\n [children]=\"children || []\"\n [parentForm]=\"formGroup || parentForm\"\n [match]=\"match ?? false\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [cols]=\"cols\" />\n }\n @if (initialized) {\n <div class=\"dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left\">\n <div>\n <ion-button type=\"submit\" [expand]=\"action ? 'block' : 'default'\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{ action ? action : options.buttons.submit.text}}\n </ion-button>\n </div>\n @if (!action) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n Back\n </ion-button>\n </div>\n }\n </div>\n }\n\n </form>\n} @else {\n <section [class]=\"'dcf-grid dcf-grid-small dcf-child-width-1-1 dcf-form-grid ' + operation\" #component [id]=\"uid\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n @for (child of children; track $index) {\n <div class=\"dcf-form-item\">\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n [projectable]=\"false\"\n [children]=\"child?.children || []\"\n [globals]=\"{props: child.props}\"\n />\n </div>\n }\n }\n </section>\n <section [class]=\"'dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if ([OperationKeys.READ, OperationKeys.DELETE].includes(operation) && modelId) {\n <div>\n <ion-button\n (click)=\"handleDelete()\"\n color=\"danger\"\n type=\"button\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n Delete\n </ion-button>\n </div>\n\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n\n <div>\n <ion-button\n type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n </div>\n }\n\n @if (options.buttons.clear) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{ [OperationKeys.DELETE, OperationKeys.READ, OperationKeys.UPDATE].includes(operation) ? 'Back' : options.buttons.clear?.text}}\n </ion-button>\n </div>\n\n }\n </section>\n}\n\n","import { Directive, ElementRef, inject, Input, OnInit } from '@angular/core';\nimport { NgxMediaService } from '../services/NgxMediaService';\nimport { HttpClient } from '@angular/common/http';\n\n@Directive({\n selector: '[ngx-decaf-svg]',\n standalone: true\n})\nexport class NgxSvgDirective implements OnInit {\n\n @Input('ngx-decaf-svg')\n path!: string;\n\n mediaService: NgxMediaService = inject(NgxMediaService);\n element: ElementRef = inject(ElementRef);\n\n http: HttpClient = inject(HttpClient);\n\n ngOnInit(): void {\n this.path = this.path?.trim() || this.element?.nativeElement?.getAttribute('src')?.trim() || '';\n if (this.path)\n this.mediaService.loadSvgObserver(this.http, this.path, this.element.nativeElement);\n }\n}\n","import { Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';\nimport { Color } from '@ionic/core';\nimport { IonButton, IonIcon } from '@ionic/angular/standalone';\nimport * as allIcons from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { Dynamic } from '../../engine/decorators';\nimport { NgxMediaService } from '../../services/NgxMediaService';\nimport { NgxSvgDirective } from '../../directives/NgxSvgDirective';\n\n\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-icon',\n templateUrl: './icon.component.html',\n styleUrls: ['./icon.component.scss'],\n imports: [NgxSvgDirective, IonIcon, IonButton],\n standalone: true,\n host: {'[attr.id]': 'uid', '[attr.aria-hidden]': '!button'},\n})\nexport class IconComponent implements OnInit {\n\n /** @description Reference to the component's native DOM element.\n * @summary Provides direct access to the native DOM element of the component through Angular's\n * ViewChild decorator. This reference can be used to manipulate the DOM element directly,\n * apply custom styles, or access native element properties and methods. The element is\n * identified by the 'component' template reference variable.\n * @type {ElementRef}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @ViewChild('component', { read: ElementRef, static: false })\n component!: ElementRef;\n\n @Input()\n name?: string;\n\n @Input()\n color: Color = \"dark\";\n\n @Input()\n slot?: 'start' | 'end' | 'icon-only' = 'icon-only';\n\n @Input()\n button: boolean = false\n\n @Input()\n buttonFill: 'clear' | 'outline' | 'solid' | 'default' = 'clear';\n\n @Input()\n buttonShape: 'round' | 'default' = 'round';\n\n @Input()\n width!: string;\n\n @Input()\n size?: 'large' | 'small' | 'default' = 'default';\n\n type: 'image' | 'ionic' = 'ionic';\n\n isSvg: boolean = false;\n\n initialized: boolean = false;\n\n @Input()\n inline: boolean = false;\n\n isDarkMode: boolean = false;\n\n mediaService: NgxMediaService = new NgxMediaService();\n\n constructor() {\n addIcons(allIcons);\n }\n\n ngOnInit(): void {\n if(this.button)\n this.slot = 'icon-only';\n if(this.name?.includes('.')) {\n this.type = 'image';\n this.isSvg = this.name.endsWith('.svg');\n }\n this.mediaService.isDarkMode().subscribe(isDark => {\n this.isDarkMode = isDark;\n });\n this.initialized = true;\n }\n}\n","<div class=\"dcf-icon\" #component>\n @if (initialized) {\n @if (button) {\n <ion-button [fill]=\"buttonFill\" [shape]=\"buttonShape\" [color]=\"isDarkMode ? 'light' : color\" [size]=\"size\">\n @if (type === \"image\") {\n @if (isSvg) {\n <span\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [class]=\"color ? 'dcf-color-' + color : ''\"\n [style.width]=\"width\"\n [ngx-decaf-svg]=\"name\"\n >\n ></span\n >\n } @else {\n <img\n aria-hidden=\"true\"\n [alt]=\"name\"\n [title]=\"name\"\n [slot]=\"slot\"\n [src]=\"name\"\n [style.width]=\"width\"\n title=\"icon\"\n />\n }\n } @else {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [ios]=\"name\"\n [md]=\"name\"\n [color]=\"isDarkMode ? 'light' : color\"\n [name]=\"name\"\n />\n }\n </ion-button>\n } @else {\n @if (type === \"image\") {\n @if (isSvg) {\n <span\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [class]=\"color ? 'dcf-color-' + color : ''\"\n [style.width]=\"width\"\n [ngx-decaf-svg]=\"name\"\n >\n </span>\n } @else {\n <img\n aria-hidden=\"true\"\n [alt]=\"name\"\n [title]=\"name\"\n [slot]=\"slot\"\n [src]=\"name\"\n [style.width]=\"width\"\n title=\"icon\"\n />\n }\n }\n @if (type === \"ionic\") {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"slot\"\n [ios]=\"name\"\n [md]=\"name\"\n [size]=\"size\"\n [color]=\"isDarkMode ? 'light' : color\"\n [name]=\"name\"\n />\n }\n }\n }\n</div>\n","/**\n * @module module:lib/components/empty-state/empty-state.component\n * @description Empty state component module.\n * @summary Exposes `EmptyStateComponent` which displays a standardized empty\n * state UI with optional icon, title, subtitle and action button. Supports\n * localization and sanitized HTML for dynamic subtitles.\n *\n * @link {@link EmptyStateComponent}\n */\n\nimport { Component, inject, Input, OnInit } from '@angular/core';\nimport { IonButton } from '@ionic/angular/standalone';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Dynamic } from '../../engine/decorators';\nimport { ElementSizes } from '../../engine/constants';\nimport { ElementSize, StringOrBoolean } from '../../engine/types';\nimport { stringToBoolean } from '../../utils/helpers';\nimport { FunctionLike } from '../../engine/types';\nimport { CardComponent } from '../card/card.component';\nimport { IconComponent } from '../../components/icon/icon.component';\n\n\n/**\n * @description Component for displaying empty state messages with optional actions.\n * @summary This component provides a standardized way to display empty state messages\n * when no data is available or when a user needs to take an action to populate content.\n * It includes customizable title, subtitle, icon, and action button elements that can be\n * styled and configured through input properties. The component supports localization\n * and can trigger navigation or custom actions when the button is clicked.\n *\n * @mermaid\n * classDiagram\n * class EmptyStateComponent {\n * +string title\n * +string titleColor\n * +string subtitle\n * +string subtitleColor\n * +StringOrBoolean showIcon\n * +string icon\n * +string iconSize\n * +string iconColor\n * +string|Function buttonLink\n * +string buttonText\n * +string buttonFill\n * +string buttonColor\n * +string buttonSize\n * +string searchValue\n * -Router Router\n * +ngOnInit()\n * +handleClick()\n * }\n * EmptyStateComponent --|> NgxBaseComponentDirective\n * EmptyStateComponent --|> OnInit\n *\n * @extends {NgxBaseComponentDirective}\n * @implements {OnInit}\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-empty-state',\n templateUrl: './empty-state.component.html',\n styleUrls: ['./empty-state.component.scss'],\n standalone: true,\n imports: [\n IconComponent,\n TranslatePipe,\n IonButton,\n CardComponent\n ]\n})\nexport class EmptyStateComponent extends CardComponent implements OnInit {\n\n\n /**\n * @description The main title displayed in the empty state.\n * @summary Specifies the primary message to show in the empty state component.\n * This text is typically used to inform the user about why they're seeing an empty view.\n * If translatable is true, this will be processed through the localization system.\n *\n * @type {string}\n * @default \"title\"\n * @memberOf EmptyStateComponent\n */\n @Input()\n override title: string = \"title\";\n\n /**\n * @description The color of the title text.\n * @summary Specifies the color for the title text using the application's color system.\n * The value should correspond to a color variable defined in the application's theme.\n * The component will automatically prefix this with \"color-\" to create the CSS class.\n *\n * @type {string}\n * @default 'gray-6'\n * @memberOf EmptyStateComponent\n */\n @Input()\n titleColor: string = 'gray-6';\n\n /**\n * @description The secondary message displayed in the empty state.\n * @summary Provides additional context or instructions below the main title.\n * This text is typically used to guide the user on what actions they can take.\n * If translatable is true, this will be processed through the localization system.\n *\n * @type {string | undefined}\n * @memberOf EmptyStateComponent\n */\n @Input()\n override subtitle: string = \"\";\n\n\n /**\n * @description The color of the subtitle text.\n * @summary Specifies the color for the subtitle text using the application's color system.\n * The value should correspond to a color variable defined in the application's theme.\n * The component will automatically prefix this with \"color-\" to create the CSS class.\n *\n * @type {string}\n * @default 'gray-4'\n * @memberOf EmptyStateComponent\n */\n @Input()\n subtitleColor: string = 'gray-4';\n\n /**\n * @description Controls whether the icon is displayed.\n * @summary Determines if the visual icon should be shown in the empty state.\n * This can be provided as a boolean or a string that will be converted to a boolean.\n * Icons help visually communicate the empty state context to users.\n *\n * @type {StringOrBoolean}\n * @default true\n * @memberOf EmptyStateComponent\n */\n @Input()\n showIcon: StringOrBoolean = true;\n\n /**\n * @description The name of the icon to display.\n * @summary Specifies which icon to show when showIcon is true.\n * The component uses the icon system defined in the application,\n * and this value should correspond to an available icon name.\n *\n * @type {string}\n * @default \"folder-open-outline\"\n * @memberOf EmptyStateComponent\n */\n @Input()\n icon: string = \"folder-open-outline\";\n\n /**\n * @description The size of the displayed icon.\n * @summary Controls the size of the icon shown in the empty state.\n * Can be either 'large' or 'small' to accommodate different layout needs.\n *\n * @type {'large' | 'small' | undefined}\n * @default 'large'\n * @memberOf EmptyStateComponent\n */\n @Input()\n iconSize?: Extract<ElementSize, 'large' | 'small'> = ElementSizes.large;\n\n /**\n * @description The color of the displayed icon.\n * @summary Specifies the color for the icon using Ionic's predefined color system.\n * This allows the icon to match the application's color scheme.\n *\n * @type {string}\n * @default 'medium'\n * @memberOf EmptyStateComponent\n */\n @Input()\n iconColor?: string = 'medium';\n\n /**\n * @description The navigation target or action for the button.\n * @summary Specifies where the button should navigate to when clicked or what function\n * it should execute. This can be either a URL string or a function that handles navigation.\n * When not provided, the button will not perform any action.\n *\n * @type {string | FunctionLike | undefined}\n * @memberOf EmptyStateComponent\n */\n @Input()\n buttonLink?: string | FunctionLike;\n\n /**\n * @description The text displayed on the action button.\n * @summary Specifies the label for the action button in the empty state.\n * If translatable is true, this will be processed through the localization system.\n * If not provided, the button will not display any text.\n *\n * @type {string | undefined}\n * @memberOf EmptyStateComponent\n */\n @Input()\n buttonText?: string;\n\n /**\n * @description The fill style of the action button.\n * @summary Controls the visual style of the button using Ionic's button fill options.\n * 'solid' creates a button with a solid background, 'outline' creates a button with\n * just a border, and 'clear' creates a button with no background or border.\n *\n * @type {'clear' | 'solid' | 'outline'}\n * @default 'solid'\n * @memberOf EmptyStateComponent\n */\n @Input()\n buttonFill: 'clear' | 'solid' | 'outline' = 'solid';\n\n /**\n * @description The color of the action button.\n * @summary Specifies the color for the button using Ionic's color system.\n * This allows the button to match the application's color scheme.\n *\n * @type {string}\n * @default 'primary'\n * @memberOf EmptyStateComponent\n */\n @Input()\n buttonColor: string = 'primary';\n\n /**\n * @description The size of the action button.\n * @summary Controls the size of the button shown in the empty state.\n * Can be 'large', 'small', or 'default' to accommodate different layout needs.\n *\n * @type {'large' | 'small' | 'default'}\n * @default 'default'\n * @memberOf EmptyStateComponent\n */\n @Input()\n buttonSize: Extract<ElementSize, 'large' | 'small' | 'default'> = 'default';\n\n /**\n * @description The search value that resulted in no results.\n * @summary When the empty state is shown due to a search with no results,\n * this property can hold the search term that was used. This can be displayed\n * in the empty state message to provide context to the user.\n *\n * @type {string}\n * @memberOf EmptyStateComponent\n */\n @Input()\n searchValue!: string;\n\n\n /**\n * @description Sanitizer instance for bypassing security and sanitizing HTML content.\n * @summary Used to sanitize dynamic HTML content, ensuring it is safe to render in the DOM.\n * @type {DomSanitizer}\n * @memberOf EmptyStateComponent\n */\n private sanitizer: DomSanitizer = inject(DomSanitizer);\n\n /**\n * @description The sanitized subtitle for search results.\n * @summary Holds the processed and sanitized HTML content for the subtitle when a search yields no results.\n * @type {SafeHtml}\n * @memberOf EmptyStateComponent\n */\n searchSubtitle!: SafeHtml;\n\n /**\n * @description Flag to enable creation by model route.\n * @summary Indicates whether the component should allow creation of new items via a model route when no button link is provided.\n * @type {boolean}\n * @default false\n * @memberOf EmptyStateComponent\n */\n enableCreationByModelRoute: boolean = false;\n\n\n /**\n * @description Creates an instance of EmptyStateComponent.\n * @summary Initializes a new EmptyStateComponent by calling the parent class constructor\n * with the component name for logging and identification purposes. This component provides\n * a standardized way to display empty state messages with optional icons and action buttons.\n *\n * @memberOf EmptyStateComponent\n */\n constructor() {\n super(\"EmptyStateComponent\");\n this.type = 'clear';\n this.componentName = \"EmptyStateComponent\";\n this.enableDarkMode = true;\n }\n\n /**\n * @description Initializes the component after Angular first displays the data-bound properties.\n * @summary Sets up the component by processing boolean inputs, applying localization to text\n * elements if translation is enabled, and formatting CSS classes for title and subtitle colors.\n * This method prepares the component for user interaction by ensuring all properties are\n * properly initialized and localized.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant E as EmptyStateComponent\n *\n * A->>E: ngOnInit()\n * E->>E: Process translatable flag\n * E->>E: Process showIcon flag\n * E->>E: Get locale settings\n * alt translatable is true\n * E->>E: Localize title\n * E->>E: Localize subtitle\n * E->>E: Localize buttonText\n * end\n * E->>E: Format title CSS class\n * E->>E: Format subtitle CSS class\n *\n * @return {Promise<void>}\n * @memberOf EmptyStateComponent\n */\n override async ngOnInit(): Promise<void> {\n super.ngOnInit();\n this.showIcon = stringToBoolean(this.showIcon);\n this.titleColor = `dcf-title dcf-color-${this.titleColor}`;\n this.subtitleColor = `dcf-subtitle dcf-color-${this.subtitleColor}`;\n if (this.searchValue)\n this.searchSubtitle = await this.getSearchSubtitle(this.subtitle as string);\n if (!this.buttonLink && this.model && this.route)\n this.enableCreationByModelRoute = true;\n }\n\n /**\n * @description Handles click events on the action button.\n * @summary This method is triggered when the user clicks the action button in the empty state\n * component. It supports three navigation patterns: 1) no action when buttonLink is not provided,\n * 2) custom function execution when buttonLink is a function, and 3) navigation to a specific URL\n * when buttonLink is a string. This flexibility allows the empty state to trigger various actions\n * based on the context in which it's used.\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant E as EmptyStateComponent\n * participant N as Router\n *\n * U->>E: Click action button\n * E->>E: handleClick()\n * alt buttonLink is not provided\n * E-->>U: Return false (no action)\n * else buttonLink is a function\n * E->>E: Execute buttonLink function\n * E-->>U: Return function result\n * else buttonLink is a URL string\n * E->>N: navigateForward(buttonLink)\n * N-->>E: Return navigation result\n * E-->>U: Return navigation result\n * end\n *\n * @return {boolean | void | Promise<boolean> | FunctionLike}\n * - false if no action is taken\n * - The result of the buttonLink function if it's a function\n * - A Promise resolving to the navigation result if buttonLink is a URL\n * @memberOf EmptyStateComponent\n */\n handleClick(): boolean | void | Promise<boolean> | FunctionLike {\n const fn = this.buttonLink;\n if (!fn)\n return false;\n if (fn instanceof Function)\n return fn() as FunctionLike;\n return this.router.navigate([fn as string]);\n }\n\n\n /**\n * @description Generates a localized and sanitized subtitle for search results.\n * @summary This method takes a content string, typically the subtitle, and processes it\n * through the translation service. It replaces a placeholder ('0') with the actual\n * search value, then sanitizes the result to safely use as HTML. This is particularly\n * useful for displaying dynamic, localized messages in the empty state when a search\n * yields no results.\n *\n * @param {string} content - The content string to be translated and processed\n * @return {Promise<SafeHtml>} A promise that resolves to a sanitized HTML string\n *\n * @mermaid\n * sequenceDiagram\n * participant E as EmptyStateComponent\n * participant T as TranslateService\n * participant S as DomSanitizer\n *\n * E->>T: instant(content, {'0': searchValue})\n * T-->>E: Return translated string\n * E->>S: bypassSecurityTrustHtml(translatedString)\n * S-->>E: Return sanitized SafeHtml\n *\n * @memberOf EmptyStateComponent\n */\n async getSearchSubtitle(content: string): Promise<SafeHtml> {\n const result = await this.translate(content, {'0': this.searchValue});\n return this.sanitizer.bypassSecurityTrustHtml(result);\n }\n}\n","<div class=\"decaf-empty-state-component\" #component>\n <ngx-decaf-card [className]=\"className\"\n [borders]=\"borders\"\n [body]=\"body\"\n >\n @if (icon && showIcon) {\n <div class=\"dcf-icon-container\">\n <ngx-decaf-icon\n aria-hidden=\"true\"\n [name]=\"icon\"\n [size]=\"iconSize\"\n [color]=\"!this.isDarkMode ? iconColor : ''\"\n />\n </div>\n }\n @if (title) {\n <h4 class=\"dcf-ititle\" [class]=\"isDarkMode ? 'light' : titleColor\" [innerHTML]=\"title\"></h4>\n }\n @if (subtitle) {\n <p [class]=\"isDarkMode ? 'light' : subtitleColor\" [innerHTML]=\"searchValue ? searchSubtitle : subtitle\"></p>\n }\n @if (!enableCreationByModelRoute) {\n @if (buttonLink && buttonText) {\n <div>\n <ion-button\n [size]=\"buttonSize\"\n [fill]=\"buttonFill\"\n [color]=\"buttonColor\"\n (click)=\"handleClick()\">\n {{ buttonText }}\n </ion-button>\n </div>\n }\n } @else {\n\n <div>\n <ion-button\n class=\"dcf-margin-top\"\n [size]=\"buttonSize\"\n [fill]=\"buttonFill\"\n [color]=\"buttonColor\"\n (click)=\"changeOperation(OperationKeys.CREATE)\" fill=\"clear\">\n {{ buttonText?.length ? buttonText : locale + '.button_create' | translate }}\n </ion-button>\n </div>\n\n }\n </ngx-decaf-card>\n</div>\n","/**\n * @module module:lib/components/fieldset/fieldset.component\n * @description Fieldset component module.\n * @summary Provides `FieldsetComponent` — a dynamic, collapsible fieldset container\n * for grouping form controls with validation, reorder and add/remove capabilities.\n * Ideal for complex forms that require nested groupings and dynamic items.\n *\n * @link {@link FieldsetComponent}\n */\n\nimport {\n AfterViewInit,\n Component,\n Input,\n ViewChild,\n OnInit,\n} from '@angular/core';\nimport {\n FormArray,\n FormControl,\n FormGroup,\n ReactiveFormsModule,\n} from '@angular/forms';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n alertCircleOutline,\n createOutline,\n addOutline,\n trashOutline,\n} from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport {\n IonAccordion,\n IonAccordionGroup,\n IonButton,\n IonItem,\n IonLabel,\n IonList,\n ItemReorderEventDetail,\n IonReorderGroup,\n IonReorder,\n IonIcon,\n IonText,\n IonSkeletonText,\n IonLoading,\n IonSpinner,\n} from '@ionic/angular/standalone';\nimport { OperationKeys } from '@decaf-ts/db-decorators';\nimport { ReservedModels } from '@decaf-ts/decorator-validation';\nimport { NgxFormDirective } from '../../engine/NgxFormDirective';\nimport { NgxFormService } from '../../services/NgxFormService';\nimport { LayoutComponent } from '../layout/layout.component';\nimport { FormParent, KeyValue } from '../../engine/types';\nimport {\n IFieldSetItem,\n IFieldSetValidationEvent,\n} from '../../engine/interfaces';\nimport { Dynamic } from '../../engine/decorators';\nimport { itemMapper } from '../../utils/helpers';\nimport { UIElementMetadata, UIModelMetadata } from '@decaf-ts/ui-decorators';\nimport { timer } from 'rxjs';\n\n/**\n * @description Dynamic fieldset component with collapsible accordion functionality.\n * @summary This component provides a sophisticated fieldset container that automatically\n * adapts its behavior based on CRUD operations. It integrates seamlessly with Ionic's\n * accordion components to create expandable/collapsible sections for organizing form\n * content and related information. The component intelligently determines its initial\n * state based on the operation type, opening automatically for READ and DELETE operations\n * while remaining closed for CREATE and UPDATE operations.\n *\n * @example\n * ```html\n * <!-- Basic usage with automatic state management -->\n * <ngx-decaf-fieldset\n * name=\"Personal Information\"\n * [operation]=\"OperationKeys.READ\"\n * target=\"_self\">\n * <ion-input label=\"Name\" placeholder=\"Enter name\"></ion-input>\n * <ion-input label=\"Email\" type=\"email\" placeholder=\"Enter email\"></ion-input>\n * </ngx-decaf-fieldset>\n *\n * <!-- Advanced usage with custom operation -->\n * <ngx-decaf-fieldset\n * name=\"Contact Details\"\n * [operation]=\"currentOperation\"\n * target=\"_blank\">\n * <!-- Complex form fields -->\n * </ngx-decaf-fieldset>\n * ```\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant F as FieldsetComponent\n * participant I as Ionic Accordion\n * participant D as DOM\n *\n * F->>F: ngAfterViewInit()\n * alt operation is READ or DELETE\n * F->>F: Set isOpen = true\n * F->>D: Query accordion element\n * F->>I: Set value attribute to 'open'\n * F->>F: Trigger change detection\n * end\n * U->>I: Click accordion header\n * I->>F: handleChange(event)\n * F->>F: Update isOpen state\n * F->>I: Reflect new state\n *\n * @memberOf FieldsetComponent\n */\n@Dynamic()\n@Component({\n standalone: true,\n selector: 'ngx-decaf-fieldset',\n templateUrl: './fieldset.component.html',\n styleUrls: ['./fieldset.component.scss'],\n schemas: [],\n imports: [\n TranslatePipe,\n ReactiveFormsModule,\n IonAccordionGroup,\n IonAccordion,\n IonList,\n IonItem,\n IonLabel,\n IonText,\n IonReorder,\n IonReorderGroup,\n IonButton,\n IonIcon,\n LayoutComponent,\n IonSpinner\n ],\n})\nexport class FieldsetComponent\n extends NgxFormDirective\n implements OnInit, AfterViewInit\n{\n /**\n * @description Reference to the ion-accordion-group component for programmatic control.\n * @summary ViewChild reference that provides direct access to the Ionic accordion group component.\n * This enables programmatic control over the accordion's expand/collapse state, allowing\n * the component to open/close the accordion based on validation errors, CRUD operations,\n * or other business logic requirements.\n *\n * @type {IonAccordionGroup}\n * @memberOf FieldsetComponent\n */\n @ViewChild('accordionComponent', { static: false })\n accordionComponent!: IonAccordionGroup;\n\n /**\n * @description The display name or title of the fieldset section.\n * @summary Sets the legend or header text that appears in the accordion header. This text\n * provides a clear label for the collapsible section, helping users understand what content\n * is contained within. The name is displayed prominently and serves as the clickable area\n * for expanding/collapsing the fieldset.\n *\n * @type {string}\n * @default 'Child'\n * @memberOf FieldsetComponent\n */\n @Input()\n formControl!: FormControl;\n\n /**\n * @description The parent component identifier for hierarchical fieldset relationships.\n * @summary Specifies the parent component name that this fieldset belongs to in a hierarchical\n * form structure. This property is used for event bubbling and establishing parent-child\n * relationships between fieldsets in complex forms with nested structures.\n *\n * @type {string}\n * @default 'Child'\n * @memberOf FieldsetComponent\n */\n @Input()\n collapsable: boolean = true;\n\n /**\n * @description Custom type definitions for specialized fieldset behavior.\n * @summary Defines custom data types or validation rules that should be applied to this fieldset.\n * Can be a single type string or array of types that determine how the fieldset handles\n * data validation, formatting, and display behavior for specialized use cases.\n *\n * @type {string | string[]}\n * @memberOf FieldsetComponent\n */\n @Input()\n customTypes!: string | string[];\n\n /**\n * @description Primary title text for the fieldset content.\n * @summary Display title used for fieldset identification and content organization.\n * Provides semantic meaning to the grouped form fields.\n *\n * @type {string}\n * @memberOf FieldsetComponent\n */\n @Input()\n title!: string;\n\n /**\n * @description Secondary descriptive text for the fieldset.\n * @summary Additional information that provides context or instructions\n * related to the fieldset content and purpose.\n *\n * @type {string}\n * @memberOf FieldsetComponent\n */\n @Input()\n description!: string;\n\n /**\n * @description Enables multiple item management within the fieldset.\n * @summary Boolean flag that determines if the fieldset supports adding multiple values.\n * When true, displays a reorderable list of items with add/remove functionality.\n *\n * @type {boolean}\n * @default false\n * @memberOf FieldsetComponent\n */\n @Input()\n multiple: boolean = true;\n\n /**\n * @description Array of raw values stored in the fieldset.\n * @summary Contains the actual data values that have been added to the fieldset.\n * This is the source of truth for the fieldset's data state.\n *\n * @type {KeyValue[]}\n * @default []\n * @memberOf FieldsetComponent\n */\n @Input()\n override value: KeyValue[] = [];\n\n /**\n * @description Controls whether borders are displayed around the fieldset.\n * @summary Boolean flag that determines if the fieldset should be visually outlined with borders.\n * When true, borders are shown to visually separate the fieldset from surrounding content.\n *\n * @type {boolean}\n * @default true\n * @memberOf FieldsetComponent\n */\n @Input()\n override borders: boolean = true;\n\n /**\n * @description Array of formatted items for UI display.\n * @summary Contains the processed items ready for display in the component template.\n * These items are mapped from the raw values using the mapper configuration.\n *\n * @type {IFieldSetItem[]}\n * @default []\n * @memberOf FieldsetComponent\n */\n items: IFieldSetItem[] | UIElementMetadata[][] = [];\n\n /**\n * @description Currently selected item for update operations.\n * @summary Holds the item being edited when in update mode. Used to track\n * which item is being modified and apply changes to the correct item.\n *\n * @type {IFieldSetItem | undefined}\n * @memberOf FieldsetComponent\n */\n updatingItem!: IFieldSetItem | undefined;\n\n /**\n * @description Current state of the accordion (expanded or collapsed).\n * @summary Boolean flag that tracks whether the fieldset accordion is currently open or closed.\n * This property is automatically managed based on user interactions and initial operation state.\n * It serves as the single source of truth for the component's visibility state and is used\n * to coordinate between user actions and programmatic state changes. The value is automatically\n * set based on CRUD operations during initialization and updated through user interactions.\n *\n * @type {boolean}\n * @default false\n * @memberOf FieldsetComponent\n */\n isOpen: boolean = false;\n\n /**\n * @description Indicates whether the fieldset contains required form fields.\n * @summary Boolean flag that signals the presence of mandatory input fields within the fieldset.\n * This property is automatically set by the CollapsableDirective when required fields are detected,\n * and can be used to apply special styling, validation logic, or UI indicators to highlight\n * fieldsets that contain mandatory information. It helps with form validation feedback and\n * user experience by making required sections more prominent.\n *\n * @type {boolean}\n * @default false\n * @memberOf FieldsetComponent\n */\n isRequired: boolean = false;\n\n /**\n * @description Indicates whether the fieldset contains validation errors.\n * @summary Boolean flag that tracks if any form fields within the fieldset have validation errors.\n * This property is used to control accordion behavior when errors are present, preventing\n * users from collapsing the accordion when they need to see and address validation issues.\n * It's automatically updated when validation error events are received from child form fields.\n *\n * @type {boolean}\n * @default false\n * @memberOf FieldsetComponent\n */\n hasValidationErrors: boolean = false;\n\n /**\n * @description Validation error message for duplicate values.\n * @summary Stores the error message when a user attempts to add a duplicate value\n * to the fieldset. Used to display uniqueness validation feedback.\n *\n * @type {string | undefined}\n * @memberOf FieldsetComponent\n */\n isUniqueError: string | undefined = undefined;\n\n /**\n * @description Localized label text for action buttons.\n * @summary Dynamic button label that changes based on the current operation mode.\n * Shows \"Add\" for create operations and \"Update\" for edit operations.\n *\n * @type {string}\n * @memberOf FieldsetComponent\n */\n buttonLabel!: string;\n\n /**\n * @description Localized label text for action buttons.\n * @summary Dynamic button label that changes based on the current operation mode.\n * Shows \"Cancel\" for update operations\n *\n * @type {string}\n * @memberOf FieldsetComponent\n */\n buttonCancelLabel!: string;\n\n /**\n * @description Maximum allowed items in the fieldset.\n * @summary Numeric limit that controls how many items can be added when `multiple` is true.\n * When set to Infinity there is no limit.\n *\n * @type {number}\n * @default Infinity\n * @memberOf FieldsetComponent\n */\n @Input()\n max: number | undefined = undefined;\n\n /**\n * @description Maximum allowed items in the fieldset.\n * @summary Numeric limit that controls how many items can be added when `multiple` is true.\n * When set to Infinity there is no limit.\n *\n * @type {number}\n * @default Infinity\n * @memberOf FieldsetComponent\n */\n @Input()\n required: boolean = false;\n\n /**\n * @description Determines if the fieldset items can be reordered.\n * @summary Boolean flag that enables or disables the drag-and-drop reordering functionality\n * for the items within the fieldset. When set to true, users can rearrange the order\n * of items using drag-and-drop gestures. This is particularly useful for managing\n * lists where the order of items is significant.\n *\n * @type {boolean}\n * @default true\n * @memberOf FieldsetComponent\n */\n @Input()\n ordenable: boolean = true;\n\n /**\n * @description Determines if the fieldset items can be edited by the user.\n * @summary Boolean flag that enables or disables the editing functionality\n * for the items within the fieldset. When set to true, users can modify the items.\n *\n * @type {boolean}\n * @default true\n * @memberOf FieldsetComponent\n * @default true\n */\n @Input()\n editable: boolean = true;\n\n /**\n * @description Component constructor that initializes the fieldset with icons and component name.\n * @summary Calls the parent NgxFormDirective constructor with the component name and\n * required Ionic icons (alertCircleOutline for validation errors and createOutline for add actions).\n * Sets up the foundational component structure and icon registry.\n *\n * @memberOf FieldsetComponent\n */\n constructor() {\n super('FieldsetComponent');\n addIcons({ alertCircleOutline, addOutline, trashOutline, createOutline });\n }\n\n /**\n * @description Component initialization lifecycle method.\n * @summary Initializes the component by setting up repository relationships if a model exists,\n * and configures the initial button label for the add action based on the current locale.\n * This method ensures proper setup of translation services and component state.\n *\n * @returns {void}\n * @memberOf FieldsetComponent\n */\n override async ngOnInit(): Promise<void> {\n console.log(this.title);\n await super.ngOnInit(this.model);\n if (this.max && this.max === 1) this.multiple = false;\n this.buttonLabel = this.translateService.instant(this.locale + '.add');\n this.buttonCancelLabel = this.translateService.instant(\n this.locale + '.cancel'\n );\n\n if (!this.multiple)\n this.ordenable = false;\n\n if ([OperationKeys.CREATE, OperationKeys.UPDATE].includes(this.operation)) {\n if (!this.formGroup) {\n if (this.parentForm instanceof FormGroup) {\n // iterate on childOf path to get correct formGroup\n const parts = (this.childOf as string).split('.');\n let formGroup = this.parentForm as FormParent;\n for (const part of parts)\n formGroup = (formGroup as FormGroup).controls[part] as FormParent;\n this.formGroup = formGroup;\n if (this.formGroup instanceof FormGroup)\n this.formGroup = this.formGroup.parent as FormArray;\n }\n if (!this.formGroup && this.parentForm instanceof FormArray)\n this.formGroup = this.parentForm;\n if (\n !this.formGroup &&\n (this.children[0] as KeyValue)?.['formGroup'] instanceof FormGroup\n )\n this.formGroup = (this.children[0] as KeyValue)?.['formGroup']\n .parent as FormArray;\n if (this.formGroup && !(this.formGroup instanceof FormArray))\n this.formGroup = (this.formGroup as FormParent)?.parent as FormArray;\n }\n }\n if (this.multiple) {\n this.formGroup?.setErrors(null);\n this.formGroup?.disable();\n if (this.required) {\n this.collapsable = false;\n this.activePage = this.getActivePage();\n }\n } else {\n this.activePage = this.getActivePage();\n }\n this.initialized = true;\n }\n\n /**\n * @description Initializes the component state after view and child components are rendered.\n * @summary This lifecycle hook implements intelligent auto-state management based on the current\n * CRUD operation. For READ and DELETE operations, the fieldset automatically opens to provide\n * immediate access to information, while CREATE and UPDATE operations keep it closed to maintain\n * a clean initial interface. The method directly manipulates the DOM to ensure proper accordion\n * synchronization and triggers change detection to reflect the programmatic state changes.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant F as FieldsetComponent\n * participant D as DOM\n * participant C as ChangeDetector\n *\n * A->>F: ngAfterViewInit()\n * alt operation is READ or DELETE\n * F->>F: Set isOpen = true\n * F->>D: Query ion-accordion-group element\n * alt accordion element exists\n * F->>D: Set value attribute to 'open'\n * end\n * end\n * F->>C: detectChanges()\n * C->>F: Update view with new state\n *\n * @returns {Promise<void>}\n * @memberOf FieldsetComponent\n */\n override async ngAfterViewInit(): Promise<void> {\n await super.ngAfterViewInit();\n // if (!this.collapsable)\n // this.isOpen = true;\n // if (this.operation === OperationKeys.READ || this.operation === OperationKeys.DELETE) {\n // this.isOpen = true;\n // // hidden remove button\n // const accordionElement = this.component?.nativeElement.querySelector('ion-accordion-group');\n // if (accordionElement)\n // this.renderer.setAttribute(accordionElement, 'value', 'open');\n // } else {\n // const inputs = this.component?.nativeElement.querySelectorAll('.dcf-field-required');\n // this.isRequired = inputs?.length > 0;\n // if (this.isRequired) {\n // this.accordionComponent.value = 'open';\n // this.handleAccordionToggle();\n // }\n // }\n // if (!(this.formGroup instanceof FormArray))\n // this.formGroup = (this.formGroup as FormGroup)\n // this.changeDetectorRef.detectChanges();\n }\n\n override async refresh(): Promise<void> {\n this.refreshing = true;\n this.changeDetectorRef.detectChanges();\n if([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation)) {\n // if(!this.multiple) {\n // this.required = this.collapsable = false;\n // }\n this.items = [... this.value.map((v) => {\n return this.children.map((child) => {\n const {props, tag} = child as KeyValue;\n return {\n tag,\n props: {\n ... props,\n value: v[props.name] || \"\"\n }\n };\n })\n })] as UIElementMetadata[][];\n }\n this.refreshing = false;\n this.changeDetectorRef.detectChanges();\n }\n\n /**\n * @description Handles removal of the fieldset with slide animation.\n * @summary Initiates the removal process for the fieldset with a smooth slide-up animation.\n * The method applies CSS classes for the slide animation and then safely removes the\n * element from the DOM using Renderer2. This provides a polished user experience\n * when removing fieldset instances from dynamic forms.\n *\n * @param {Event} event - DOM event from the remove button click\n * @returns {void}\n * @memberOf FieldsetComponent\n */\n handleClear(event?: Event): void {\n if (event) event.stopImmediatePropagation();\n this.formGroup?.disable();\n this.items = [];\n this.value = undefined as unknown as KeyValue[];\n this.activePage = undefined;\n this.activeFormGroupIndex = 0;\n this.accordionComponent.value = '';\n this.changeDetectorRef.detectChanges();\n\n // this.component.nativeElement.classList.add('dcf-animation', 'dcf-animation-slide-top-medium', 'dcf-animation-reverse', 'dcf-animation-fast');\n // setTimeout(() => {\n // // Use Renderer2 to safely remove the element\n // const parent = this.renderer.parentNode(this.component.nativeElement);\n // if (parent)\n // this.renderer.removeChild(parent, this.component.nativeElement);\n // }, 150);\n }\n\n /**\n * @description Handles creating new items or triggering group addition events.\n * @summary Processes form validation events for item creation or emits events to trigger\n * the addition of new fieldset groups. When called with validation event data, it validates\n * uniqueness and adds the item to the fieldset. When called without parameters, it triggers\n * a group addition event for parent components to handle.\n *\n * @param {CustomEvent<IFieldSetValidationEvent>} [event] - Optional validation event containing form data\n * @returns {Promise<void>}\n * @memberOf FieldsetComponent\n *\n * @example\n * ```typescript\n * // Called from form validation\n * handleCreateItem(validationEvent);\n *\n * // Called to trigger group addition\n * handleCreateItem();\n * ```\n */\n async handleCreateItem(\n event?: CustomEvent<IFieldSetValidationEvent>\n ): Promise<void | boolean> {\n if (event && event instanceof CustomEvent) event.stopImmediatePropagation();\n if (!this.activePage) {\n this.activePage = this.getActivePage();\n return;\n }\n const formGroup = this.activeFormGroup as FormGroup;\n const value = formGroup.value;\n const hasSomeValue = this.hasValue(value);\n\n if (hasSomeValue) {\n const action = this.updatingItem\n ? OperationKeys.UPDATE\n : OperationKeys.CREATE;\n const isValid = NgxFormService.validateFields(formGroup);\n\n // must pass correct pk here\n const isUnique = NgxFormService.isUniqueOnGroup(\n formGroup,\n action,\n action === OperationKeys.UPDATE ? this.updatingItem?.index : undefined\n );\n if (isValid) {\n this.mapper = this.getMapper(value as KeyValue);\n if (isUnique) {\n this.isUniqueError = this.updatingItem = undefined;\n this.setValue();\n NgxFormService.addGroupToParent(formGroup.parent as FormArray);\n this.activeFormGroupIndex =\n (formGroup.parent as FormArray).length - 1;\n this.activePage = this.getActivePage();\n } else {\n this.isUniqueError =\n typeof value === ReservedModels.OBJECT.name.toLowerCase()\n ? (value as KeyValue)?.[this.pk] || undefined\n : value;\n }\n }\n }\n }\n\n hasValue(value: KeyValue = {}): boolean {\n return Object.keys(value).some(\n (key) =>\n value[key] !== null && value[key] !== undefined && value[key] !== ''\n );\n }\n\n handleUpdateItem(index: number): void {\n const formGroup = this.getFormArrayIndex(index);\n if (formGroup) {\n this.updatingItem = Object.assign({}, formGroup.value || {}, { index });\n this.activeFormGroupIndex = index;\n this.activePage = this.getActivePage();\n }\n }\n\n /**\n * @description Cancels the update mode and resets the UI state.\n * @summary Exits the update mode by resetting the button label and clearing the updating item,\n * restoring the component to its default state for adding new items. Notifies parent components\n * that the update operation has been cancelled.\n *\n * @returns {void}\n * @memberOf FieldsetComponent\n */\n handleCancelUpdateItem(): void {\n this.buttonLabel = this.translateService.instant(this.locale + '.add');\n this.updatingItem = undefined;\n this.activeFormGroupIndex = (this.formGroup as FormArray)?.length - 1;\n this.getFormArrayIndex(this.activeFormGroupIndex);\n }\n\n /**\n * @description Handles item removal operations with form array management.\n * @summary Processes item removal by either handling validation events or removing specific\n * items from the form array. When called with a validation event, it triggers value updates.\n * When called with an identifier, it locates and removes the matching item from the form array.\n *\n * @param {string | undefined} value - The identifier of the item to remove\n * @param {CustomEvent} [event] - Optional validation event for form updates\n * @returns {void}\n * @memberOf FieldsetComponent\n */\n handleRemoveItem(index: number): void {\n const formArray = this.formGroup as FormArray;\n if (formArray.length === 1) {\n const currentGroup = formArray.at(0) as FormGroup;\n Object.keys(currentGroup?.controls).forEach((controlName) => {\n currentGroup.get(controlName)?.setValue(null);\n });\n } else {\n formArray.removeAt(index);\n }\n this.setValue();\n if (this.items.length > 0) {\n if (this.activeFormGroupIndex > 0)\n this.activeFormGroupIndex = this.activeFormGroupIndex - 1;\n } else {\n this.handleClear();\n }\n }\n\n /**\n * @description Handles reordering of items within the fieldset list.\n * @summary Processes drag-and-drop reorder events from the ion-reorder-group component.\n * Updates both the display items array and the underlying value array to maintain\n * consistency between UI state and data state. Preserves item indices after reordering.\n *\n * @param {CustomEvent<ItemReorderEventDetail>} event - Ionic reorder event containing source and target indices\n * @returns {void}\n * @memberOf FieldsetComponent\n *\n * @example\n * ```html\n * <ion-reorder-group (ionItemReorder)=\"handleReorder($event)\">\n * <!-- Reorderable items -->\n * </ion-reorder-group>\n * ```\n */\n handleReorderItems(event: CustomEvent<ItemReorderEventDetail>): void {\n const fromIndex = event.detail.from;\n const toIndex = event.detail.to;\n\n const items = [...this.items]; // visual data\n const formArray = this.formGroup as FormArray; // FormArray\n\n if (fromIndex !== toIndex) {\n this.items = [];\n // reorder visual data\n const itemToMove = items.splice(fromIndex, 1)[0];\n items.splice(toIndex, 0, itemToMove);\n items.forEach((item, index) => ((item as IFieldSetItem)['index'] = index + 1));\n\n // reorder FormArray controls\n const controlToMove = formArray.at(fromIndex);\n formArray.removeAt(fromIndex);\n formArray.insert(toIndex, controlToMove);\n }\n this.items = [...items as IFieldSetItem[]];\n event.detail.complete();\n }\n\n /**\n * @description Handles accordion state change events from user interactions.\n * @summary Processes CustomEvent objects triggered when users expand or collapse the accordion.\n * This method extracts the new state from the event details and updates the component's\n * internal state accordingly. It specifically listens for ION-ACCORDION-GROUP events to\n * ensure proper event source validation and prevent handling of unrelated events.\n *\n * @param {CustomEvent} event - The event object containing accordion state change details\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant I as Ion-Accordion\n * participant F as FieldsetComponent\n *\n * U->>I: Click accordion header\n * I->>F: handleChange(CustomEvent)\n * F->>F: Extract target and detail from event\n * F->>F: Validate target is ION-ACCORDION-GROUP\n * alt valid target\n * F->>F: Update isOpen = !!value\n * end\n * F->>I: Reflect updated state\n *\n * @memberOf FieldsetComponent\n */\n\n /**\n * @description Handles accordion toggle functionality with validation error consideration.\n * @summary Manages the expand/collapse state of the accordion while respecting validation error states.\n * When validation errors are present, the accordion cannot be collapsed to ensure users can see\n * and address the errors. When no errors exist, users can freely toggle the accordion state.\n * This method also stops event propagation to prevent unwanted side effects.\n *\n * @param {CustomEvent} [event] - Optional event object from user interaction\n * @returns {void}\n * @memberOf FieldsetComponent\n */\n handleAccordionToggle(event?: CustomEvent): void {\n if (event) event.stopImmediatePropagation();\n\n if (!this.collapsable || this.isRequired) {\n this.isOpen = true;\n } else {\n if (!this.hasValidationErrors) {\n this.accordionComponent.value = this.isOpen ? undefined : 'open';\n this.isOpen = !!this.accordionComponent.value;\n }\n }\n }\n\n /**\n * @description Handles validation error events from child form fields.\n * @summary Processes validation error events dispatched by form fields within the fieldset.\n * When errors are detected, the accordion is forced open and prevented from collapsing\n * to ensure users can see the validation messages. This method updates the component's\n * error state and accordion visibility accordingly.\n *\n * @param {CustomEvent} event - Custom event containing validation error details\n * @returns {UIModelMetadata[] | undefined}\n * @memberOf FieldsetComponent\n */\n // handleValidationError(event: CustomEvent): void {\n // event.stopImmediatePropagation();\n // const {hasErrors} = event.detail;\n // this.isOpen = this.hasValidationErrors = hasErrors;\n // if (hasErrors)\n // this.accordionComponent.value = 'open';\n // }\n\n protected override getActivePage(): UIModelMetadata[] | undefined {\n this.activePage = undefined;\n this.isOpen = true;\n this.accordionComponent.value = 'open';\n this.changeDetectorRef.detectChanges();\n this.timerSubscription = timer(10).subscribe(() => {\n this.children = this.children.map((child) => {\n if (!child.props) child.props = {};\n child.props = Object.assign(child.props, {\n activeFormGroup: this.activeFormGroupIndex,\n multiple: this.multiple,\n });\n return child;\n });\n });\n if (this.multiple && [OperationKeys.CREATE, OperationKeys.UPDATE].includes(this.operation))\n this.getFormArrayIndex(this.activeFormGroupIndex);\n return this.children as UIModelMetadata[];\n }\n\n /**\n * @description Processes and stores a new or updated value in the fieldset.\n * @summary Handles both create and update operations for fieldset items. Parses and cleans\n * the input value, determines the operation type based on the updating state, and either\n * adds a new item or updates an existing one. Maintains data integrity and UI consistency.\n *\n * @returns {void}\n * @private\n * @memberOf FieldsetComponent\n */\n private setValue(): void {\n this.value = (this.formGroup as FormArray).controls.map(\n ({ value }) => value\n );\n this.items = this.value\n .filter((v) => (v[this.pk] || '').trim().length)\n .map((v, index) => {\n return {\n ...itemMapper(Object.assign({}, v), this.mapper),\n index: index + 1,\n } as IFieldSetItem;\n });\n\n this.updatingItem = undefined;\n }\n\n /**\n * @description Automatically configures the field mapping based on the value structure.\n * @summary Analyzes the provided value object to automatically determine the primary key\n * and create appropriate field mappings for display purposes. Sets up the mapper object\n * with title, description, and index fields based on the available data structure.\n *\n * @param {KeyValue} value - Sample value object used to determine field mappings\n * @returns {KeyValue} The configured mapper object\n * @private\n * @memberOf FieldsetComponent\n */\n private getMapper(value: KeyValue): KeyValue {\n if (!this.pk) this.pk = Object.keys(value)[0];\n if (!Object.keys(this.mapper).length)\n (this.mapper as KeyValue)['title'] = this.pk;\n (this.mapper as KeyValue)['index'] = 'index';\n for (const key in value) {\n if (\n Object.keys(this.mapper).length >= 2 ||\n Object.keys(this.mapper).length === Object.keys(value).length\n )\n break;\n if (!(this.mapper as KeyValue)['title']) {\n (this.mapper as KeyValue)['title'] = key;\n } else {\n (this.mapper as KeyValue)['description'] = key;\n }\n }\n return this.mapper;\n }\n}\n","\n\n <fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.open]=\"isOpen\"\n [class.dcf-not-collapsable]=\"!collapsable\"\n #component>\n <div class=\"dcf-width-1-1\">\n @if (!collapsable || required) {\n <legend class=\"dcf-title\">{{ (title ? title : name) | translate }}</legend>\n }\n <ion-accordion-group class=\"dcf-width-1-1\" [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" [value]=\"(operation === 'read' || !collapsable) ? 'open' : ''\" #accordionComponent>\n <ion-accordion\n value=\"open\"\n [class.dcf-disabled]=\"!activePage\"\n [class.dcf-empty]=\"!items?.length\"\n >\n @if (collapsable && !required) {\n <ion-item slot=\"header\" [button]=\"collapsable\" (click)=\"handleAccordionToggle($event)\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-width-1-1\">\n <div class=\"dcf-width-expand\">\n <legend>{{ (title ? title : name) | translate }}</legend>\n </div>\n @if (!isRequired && ['create', 'update'].includes(operation) && collapsable && multiple) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleClear($event)\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n </div>\n </ion-item>\n }\n\n <div slot=\"content\" [attr.aria-hidden]=\"!isOpen\">\n @if (['create', 'update'].includes(operation) || !multiple) {\n @if(activePage) {\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested'\"\n [flexMode]=\"props.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [children]=\"activePage || []\"\n [parentForm]=\"formGroup || parentForm\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [borders]=\"activePage?.borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [hidden]=\"items.length === max && !updatingItem\"\n />\n </div>\n }\n } @else {\n @if(refreshing) {\n <div class=\"dcf-loading-container\">\n <ion-spinner name=\"crescent\" color=\"primary\"></ion-spinner>\n </div>\n } @else {\n @if(!items.length) {\n <div class=\"dcf-padding-xsmall\">\n <ion-text class=\"dcf-text-small\">{{ locale + '.empty' | translate }}</ion-text>\n </div>\n } @else {\n @for(item of items; track trackItemFn($index, item)) {\n <div class=\"dcf-fieldset-item\">\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested ' + operation\"\n [flexMode]=\"item?.props?.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'collapse'\"\n [children]=\"item || []\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [borders]=\"item?.props?.borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n />\n </div>\n </div>\n }\n }\n }\n }\n </div>\n </ion-accordion>\n </ion-accordion-group>\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group [formGroup]=\"formGroup.parent\" [disabled]=\"updatingItem\" (ionItemReorder)=\"handleReorderItems($any($event))\" #accordionComponent>\n @for(item of items; track item.index) {\n <ion-item [class.not-unique]=\"item.title === isUniqueError\" [class.updating]=\"updatingItem?.[pk] === item.title\" lines=\"full\" [button]=\"false\">\n @if(ordenable) {\n @if (items?.length > 1 && !updatingItem) {\n <ion-reorder slot=\"start\">\n <ion-icon aria-hidden=\"true\" name=\"swap-vertical-outline\"></ion-icon>\n </ion-reorder>\n } @else {\n <div slot=\"start\">\n <ion-icon aria-hidden=\"true\" class=\"dcf-reorder-disabled\" size=\"small\" name=\"swap-vertical-outline\" disabled></ion-icon>\n </div>\n }\n }\n\n <ion-label [color]=\"(item.title === isUniqueError && !updatingItem?.[pk] === item.title) ? 'danger' : ''\">{{ item.index }}. {{ item.title }}\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{item.description}}</ion-text>\n }\n </ion-label>\n\n @if(editable) {\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleUpdateItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"create-outline\" color=\"dark\" ></ion-icon>\n </ion-button>\n }\n }\n\n\n @if (!updatingItem) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleRemoveItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"close-outline\" color=\"dark\"></ion-icon>\n </ion-button>\n }\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (isUniqueError) {\n <div class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\">\n <div class=\" dcf-grid dcf-grid-collapse dcf-width-1-1 \">\n <div class=\"dcf-auto\" [attr.style]=\"'max-width: 50px'\">\n <ion-icon aria-hidden=\"true\" name=\"alert-circle-outline\"></ion-icon>\n </div>\n <div class=\"dcf-width-expand\">\n <ion-text color=\"danger\" class=\"dcf-text-small\">{{ locale + '.not_unique' | translate : { value: isUniqueError } }}</ion-text>\n </div>\n </div>\n </div>\n }\n\n @if(max) {\n <div class=\"dcf-width-1-1 dcf-max-message-container\">\n <ion-text class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{ locale + (items.length !== max ? '.max_items' : '.max_items_reached') | translate : { '0': max } }}\n </ion-text>\n </div>\n }\n\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\" [class.dcf-not-collapsable]=\"!collapsable\" [class.dcf-empty]=\"!activePage\" [class.dcf-blank]=\"!borders\">\n @if (updatingItem) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ locale + '.cancel' | translate }}\n </ion-button>\n </div>\n <div>\n <ion-button size=\"small\" fill=\"clear\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update' | translate }}\n </ion-button>\n </div>\n } @else {\n @if (items.length < max || !max) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" [color]=\"isDarkMode ? 'light' : 'dark'\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"add-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.add' | translate }}\n </ion-button>\n </div>\n }\n }\n </div>\n }\n </div>\n </fieldset>\n\n\n","/**\n * @module module:lib/components/searchbar/searchbar.component\n * @description Searchbar component module.\n * @summary Exposes `SearchbarComponent` providing a configurable search input with\n * debouncing, clear/cancel handling and optional global window events. Use this\n * component to add search UI across lists and pages.\n *\n * @link {@link SearchbarComponent}\n */\n\nimport { Component, EventEmitter, HostListener, Input, OnInit, Output } from '@angular/core';\nimport { IonSearchbar } from '@ionic/angular/standalone';\nimport * as allIcons from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { AutocompleteTypes, PredefinedColors} from '@ionic/core';\nimport { NgxComponentDirective } from '../../engine/NgxComponentDirective';\nimport { StringOrBoolean } from '../../engine/types';\nimport {windowEventEmitter} from '../../utils/helpers';\nimport { stringToBoolean } from '../../utils/helpers';\n\n\n/**\n * @description Searchbar component for Angular applications.\n * @summary The SearchbarComponent provides a highly customizable search input field with comprehensive\n * options for appearance, behavior, and interaction patterns. It extends NgxBaseComponentDirective to inherit\n * common functionality and implements OnInit for proper lifecycle management. This component features\n * debounced input handling, window event integration, visibility controls, and extensive styling options.\n * It's designed to be flexible and adaptable to different search requirements within modern web applications.\n *\n * @class SearchbarComponent\n * @extends {NgxBaseComponentDirective}\n * @implements {OnInit}\n * @memberOf SearchbarComponent\n */\n@Component({\n selector: 'ngx-decaf-searchbar',\n templateUrl: './searchbar.component.html',\n styleUrls: ['./searchbar.component.scss'],\n standalone: true,\n imports: [IonSearchbar],\n})\nexport class SearchbarComponent extends NgxComponentDirective implements OnInit {\n\n /**\n * @description The mode of the searchbar.\n * @summary Determines the visual style of the searchbar, either iOS or Material Design.\n * @type {\"ios\" | \"md\" | undefined}\n * @default \"ios\"\n */\n // @Input()\n // override mode: \"ios\" | \"md\" | undefined = \"md\";\n\n /**\n * @description The autocomplete attribute for the searchbar input.\n * @summary Specifies whether the browser should enable autocomplete for the input field.\n * This controls the browser's built-in autocomplete functionality, helping users by\n * suggesting previously entered values or common inputs. Setting to 'off' disables\n * this feature for privacy or security reasons.\n *\n * @type {AutocompleteTypes | undefined}\n * @default \"off\"\n * @memberOf SearchbarComponent\n */\n @Input()\n autocomplete: AutocompleteTypes | undefined = \"off\";\n\n /**\n * @description The autocorrect attribute for the searchbar input.\n * @summary Controls whether the browser should enable autocorrect functionality for the input field.\n * When enabled, the browser will automatically correct spelling mistakes as the user types.\n * This is typically disabled for search fields to preserve the user's exact search terms.\n *\n * @type {\"on\" | \"off\"}\n * @default \"off\"\n * @memberOf SearchbarComponent\n */\n @Input()\n autocorrect: \"on\" | \"off\" = \"off\";\n\n /**\n * @description Whether the searchbar should animate.\n * @summary Controls the animation behavior of the searchbar during appearance and disappearance transitions.\n * When enabled, the searchbar will use smooth animations for state changes, providing a more\n * polished user experience. This affects transitions like showing/hiding the component.\n *\n * @type {StringOrBoolean}\n * @default true\n * @memberOf SearchbarComponent\n */\n @Input()\n animated: StringOrBoolean = true;\n\n /**\n * @description The text for the cancel button.\n * @summary Specifies the localized text to be displayed on the cancel button of the searchbar.\n * This text appears when the cancel button is visible and provides users with a clear\n * indication of how to dismiss the search interface. The text can be customized for\n * different languages and cultural contexts.\n *\n * @type {string}\n * @default \"Cancel\"\n * @memberOf SearchbarComponent\n */\n @Input()\n buttonCancelText: string = \"Cancel\";\n\n /**\n * @description The icon to use for the clear button.\n * @summary Specifies the icon to be displayed for the clear button of the searchbar.\n * @type {string | undefined}\n * @default undefined\n * @memberOf SearchbarComponent\n */\n @Input()\n clearIcon: string | undefined = undefined;\n\n /**\n * @description The color of the searchbar.\n * @summary Specifies the color theme to be applied to the searchbar.\n * @type {string | undefined}\n * @default undefined\n * @memberOf SearchbarComponent\n */\n @Input()\n color: string | undefined = undefined;\n\n /**\n * @description The amount of time, in milliseconds, to wait to trigger the `ionChange` event after each keystroke.\n * @summary Controls the debounce time for the search input to reduce the frequency of event emissions.\n * @type {number}\n * @default 500\n * @memberOf SearchbarComponent\n */\n @Input()\n debounce: number = 500;\n\n /**\n * @description Whether the searchbar is disabled.\n * @summary Controls whether the searchbar is interactive or not.\n * @type {StringOrBoolean}\n * @default false\n * @memberOf SearchbarComponent\n */\n @Input()\n disabled: StringOrBoolean = false;\n\n /**\n * @description A hint to the browser for which enter key to display.\n * @summary Specifies the type of action that will be performed when the enter key is pressed.\n * @type {\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined}\n * @default \"enter\"\n * @memberOf SearchbarComponent\n */\n @Input()\n enterkeyhint: \"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined = \"enter\";\n\n /**\n * @description The input mode for the searchbar.\n * @summary Specifies the type of data that might be entered by the user while editing the element or its contents.\n * @type {\"text\" | \"search\" | \"none\" | \"email\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined}\n * @default 'search'\n * @memberOf SearchbarComponent\n */\n @Input()\n inputmode: \"text\" | \"search\" | \"none\" | \"email\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined = 'search';\n\n /**\n * @description The placeholder for the searchbar input.\n * @summary Specifies the placeholder text to be displayed in the searchbar when it's empty.\n * @type {string}\n * @default \"Search\"\n * @memberOf SearchbarComponent\n */\n @Input()\n placeholder = \"Search\";\n\n /**\n * @description The icon to use for the search button.\n * @summary Specifies the icon to be displayed for the search button of the searchbar.\n * @type {string | undefined}\n * @default \"search-outline\"\n * @memberOf SearchbarComponent\n */\n @Input()\n searchIcon: string | undefined = \"search-outline\";\n\n /**\n * @description When to show the cancel button.\n * @summary Controls the visibility of the cancel button in different states of the searchbar.\n * @type {\"always\" | \"focus\" | \"never\"}\n * @default \"never\"\n * @memberOf SearchbarComponent\n */\n @Input()\n showCancelButton: \"always\" | \"focus\" | \"never\" = \"never\";\n\n /**\n * @description When to show the clear button.\n * @summary Controls the visibility of the clear button in different states of the searchbar.\n * @type {\"always\" | \"focus\" | \"never\"}\n * @default \"focus\"\n * @memberOf SearchbarComponent\n */\n @Input()\n showClearButton: \"always\" | \"focus\" | \"never\" = \"focus\";\n\n /**\n * @description Whether to enable spellcheck on the searchbar input.\n * @summary Controls whether the browser's spellcheck feature is enabled for the searchbar input.\n * @type {boolean}\n * @default false\n * @memberOf SearchbarComponent\n */\n @Input()\n spellcheck: boolean = false;\n\n /**\n * @description The type of input to use for the searchbar.\n * @summary Specifies the type of control to display for the searchbar input.\n * @type {\"number\" | \"text\" | \"search\" | \"email\" | \"password\" | \"tel\" | \"url\" | undefined}\n * @default \"search\"\n * @memberOf SearchbarComponent\n */\n @Input()\n type: \"number\" | \"text\" | \"search\" | \"email\" | \"password\" | \"tel\" | \"url\" | undefined = \"search\";\n\n /**\n * @description The value of the searchbar input.\n * @summary Specifies the current value of the searchbar input.\n * @type {null | string | undefined}\n * @default \"\"\n * @memberOf SearchbarComponent\n */\n @Input()\n override value: null | string | undefined = \"\";\n\n /**\n * @description The keys to use for querying.\n * @summary Specifies the keys to be used when performing a search query.\n * @type {string | string[]}\n * @default \"name\"\n * @memberOf SearchbarComponent\n */\n @Input()\n queryKeys: string | string[] = \"name\";\n\n /**\n * @description Whether the searchbar is visible.\n * @summary Controls the visibility of the searchbar component.\n * @type {StringOrBoolean}\n * @default false\n * @memberOf SearchbarComponent\n */\n @Input()\n isVisible: StringOrBoolean = false;\n\n /**\n * @description Whether to wrap the searchbar in a container.\n * @summary Controls whether the searchbar is wrapped in an additional container element.\n * @type {StringOrBoolean}\n * @default false\n * @memberOf SearchbarComponent\n */\n @Input()\n wrapper: StringOrBoolean = false;\n\n /**\n * @description The color of the wrapper.\n * @summary Specifies the color theme to be applied to the wrapper container, if present.\n * @type {PredefinedColors}\n * @default \"primary\"\n * @memberOf SearchbarComponent\n */\n @Input()\n wrapperColor: PredefinedColors = \"primary\";\n\n /**\n * @description Whether to emit events to the window.\n * @summary Controls whether search events should be emitted as window events.\n * @type {StringOrBoolean}\n * @default true\n * @memberOf SearchbarComponent\n */\n @Input()\n emitEventToWindow: StringOrBoolean = true;\n\n /**\n * @description The current value of the searchbar.\n * @summary Stores the current value of the searchbar input for internal state management and processing.\n * This property is used to track the search term throughout the component's lifecycle and\n * coordinate between different event handlers and methods.\n *\n * @type {string | undefined}\n * @memberOf SearchbarComponent\n */\n currentValue: string | undefined;\n\n /**\n * @description Event emitter for search events.\n * @summary Emits search events when the user interacts with the searchbar, providing a reactive\n * interface for parent components to respond to search actions. This event is triggered by\n * various user interactions including typing, clearing, and explicit search actions.\n *\n * @type {EventEmitter<string>}\n * @memberOf SearchbarComponent\n */\n @Output()\n searchEvent: EventEmitter<string> = new EventEmitter<string>();\n\n /**\n * @description Creates an instance of SearchbarComponent.\n * @summary Initializes the SearchbarComponent with all necessary dependencies and configurations.\n * During initialization, it adds all available Ionicons to the application's icon registry,\n * ensuring that search and clear icons are available for use throughout the component's lifecycle.\n *\n * @memberOf SearchbarComponent\n */\n constructor() {\n super('SearchbarComponent');\n addIcons(allIcons)\n }\n\n /**\n * @description Initializes the component after Angular first displays the data-bound properties.\n * @summary Performs essential component initialization by converting string-based boolean inputs\n * to proper boolean values using the stringToBoolean utility. This ensures that all boolean\n * properties work correctly regardless of how they were passed from parent components or templates.\n *\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant S as SearchbarComponent\n * participant U as Utility Functions\n *\n * A->>S: ngOnInit()\n * S->>U: stringToBoolean(emitEventToWindow)\n * U-->>S: boolean value\n * S->>U: stringToBoolean(wrapper)\n * U-->>S: boolean value\n * S->>U: stringToBoolean(isVisible)\n * U-->>S: boolean value\n * S->>U: stringToBoolean(disabled)\n * U-->>S: boolean value\n * S->>U: stringToBoolean(animated)\n * U-->>S: boolean value\n * Note over S: Component ready for interaction\n *\n * @memberOf SearchbarComponent\n */\n ngOnInit(): void {\n this.emitEventToWindow = stringToBoolean(this.emitEventToWindow);\n this.wrapper = stringToBoolean(this.wrapper);\n this.isVisible = stringToBoolean(this.isVisible);\n this.disabled = stringToBoolean(this.disabled);\n this.animated = stringToBoolean(this.animated);\n }\n\n /**\n * @description Handles the visibility toggle of the searchbar component.\n * @summary Listens for global window events to toggle the visibility state of the searchbar.\n * When the searchbar becomes visible, it automatically focuses on the input field after a brief\n * delay to ensure smooth animation completion. This provides a seamless user experience for\n * search activation through keyboard shortcuts or programmatic triggers.\n *\n * @param {CustomEvent} event - The custom event triggering the visibility toggle (unused but required by HostListener)\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant W as Window\n * participant S as SearchbarComponent\n * participant E as DOM Element\n *\n * W->>S: toggleSearchbarVisibility event\n * S->>S: handleToggleVisibility()\n * S->>S: Toggle isVisible state\n * alt isVisible is true AND component exists\n * S->>S: setTimeout(125ms)\n * S->>E: setFocus() on ion-searchbar\n * end\n *\n * @memberOf SearchbarComponent\n */\n @HostListener(\"window:toggleSearchbarVisibility\", ['$event'])\n handleToggleVisibility(): void {\n this.isVisible = !this.isVisible;\n if (this.isVisible && !!this.component.nativeElement) {\n setTimeout(() => {\n (this.component.nativeElement as HTMLIonSearchbarElement).setFocus();\n }, 125);\n }\n }\n\n /**\n * @description Triggers a manual search event with the current searchbar value.\n * @summary Retrieves the current value from the searchbar's native element and emits it as a search event.\n * This method provides a programmatic way to trigger search functionality, useful for external\n * components or keyboard shortcuts that need to execute search without user interaction with the searchbar itself.\n *\n * @return {void}\n * @memberOf SearchbarComponent\n */\n search(): void {\n const element = this.component.nativeElement as HTMLIonSearchbarElement;\n this.searchEvent.emit(element.value || undefined);\n }\n\n /**\n * @description Handles value changes in the searchbar input field.\n * @summary Processes change events from the Ionic searchbar component and extracts the new value\n * to emit as a search event. This method is triggered when the user finishes editing the searchbar\n * value, providing a way to react to completed input changes rather than real-time typing.\n *\n * @param {CustomEvent} event - The change event from the Ionic searchbar containing the new value\n * @return {void}\n * @memberOf SearchbarComponent\n */\n handleChange(event: CustomEvent): void {\n this.emitEvent(event?.detail?.value ?? undefined);\n }\n\n /**\n * @description Handles clearing of the searchbar input field.\n * @summary Emits an undefined value as a search event when the searchbar is cleared by the user.\n * This method is typically triggered when the user clicks the clear button or uses other\n * clear mechanisms, signaling that the search should be reset or cleared.\n *\n * @return {void}\n * @memberOf SearchbarComponent\n */\n handleClear(): void {\n this.emitEvent(undefined);\n }\n\n /**\n * @description Handles real-time input events on the searchbar.\n * @summary Processes input events as the user types, providing immediate feedback for search functionality.\n * This method implements smart clearing behavior - if the input becomes empty, it automatically\n * triggers the clear handler. Otherwise, it emits the current value for real-time search suggestions\n * or filtering. This enables responsive search experiences with debounced event handling.\n *\n * @param {CustomEvent} event - The input event from the Ionic searchbar containing the current value\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant S as SearchbarComponent\n * participant E as Event System\n *\n * U->>S: Type in searchbar\n * S->>S: handleInput(event)\n * S->>S: Extract value from event\n * alt value is empty or null\n * S->>S: handleClear()\n * S->>E: Emit undefined\n * else value has content\n * S->>S: emitEvent(value)\n * S->>E: Emit search value\n * end\n *\n * @memberOf SearchbarComponent\n */\n handleInput(event: CustomEvent): void {\n const value = event?.detail?.value;\n if (!value || !value?.length)\n return this.handleClear();\n this.emitEvent(value);\n }\n\n /**\n * @description Handles blur events on the searchbar.\n * @summary Currently an empty method, can be implemented for specific blur behavior.\n * @param {CustomEvent} event - The blur event from the searchbar\n * @return {void}\n */\n // handleBlur(event: CustomEvent): void {}\n\n /**\n * @description Emits search events through multiple channels.\n * @summary Orchestrates the emission of search events both as component output events and optionally\n * as global window events. This dual-channel approach enables both direct parent-child communication\n * and application-wide event broadcasting, supporting flexible integration patterns and loose coupling\n * between components that need to respond to search actions.\n *\n * @param {string | undefined} value - The search value to emit across all configured channels\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant S as SearchbarComponent\n * participant P as Parent Component\n * participant W as Window Event System\n *\n * S->>S: emitEvent(value)\n * S->>P: searchEvent.emit(value)\n * alt emitEventToWindow is true\n * S->>W: windowEventEmitter('searchbarEvent', {value})\n * end\n *\n * @memberOf SearchbarComponent\n */\n emitEvent(value: string | undefined): void {\n this.searchEvent.emit(value);\n if (this.emitEventToWindow)\n windowEventEmitter('searchbarEvent', {value: value})\n }\n\n /**\n * @description Prevents default behavior of DOM events.\n * @summary Utility method to prevent unwanted default actions on DOM events, such as form submissions\n * or navigation triggers. This is commonly used in event handlers where the default browser behavior\n * would interfere with the component's custom logic or user experience design.\n *\n * @param {Event} event - The DOM event whose default behavior should be prevented\n * @return {void}\n * @memberOf SearchbarComponent\n */\n preventChange(event: Event): void {\n event.preventDefault();\n }\n}\n","<ion-searchbar\n [id]=\"uid\"\n ngClass=\"dcf-searchbar\"\n name=\"search\"\n mode=\"ios\"\n (keyup.enter)=\"preventChange($event)\"\n (ionChange)=\"handleChange($event)\"\n (ionInput)=\"handleInput($event)\"\n (ionClear)=\"handleClear()\"\n [autocomplete]=\"autocomplete\"\n [showCancelButton]=\"showCancelButton\"\n [cancelButtonText]=\"buttonCancelText\"\n [clearIcon]=\"clearIcon\"\n [color]=\"color\"\n [debounce]=\"debounce\"\n [disabled]=\"disabled\"\n [enterkeyhint]=\"enterkeyhint\"\n [inputmode]=\"inputmode\"\n [placeholder]=\"placeholder\"\n [searchIcon]=\"searchIcon\"\n [showClearButton]=\"showClearButton\"\n [spellcheck]=\"spellcheck\"\n [type]=\"type\"\n #component\n />\n","/**\n * @module module:lib/components/filter/filter.component\n * @description Filter component module.\n * @summary Provides `FilterComponent` which builds advanced, multi-step filter\n * queries (index → condition → value) and emits filter events for data querying.\n * It supports responsive behavior, suggestions and integration with `SearchbarComponent`.\n *\n * @link {@link FilterComponent}\n */\n\nimport {\n Component,\n ElementRef,\n EventEmitter,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ViewChild,\n} from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { FormsModule } from '@angular/forms';\nimport { debounceTime, fromEvent, Subscription } from 'rxjs';\nimport {\n IonButton,\n IonChip,\n IonIcon,\n IonSelect,\n IonSelectOption,\n} from '@ionic/angular/standalone';\nimport {\n chevronDownOutline,\n trashOutline,\n closeOutline,\n searchOutline,\n arrowDownOutline,\n arrowUpOutline,\n chevronUpOutline,\n} from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { Model } from '@decaf-ts/decorator-validation';\nimport { OrderDirection, Repository } from '@decaf-ts/core';\nimport { NgxComponentDirective } from '../../engine/NgxComponentDirective';\nimport { Dynamic } from '../../engine/decorators';\nimport { IFilterQuery, IFilterQueryItem } from '../../engine/interfaces';\nimport { getWindowWidth } from '../../utils/helpers';\nimport { SearchbarComponent } from '../searchbar/searchbar.component';\nimport { Constructor } from '@decaf-ts/decoration';\n\n/**\n * @description Advanced filter component for creating dynamic search filters with step-by-step construction.\n * @summary This component provides a comprehensive filtering interface that allows users to build\n * complex search criteria using a three-step approach: select index → select condition → enter value.\n * It supports filtering by multiple field indexes, comparison conditions, and values, displaying\n * selected filters as removable chips. The component is responsive and includes auto-suggestions\n * with keyboard navigation support.\n *\n * @example\n * ```html\n * <ngx-decaf-filter\n * [indexes]=\"['name', 'email', 'department', 'status']\"\n * [conditions]=\"['Equal', 'Contains', 'Greater Than', 'Less Than']\"\n * [sort]=\"['createdAt', 'updatedAt']\"\n * [disableSort]=\"false\"\n * (filterEvent)=\"onFiltersChanged($event)\">\n * </ngx-decaf-filter>\n * ```\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant F as FilterComponent\n * participant P as Parent Component\n *\n * U->>F: Focus input field\n * F->>F: handleFocus() - Show available indexes\n * U->>F: Select index (e.g., \"name\")\n * F->>F: addFilter() - Step 1 completed\n * F->>F: Show available conditions\n * U->>F: Select condition (e.g., \"Contains\")\n * F->>F: addFilter() - Step 2 completed\n * F->>F: Show value input prompt\n * U->>F: Enter value and press Enter\n * F->>F: addFilter() - Step 3 completed\n * F->>F: Create complete filter object\n * F->>P: Emit filterEvent with new filter array\n * F->>F: Reset to step 1 for next filter\n *\n * @memberOf ForAngularCommonModule\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-filter',\n templateUrl: './filter.component.html',\n styleUrls: ['./filter.component.scss'],\n imports: [\n FormsModule,\n TranslatePipe,\n IonChip,\n IonIcon,\n IonButton,\n IonSelect,\n IonSelectOption,\n IonIcon,\n SearchbarComponent,\n ],\n standalone: true,\n host: { '[attr.id]': 'uid' },\n})\nexport class FilterComponent\n extends NgxComponentDirective\n implements OnInit, OnDestroy\n{\n /**\n * @description Reference to the dropdown options container element.\n * @summary ViewChild reference used to access and manipulate the dropdown options element\n * for highlighting filtered items and managing visual feedback during option selection.\n * This element contains the filterable suggestions that users can interact with.\n *\n * @type {ElementRef}\n * @memberOf FilterComponent\n */\n @ViewChild('optionsFilterElement', { read: ElementRef, static: false })\n optionsFilterElement!: ElementRef;\n\n /**\n * @description Available field indexes for filtering operations.\n * @summary Defines the list of field names that users can filter by. These represent\n * the data properties available for filtering operations. Each index corresponds to\n * a field in the data model that supports comparison operations.\n *\n * @type {string[]}\n * @default []\n * @memberOf FilterComponent\n */\n @Input()\n indexes: string[] = [];\n\n @Input()\n multiple: boolean = false;\n\n /**\n * @description Available comparison conditions for filters.\n * @summary Defines the list of comparison operators that can be used when creating filters.\n * These conditions determine how the filter value is compared against the field value.\n * Common conditions include equality, containment, and numerical comparison operations.\n *\n * @type {string[]}\n * @default []\n * @memberOf FilterComponent\n */\n @Input()\n conditions: string[] = [\n 'Equal',\n 'Contains',\n 'Not Contains',\n 'Greater Than',\n 'Less Than',\n 'Not Equal',\n ];\n\n /**\n * @description Available sorting options for the filtered data.\n * @summary Defines the list of field names that can be used for sorting the filtered results.\n * When disableSort is false, this array is automatically merged with the indexes array\n * to provide comprehensive sorting capabilities.\n *\n * @type {string[]}\n * @default []\n * @memberOf FilterComponent\n */\n @Input()\n sortBy: string[] = [];\n\n /**\n * @description Controls whether sorting functionality is disabled.\n * @summary When set to true, prevents the automatic merging of sort and indexes arrays,\n * effectively disabling sorting capabilities. This is useful when you want to provide\n * filtering without sorting options.\n *\n * @type {boolean}\n * @default false\n * @memberOf FilterComponent\n */\n @Input()\n disableSort: boolean = false;\n\n /**\n * @description Current window width for responsive behavior.\n * @summary Stores the current browser window width in pixels. This value is updated\n * on window resize events to enable responsive filtering behavior and layout adjustments\n * based on available screen space.\n *\n * @type {number}\n * @memberOf FilterComponent\n */\n windowWidth!: number;\n\n /**\n * @description Available options for the current filter step.\n * @summary Contains the list of options available for selection in the current step.\n * This array changes dynamically based on the current step: indexes → conditions → empty for value input.\n *\n * @type {string[]}\n * @default []\n * @memberOf FilterComponent\n */\n options: string[] = [];\n\n /**\n * @description Filtered options based on user input.\n * @summary Contains the subset of options that match the current user input for real-time\n * filtering. This array is updated as the user types to show only relevant suggestions\n * in the dropdown menu.\n *\n * @type {string[]}\n * @default []\n * @memberOf FilterComponent\n */\n filteredOptions: string[] = [];\n\n /**\n * @description Complete filter objects created by the user.\n * @summary Array of complete filter objects, each containing index, condition, and value properties.\n * These represent the active filters that can be applied to data operations.\n *\n * @type {KeyValue[]}\n * @default []\n * @memberOf FilterComponent\n */\n filterValue: IFilterQueryItem[] = [];\n\n /**\n * @description Current filter being constructed.\n * @summary Temporary object that accumulates filter properties (index, condition, value)\n * during the three-step filter creation process. Gets added to filterValue when complete.\n *\n * @type {KeyValue}\n * @default {}\n * @memberOf FilterComponent\n */\n lastFilter: IFilterQueryItem = {};\n\n /**\n * @description Current step in the filter creation process.\n * @summary Tracks the current step of filter creation: 1 = index selection, 2 = condition selection,\n * 3 = value input. Automatically resets to 1 after completing a filter.\n *\n * @type {number}\n * @default 1\n * @memberOf FilterComponent\n */\n step: number = 1;\n\n /**\n * @description Controls dropdown visibility state.\n * @summary Boolean flag that determines whether the options dropdown is currently visible.\n * Used to manage the dropdown's open/close state and coordinate with focus/blur events.\n *\n * @type {boolean}\n * @default false\n * @memberOf FilterComponent\n */\n dropdownOpen: boolean = false;\n\n /**\n * @description Current input field value.\n * @summary Stores the current text input value that the user is typing. This value is\n * bound to the input field and is cleared after each successful filter step completion.\n *\n * @type {string}\n * @default ''\n * @memberOf FilterComponent\n */\n override value: string = '';\n\n /**\n * @description Current sorting field value.\n * @summary Stores the field name currently selected for sorting operations.\n * This value determines which field is used to order the filtered results.\n * Defaults to 'id' and can be changed through the sort dropdown selection.\n *\n * @type {string}\n * @default 'id'\n * @memberOf FilterComponent\n */\n sortValue: string = 'id';\n\n /**\n * @description Current sorting direction.\n * @summary Defines the direction of the sort operation - ascending or descending.\n * This value works in conjunction with sortValue to determine the complete\n * sorting configuration for filtered results.\n *\n * @type {OrderDirection}\n * @default OrderDirection.DSC\n * @memberOf FilterComponent\n */\n sortDirection: OrderDirection = OrderDirection.DSC;\n\n /**\n * @description Subscription for window resize events.\n * @summary RxJS subscription that listens for window resize events with debouncing\n * to update the windowWidth property. This enables responsive behavior and prevents\n * excessive updates during resize operations.\n *\n * @type {Subscription}\n * @memberOf FilterComponent\n */\n windowResizeSubscription!: Subscription;\n\n /**\n * @description Event emitter for filter changes.\n * @summary Emits filter events when the user creates, modifies, or clears filters.\n * The emitted value contains an array of complete filter objects or undefined when\n * filters are cleared. Parent components listen to this event to update their data display.\n *\n * @type {EventEmitter<KeyValue[] | undefined>}\n * @memberOf FilterComponent\n */\n @Output()\n filterEvent: EventEmitter<IFilterQuery | undefined> = new EventEmitter<\n IFilterQuery | undefined\n >();\n\n /**\n * @description Event emitter for search events.\n * @summary Emits search events when the user interacts with the searchbar.\n * @type {EventEmitter<string>}\n * @memberOf FilterComponent\n */\n @Output()\n searchEvent: EventEmitter<string> = new EventEmitter<string>();\n\n /**\n * @description Constructor for FilterComponent.\n * @summary Initializes a new instance of the FilterComponent.\n * Calls the parent constructor with the component name to establish base locale string generation\n * and internationalization support.\n *\n * @memberOf FilterComponent\n */\n constructor() {\n super('FilterComponent');\n addIcons({\n chevronDownOutline,\n trashOutline,\n closeOutline,\n searchOutline,\n arrowDownOutline,\n arrowUpOutline,\n chevronUpOutline,\n });\n }\n\n /**\n * @description Initializes the component after Angular first displays the data-bound properties.\n * @summary Sets up the component by initializing window width tracking, setting up resize event\n * subscriptions with debouncing, configuring sorting options, and calling the base initialization.\n * This method prepares the component for user interaction and responsive behavior.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant F as FilterComponent\n * participant W as Window\n * participant R as RxJS\n *\n * A->>F: ngOnInit()\n * F->>W: getWindowWidth()\n * W-->>F: Return current width\n * F->>R: Setup resize subscription with debounce\n * R-->>F: Subscription created\n * alt disableSort is false\n * F->>F: Merge sort and indexes arrays\n * end\n * F->>F: Call initialize()\n *\n * @returns {Promise<void>}\n * @memberOf FilterComponent\n */\n async ngOnInit(): Promise<void> {\n this.windowWidth = getWindowWidth() as number;\n this.windowResizeSubscription = fromEvent(window, 'resize')\n .pipe(debounceTime(300))\n .subscribe(() => {\n this.windowWidth = getWindowWidth() as number;\n });\n\n this.getIndexes();\n this.initialize();\n }\n\n /**\n * @description Retrieves and configures available indexes for filtering and sorting.\n * @summary Extracts field indexes from the model if available and merges them with\n * sorting options when sorting is enabled. This method sets up the available field\n * options for both filtering and sorting operations based on the model structure.\n *\n * @returns {void}\n * @memberOf FilterComponent\n */\n getIndexes(): void {\n if (this.model)\n this.indexes = Object.keys(Model.indexes(this.model as Model) || {});\n if (!this.disableSort) {\n this.sortBy = [...this.sortBy, ...this.indexes];\n if (this.repository) {\n const pk = Model.pk(this.repository.class as Constructor<Model>);\n this.sortValue = pk || this.sortValue;\n }\n }\n }\n\n /**\n * @description Cleanup method called when the component is destroyed.\n * @summary Unsubscribes from window resize events to prevent memory leaks.\n * This is essential for proper cleanup of RxJS subscriptions when the component\n * is removed from the DOM.\n *\n * @returns {void}\n * @memberOf FilterComponent\n */\n override async ngOnDestroy(): Promise<void> {\n super.ngOnDestroy();\n if (this.windowResizeSubscription)\n this.windowResizeSubscription.unsubscribe();\n this.clear();\n }\n\n /**\n * @description Handles input events from the text field.\n * @summary Processes user input and filters the available options based on the typed value.\n * This method provides real-time filtering of suggestions as the user types in the input field.\n *\n * @param {InputEvent} event - The input event containing the new value\n * @returns {void}\n * @memberOf FilterComponent\n */\n handleInput(event: InputEvent): void {\n const { value } = event.target as HTMLInputElement;\n this.filteredOptions = this.filterOptions(value);\n }\n\n /**\n * @description Handles focus events on the input field.\n * @summary Sets up the available options when the input field receives focus and opens the dropdown.\n * If no options are provided, automatically determines the appropriate options based on current step.\n * This method initializes the dropdown with contextually relevant suggestions.\n *\n * @param {string[]} options - Optional array of options to display\n * @returns {void}\n * @memberOf FilterComponent\n */\n handleFocus(options: string[] = []): void {\n if (!options.length) options = this.getOptions();\n this.filteredOptions = this.options = options;\n this.dropdownOpen = true;\n }\n\n /**\n * @description Handles blur events on the input field with delayed closing.\n * @summary Manages the dropdown closing behavior with a delay to allow for option selection.\n * Uses a two-phase approach to prevent premature closing when users click on dropdown options.\n *\n * @param {boolean} close - Internal flag to control the closing phase\n * @returns {void}\n * @memberOf FilterComponent\n */\n handleBlur(close: boolean = false): void {\n if (!close) {\n this.dropdownOpen = false;\n setTimeout(() => {\n this.handleBlur(true);\n }, 100);\n } else {\n if (!this.dropdownOpen && this.options.length) {\n setTimeout(() => {\n this.options = [];\n this.dropdownOpen = false;\n }, 50);\n }\n }\n }\n\n /**\n * @description Determines the appropriate options based on the current filter step.\n * @summary Returns the contextually relevant options for the current step in the filter creation process.\n * Step 1 shows indexes, Step 2 shows conditions, Step 3 shows no options (value input).\n *\n * @returns {string[]} Array of options appropriate for the current step\n * @memberOf FilterComponent\n */\n getOptions(): string[] {\n switch (this.step) {\n case 1:\n this.options = this.indexes;\n break;\n case 2:\n this.options = this.conditions;\n break;\n case 3:\n this.options = [];\n break;\n }\n return this.options;\n }\n\n /**\n * @description Adds a filter step or completes filter creation through a three-step process.\n * @summary Core method for building filters step by step: Step 1 (Index) → Step 2 (Condition) → Step 3 (Value).\n * When all steps are complete, creates a complete filter object and adds it to the filter collection.\n * Handles both keyboard events (Enter to submit) and programmatic calls.\n *\n * @param {string} value - The value to add for the current step\n * @param {CustomEvent} event - Optional event (KeyboardEvent triggers submission when value is empty)\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant F as FilterComponent\n *\n * U->>F: addFilter(value, event)\n * F->>F: Trim and validate value\n * alt KeyboardEvent && empty value\n * F->>F: submit() - Send current filters\n * else Valid value or step 3\n * alt Step 1 (Index)\n * F->>F: lastFilter.index = value\n * F->>F: options = conditions\n * else Step 2 (Condition)\n * F->>F: lastFilter.condition = value\n * F->>F: options = []\n * else Step 3 (Value)\n * F->>F: lastFilter.value = value\n * F->>F: Add complete filter to filterValue\n * F->>F: Reset step to 1\n * end\n * F->>F: Increment step\n * F->>F: Clear input & focus\n * F->>F: Show next options\n * end\n *\n * @memberOf FilterComponent\n */\n async addFilter(value: string, event?: CustomEvent): Promise<void> {\n value = value.trim();\n if (event instanceof KeyboardEvent && !value) {\n this.submit();\n } else {\n if ((value && !(event instanceof KeyboardEvent)) || this.step === 3) {\n const filter = this.lastFilter;\n switch (this.step) {\n case 1:\n filter['index'] = value;\n this.options = this.conditions;\n break;\n case 2:\n filter['condition'] = value;\n this.options = [];\n break;\n case 3:\n filter['value'] = value;\n this.options = this.indexes;\n break;\n }\n if (!this.filterValue.length) {\n this.filterValue.push(filter);\n } else {\n if (this.step === 1)\n this.filterValue.push(filter);\n }\n if (this.step === 3) {\n this.step = 0;\n this.filterValue[this.filterValue.length - 1] = filter;\n this.lastFilter = {};\n if(!this.multiple)\n return await this.submit();\n }\n this.step++;\n this.value = '';\n if (this.options.length)\n this.handleFocus(this.options);\n this.component.nativeElement.querySelector('#dcf-filter-field').focus();\n }\n }\n }\n\n /**\n * @description Selects an option from the dropdown suggestions.\n * @summary Handles option selection when a user clicks on a suggestion in the dropdown.\n * This method acts as a bridge between dropdown clicks and the main addFilter logic.\n *\n * @param {CustomEvent} event - The click event from the dropdown option\n * @param {string} value - The selected option value\n * @returns {void}\n * @memberOf FilterComponent\n */\n selectOption(value: string): void {\n this.addFilter(value);\n }\n\n /**\n * @description Determines if a filter option can be individually removed.\n * @summary Checks whether a filter component should display a close icon for removal.\n * Only value options can be removed individually; index and condition options are part\n * of the complete filter structure and cannot be removed separately.\n *\n * @param {string} option - The filter option text to check\n * @returns {boolean} True if the option can be cleared individually, false otherwise\n * @memberOf FilterComponent\n */\n allowClear(option: string): boolean {\n return (\n this.indexes.indexOf(option) === -1 &&\n this.conditions.indexOf(option) === -1\n );\n }\n\n /**\n * @description Removes a complete filter from the collection based on filter value.\n * @summary Removes a complete filter by matching the provided value against filter values\n * in the collection. Uses string normalization to handle accents and case differences.\n * After removal, resets the interface to show available indexes for new filter creation.\n *\n * @param {string} filter - The filter value to remove (matches against filter.value property)\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant F as FilterComponent\n *\n * U->>F: removeFilter(filterValue)\n * F->>F: cleanString(filterValue)\n * F->>F: Filter out matching filter objects\n * F->>F: Clear input value\n * F->>F: handleFocus(indexes) - Reset to index selection\n * Note over F: Filter removed and UI reset\n *\n * @memberOf FilterComponent\n */\n removeFilter(filter: string): void {\n function cleanString(filter: string): string {\n return filter\n .toLowerCase() // convert all characters to lowercase\n .normalize('NFD') // separate accent marks from characters\n .replace(/[\\u0300-\\u036f]/g, '') // remove accent marks\n .replace(/\\s+/g, ''); // remove all whitespace\n }\n this.value = '';\n this.filterValue = this.filterValue.filter(\n (item) =>\n item?.['value'] && cleanString(item?.['value']) !== cleanString(filter)\n );\n if (this.filterValue.length === 0) {\n this.step = 1;\n this.lastFilter = {};\n }\n this.handleFocus(this.indexes);\n }\n\n /**\n * @description Resets the component to its initial state.\n * @summary Clears all filter data, options, and resets the step counter to 1.\n * This method provides a clean slate for new filter creation without emitting events.\n *\n * @returns {void}\n * @memberOf FilterComponent\n */\n reset(submit: boolean = true): void {\n this.options = this.filteredOptions = this.filterValue = [];\n this.step = 1;\n this.lastFilter = {};\n this.value = '';\n if (submit) {\n setTimeout(() => {\n this.submit();\n }, 100);\n }\n }\n\n /**\n * @description Clears all filters and notifies parent components.\n * @summary Resets the component state and emits undefined to notify parent components\n * that all filters have been cleared. This triggers any connected data refresh logic.\n *\n * @param {string} value - Optional parameter (currently unused)\n * @returns {void}\n * @memberOf FilterComponent\n */\n clear(value?: string): void {\n if (!value) this.reset();\n }\n\n /**\n * @description Submits the current filter collection to parent components.\n * @summary Emits the current filter array to parent components when filters are ready\n * to be applied. Only emits if there are active filters. Clears options after submission.\n *\n * @returns {Promise<void>}\n * @memberOf FilterComponent\n */\n override async submit(): Promise<void> {\n this.filterEvent.emit({\n query: this.filterValue.length > 0 ? this.filterValue : undefined,\n sort: {\n value: this.sortValue,\n direction: this.sortDirection,\n },\n } as IFilterQuery);\n if (this.filterValue.length === 0) this.options = [];\n }\n\n /**\n * @description Toggles the sort direction between ascending and descending.\n * @summary Handles sort direction changes by toggling between ASC and DSC values.\n * When the direction changes, automatically triggers a submit to apply the new\n * sorting configuration to the filtered results.\n *\n * @returns {void}\n * @memberOf FilterComponent\n */\n handleSortDirectionChange(): void {\n const direction =\n this.sortDirection === OrderDirection.ASC\n ? OrderDirection.DSC\n : OrderDirection.ASC;\n if (direction !== this.sortDirection) {\n this.sortDirection = direction;\n this.submit();\n }\n }\n\n /**\n * @description Handles sort field selection changes from the dropdown.\n * @summary Processes sort field changes when users select a different field\n * from the sort dropdown. Updates the sortValue property and triggers\n * a submit to apply the new sorting configuration if the value has changed.\n *\n * @param {CustomEvent} event - The select change event containing the new sort field value\n * @returns {void}\n * @memberOf FilterComponent\n */\n handleSortChange(event: CustomEvent): void {\n const target = event.target as HTMLIonSelectElement;\n const value = target.value;\n if (value !== this.sortValue) {\n this.sortValue = value as string;\n this.submit();\n }\n }\n\n /**\n * @description Filters available options based on user input with visual highlighting.\n * @summary Performs real-time filtering of available options based on user input.\n * Also handles visual highlighting of matching options in the dropdown. Returns all\n * options if input is less than 2 characters for performance optimization.\n *\n * @param {string | null | undefined} value - The search value to filter by\n * @returns {string[]} Array of filtered options that match the input\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant F as FilterComponent\n * participant D as DOM\n *\n * U->>F: filterOptions(inputValue)\n * alt inputValue < 2 characters\n * F->>D: Remove existing highlights\n * F-->>U: Return all options\n * else inputValue >= 2 characters\n * F->>D: Query all option elements\n * F->>D: Add highlight to first matching option\n * F->>F: Filter options by substring match\n * F-->>U: Return filtered options\n * end\n *\n * @memberOf FilterComponent\n */\n filterOptions(value: string | null | undefined): string[] {\n const optionsElement = this.optionsFilterElement.nativeElement;\n\n if (!value?.length || !value || value.length < 2) {\n const filteredOption = optionsElement.querySelector(\n '.dcf-filtering-item'\n );\n if (filteredOption) filteredOption.classList.remove('dcf-filtering-item');\n return this.options;\n }\n const options = optionsElement.querySelectorAll('.dcf-item');\n for (const option of options) {\n const isActive = option.textContent\n ?.toLowerCase()\n .includes(value.toLowerCase());\n if (isActive) {\n option.classList.add('dcf-filtering-item');\n break;\n }\n }\n return this.options.filter((option: string) =>\n option.toLowerCase().includes(value.toLowerCase() as string)\n );\n }\n\n /**\n * @description Handles search events from the integrated searchbar component.\n * @summary Processes search input from the searchbar and emits search events\n * to parent components. This method acts as a bridge between the internal\n * searchbar component and external search event listeners.\n *\n * @param {string | undefined} value - The search value entered by the user\n * @returns {void}\n * @memberOf FilterComponent\n */\n handleSearch(value: string | undefined): void {\n this.searchEvent.emit(value);\n }\n}\n","\n@if (!indexes.length) {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n}\n\n<div [id]=\"uid\" class=\"dcf-grid dcf-grid-small dcf-grid-match dcf-filter-component\" [class.dcf-hidden]=\"!indexes.length\" #component>\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-filter\">\n <div class=\"dcf-input\">\n @for(filter of filterValue; track trackItemFn($index, filter?.['index'])) {\n @if (filter?.['index']) {\n <ion-chip [outline]=\"true\">{{ filter?.['index'] }}</ion-chip>\n }\n @if (filter?.['condition']) {\n <ion-chip [outline]=\"true\">{{ filter?.['condition'] }}</ion-chip>\n }\n @if (filter?.['value']) {\n <ion-chip [outline]=\"true\" class=\"dcf-filter-value\">\n {{ filter?.['value'] }}\n <ion-icon tabindex=\"0\" name=\"close-outline\" (click)=\"removeFilter(filter?.['value'])\" size=\"small\"></ion-icon>\n </ion-chip>\n }\n }\n <div class=\"dcf-width-1-1\">\n <!-- [readonly]=\"step !== 3\" -->\n <input\n fill=\"none\"\n [(ngModel)]=\"value\"\n (keydown.enter)=\"addFilter(value, $event)\"\n (keydown.backspace)=\"clear(value)\"\n (input)=\"handleInput($event)\"\n (click)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n type=\"text\"\n id=\"dcf-filter-field\"\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n\n />\n @if (windowWidth >= 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n @if (filterValue.length > 0) {\n <div class=\"dcf-icon-clear\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"clear()\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n <div class=\"dcf-icon-search\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"submit()\">\n <ion-icon aria-hidden=\"true\" name=\"search-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n </div>\n @if (windowWidth < 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n @if (!disableSort) {\n <div class=\"dcf-width-1-5@m dcf-width-1-1 dcf-sort-container\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-grid-match\">\n <div class=\"dcf-width-expand\">\n <ion-select\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n class=\"dcf-sort-select\"\n (ionChange)=\"handleSortChange($event)\"\n interface=\"popover\"\n [value]=\"sortValue\"\n label-placement=\"floating\"\n fill=\"outline\"\n [label]=\"locale + '.sort' | translate\"\n >\n @for(sort of sortBy; track sort) {\n\n <ion-select-option [value]=\"sort\">{{ sort | translate }}</ion-select-option>\n }\n </ion-select>\n </div>\n <div class=\"dcf-width-auto\">\n <ion-button (click)=\"handleSortDirectionChange()\" fill=\"clear\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" [color]=\"!isDarkMode ? 'primary' : 'light'\" [name]=\"sortDirection === 'desc' ? 'arrow-down-outline' : 'arrow-up-outline'\"></ion-icon>\n </ion-button>\n </div>\n </div>\n </div>\n }\n</div>\n\n\n","/**\n * @module module:lib/components/pagination/pagination.component\n * @description Pagination component module.\n * @summary Provides `PaginationComponent` for displaying page navigation controls\n * and emitting pagination events. Use this component to navigate paginated data\n * in lists and other collections.\n *\n * @link {@link PaginationComponent}\n */\n\nimport { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { IonIcon } from '@ionic/angular/standalone';\nimport { addIcons } from 'ionicons';\nimport { chevronBackOutline, chevronForwardOutline } from 'ionicons/icons';\nimport { NgxComponentDirective } from '../../engine/NgxComponentDirective';\nimport { KeyValue } from '../../engine/types';\nimport { ComponentEventNames } from '../../engine/constants';\nimport { IPaginationCustomEvent } from '../../engine/interfaces';\n\n/**\n * @description A pagination component for navigating through multiple pages of content.\n * @summary This component provides a user interface for paginated content navigation,\n * displaying page numbers and navigation controls. It supports customizable page counts,\n * current page tracking, and emits events when users navigate between pages.\n *\n * The component intelligently handles large numbers of pages by showing a subset of page\n * numbers with ellipses to indicate skipped pages, ensuring the UI remains clean and usable\n * even with many pages.\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant P as PaginationComponent\n * participant E as External Component\n *\n * U->>P: Click page number\n * P->>P: navigate(page)\n * P->>P: handleClick(direction, page)\n * P->>E: Emit clickEvent with IPaginationCustomEvent\n *\n * U->>P: Click next button\n * P->>P: next()\n * P->>P: handleClick('next')\n * P->>E: Emit clickEvent with IPaginationCustomEvent\n *\n * U->>P: Click previous button\n * P->>P: previous()\n * P->>P: handleClick('previous')\n * P->>E: Emit clickEvent with IPaginationCustomEvent\n *\n * @example\n * <ngx-decaf-pagination\n * [pages]=\"10\"\n * [current]=\"3\"\n * (clickEvent)=\"handlePageChange($event)\">\n * </ngx-decaf-pagination>\n *\n * @extends {NgxBaseComponentDirective}\n * @implements {OnInit}\n */\n@Component({\n selector: 'ngx-decaf-pagination',\n templateUrl: './pagination.component.html',\n styleUrls: ['./pagination.component.scss'],\n imports: [\n TranslatePipe,\n IonIcon\n ],\n standalone: true,\n host: {'[attr.id]': 'uid'}\n})\nexport class PaginationComponent extends NgxComponentDirective implements OnInit {\n\n /**\n * @description The total number of pages to display in the pagination component.\n * @summary Specifies the total number of pages available for navigation. This is a required\n * input that determines how many page numbers will be generated and displayed.\n *\n * @type {number}\n * @required\n * @memberOf PaginationComponent\n */\n @Input({ required: true })\n totalPages!: number;\n\n /**\n * @description The currently active page number.\n * @summary Specifies which page is currently active or selected. This value is used\n * to highlight the current page in the UI and as a reference point for navigation.\n *\n * @type {number}\n * @default 1\n * @memberOf PaginationComponent\n */\n @Input()\n current = 1;\n\n /**\n * @description Array of page objects for rendering in the template.\n * @summary Contains the processed page data used for rendering the pagination UI.\n * Each object includes an index (page number) and text representation.\n *\n * @type {KeyValue[]}\n * @memberOf PaginationComponent\n */\n pages!: KeyValue[];\n\n /**\n * @description The last page number in the pagination.\n * @summary Stores the number of the last page for boundary checking during navigation.\n *\n * @type {number}\n * @memberOf PaginationComponent\n */\n last!: number;\n\n /**\n * @description Event emitter for pagination navigation events.\n * @summary Emits a custom event when users navigate between pages, either by clicking\n * on page numbers or using the next/previous buttons. The event contains information\n * about the navigation direction and the target page number.\n *\n * @type {EventEmitter<IPaginationCustomEvent>}\n * @memberOf PaginationComponent\n */\n @Output()\n clickEvent: EventEmitter<IPaginationCustomEvent> = new EventEmitter<IPaginationCustomEvent>();\n\n /**\n * @constructor\n * @description Initializes a new instance of the PaginationComponent.\n * Calls the parent constructor with the component name for generate base locale string.\n */\n constructor() {\n super(\"PaginationComponent\");\n addIcons({chevronBackOutline, chevronForwardOutline});\n }\n\n /**\n * @description Initializes the component after Angular sets the input properties.\n * @summary Sets up the component by initializing the locale settings based on the\n * translatable property, generating the page numbers based on the total pages and\n * current page, and storing the last page number for boundary checking.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant P as PaginationComponent\n *\n * A->>P: ngOnInit()\n * P->>P: getLocale(translatable)\n * P->>P: Set locale\n * P->>P: getPages(data, current)\n * P->>P: Set pages array\n * P->>P: Set last page number\n *\n * @returns {void}\n * @memberOf PaginationComponent\n */\n ngOnInit(): void {\n // this.locale = this.getLocale(this.translatable);\n this.pages = this.getPages(this.totalPages, this.current) as KeyValue[];\n this.last = this.totalPages;\n }\n\n /**\n * @description Handles click events on pagination controls.\n * @summary Processes user interactions with the pagination component, updating the\n * current page if specified and emitting an event with navigation details. This method\n * is called when users click on page numbers or navigation buttons.\n *\n * @param {('next' | 'previous')} direction - The direction of navigation\n * @param {number} [page] - Optional page number to navigate to directly\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant P as PaginationComponent\n * participant E as External Component\n *\n * U->>P: Click pagination control\n * P->>P: handleClick(direction, page?)\n * alt page is provided\n * P->>P: Update current page\n * end\n * P->>E: Emit clickEvent with direction and page\n *\n * @memberOf PaginationComponent\n */\n handleClick(direction: 'next' | 'previous', page?: number): void {\n if (page)\n this.current = page;\n this.clickEvent.emit({\n name: ComponentEventNames.CLICK,\n data: {\n direction,\n page: this.current\n },\n component: this.componentName\n } as IPaginationCustomEvent);\n }\n\n /**\n * @description Generates the array of page objects for display.\n * @summary Creates an array of page objects based on the total number of pages and\n * the current page. For small page counts (≤5), all pages are shown. For larger page\n * counts, a subset is shown with ellipses to indicate skipped pages. This ensures\n * the pagination UI remains clean and usable even with many pages.\n *\n * @param {number} total - The total number of pages\n * @param {number} [current] - The current active page (defaults to this.current)\n * @returns {KeyValue[]} Array of page objects with index and text properties\n *\n * @mermaid\n * flowchart TD\n * A[Start] --> B{total <= 5?}\n * B -->|Yes| C[Show all pages]\n * B -->|No| D[Show first page]\n * D --> E[Show last pages]\n * E --> F[Add ellipses for skipped pages]\n * C --> G[Return pages array]\n * F --> G\n *\n * @memberOf PaginationComponent\n */\n getPages(total: number, current?: number): KeyValue[] {\n if (!current) current = this.current;\n\n const pages: KeyValue[] = [];\n\n function getPage(index: number | null, text = '', clazz = 'button'): void {\n if (pages.some(item => item['index'] === index)) return;\n pages.push({ index, text: index != null ? index.toString().padStart(2, '0') : text, class: clazz });\n }\n\n if (total <= 5) {\n for (let i = 1; i <= total; i++) getPage(i);\n } else {\n // Adiciona os dois primeiros\n getPage(1);\n getPage(2);\n\n // Adiciona \"...\" entre os blocos\n if (current && current > 3) getPage(null, '...');\n\n // Adiciona a página atual (se estiver no meio)\n if (current && current > 2 && current < total - 1) getPage(current);\n\n // Adiciona \"...\" entre os blocos\n if (current && current < total - 2) getPage(null, '...' , 'separator');\n\n // Adiciona os dois últimos\n getPage(total - 1);\n getPage(total);\n }\n\n return pages;\n }\n\n /**\n * @description Gets the current active page number.\n * @summary Returns the current page number that is active in the pagination component.\n * This method provides a way to access the current page state from outside the component.\n *\n * @returns {number} The current page number\n * @memberOf PaginationComponent\n */\n getCurrent(): number {\n return this.current;\n }\n\n /**\n * @description Navigates to the next page.\n * @summary Increments the current page number if not at the last page and triggers\n * the click event handler with 'next' direction. This method is typically called\n * when the user clicks on the \"next\" button in the pagination UI.\n *\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant P as PaginationComponent\n *\n * U->>P: Click next button\n * P->>P: next()\n * alt page <= max pages\n * P->>P: Increment current page\n * P->>P: handleClick('next')\n * end\n *\n * @memberOf PaginationComponent\n */\n next(): void {\n const page = this.current + 1;\n if (page <= Object.keys(this.pages)?.length || 0) {\n this.current = page;\n this.handleClick('next');\n }\n }\n\n /**\n * @description Navigates to the previous page.\n * @summary Decrements the current page number if not at the first page and triggers\n * the click event handler with 'previous' direction. This method is typically called\n * when the user clicks on the \"previous\" button in the pagination UI.\n *\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant P as PaginationComponent\n *\n * U->>P: Click previous button\n * P->>P: previous()\n * alt page > 0\n * P->>P: Decrement current page\n * P->>P: handleClick('previous')\n * end\n *\n * @memberOf PaginationComponent\n */\n previous(): void {\n const page = this.current - 1;\n if (page > 0) {\n this.current = page;\n this.handleClick('previous');\n }\n }\n\n /**\n * @description Navigates to a specific page number.\n * @summary Updates the current page to the specified page number and triggers\n * the click event handler with the appropriate direction. This method is typically\n * called when the user clicks directly on a page number in the pagination UI.\n *\n * @param {number | null} page - The page number to navigate to\n * @returns {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant P as PaginationComponent\n *\n * U->>P: Click page number\n * P->>P: navigate(page)\n * alt page is not null and different from current\n * P->>P: Determine direction (next/previous)\n * P->>P: handleClick(direction, page)\n * end\n *\n * @memberOf PaginationComponent\n */\n navigate(page: number | null): void {\n if (page !== null && this.current !== page as number)\n this.handleClick(page > this.current ? 'next' : 'previous', page);\n }\n}\n"," <div [id]=\"uid\" class=\"dcf-paginator-container dcf-flex dcf-flex-center\" #component>\n <div class=\"dcf-width-1-1\">\n <div class=\"dcf-pagination-resume\" [innerHTML]=\"locale + '.resume' | translate:{'0': current, '1': last}\"></div>\n <div #paginationComponent class=\"dcf-pagination dcf-flex-center\">\n <div\n aria-label=\"previous\"\n tabindex=\"0\"\n (click)=\"previous()\"\n (keydown.enter)=\"previous()\" [class.dcf-disabled]=\"current === 1\">\n <ion-icon name=\"chevron-back-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n @for(page of pages; track page) {\n <div tabindex=\"0\" [class]=\"page['class']\" (click)=\"navigate(page['index'])\"\n (keydown.enter)=\"navigate(page['index'])\"\n [class.dcf-active]=\"current === page['index']\">\n <span class=\"page-item\">{{ page['text'] }}</span>\n </div>\n }\n <div\n tabindex=\"0\" (click)=\"next()\"\n (keydown.enter)=\"next()\"\n [class.dcf-disabled]=\"current === last\">\n <ion-icon name=\"chevron-forward-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n </div>\n </div>\n</div>\n","/**\n * @module module:lib/components/list/list.component\n * @description List component module.\n * @summary Provides the `ListComponent` which renders collections of data with\n * support for infinite scroll, pagination, searching, filtering, custom item\n * rendering and refresh events. Use this module's `ListComponent` to display\n * lists sourced from models, functions or direct data arrays.\n *\n * @link {@link ListComponent}\n */\n\nimport {\n Component,\n OnInit,\n EventEmitter,\n Output,\n Input,\n HostListener,\n OnDestroy,\n} from '@angular/core';\nimport {\n InfiniteScrollCustomEvent,\n RefresherCustomEvent,\n SpinnerTypes,\n} from '@ionic/angular';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n IonButton,\n IonInfiniteScroll,\n IonInfiniteScrollContent,\n IonItem,\n IonLabel,\n IonList,\n IonRefresher,\n IonRefresherContent,\n IonSkeletonText,\n IonText,\n IonThumbnail,\n} from '@ionic/angular/standalone';\nimport { OperationKeys } from '@decaf-ts/db-decorators';\nimport { Model, Primitives } from '@decaf-ts/decorator-validation';\nimport { Condition, Observer, OrderDirection, Paginator } from '@decaf-ts/core';\nimport { debounceTime, Subject } from 'rxjs';\nimport { NgxComponentDirective } from '../../engine/NgxComponentDirective';\nimport { Dynamic } from '../../engine/decorators';\nimport { KeyValue, FunctionLike, DecafRepository } from '../../engine/types';\nimport {\n ComponentEventNames,\n ComponentsTagNames,\n DefaultListEmptyOptions,\n ListComponentsTypes,\n} from '../../engine/constants';\nimport {\n IBaseCustomEvent,\n ListItemCustomEvent,\n IPaginationCustomEvent,\n IFilterQuery,\n IFilterQueryItem,\n IListEmptyOptions,\n} from '../../engine/interfaces';\nimport { stringToBoolean, formatDate, isValidDate } from '../../utils/helpers';\nimport { SearchbarComponent } from '../searchbar/searchbar.component';\nimport { EmptyStateComponent } from '../empty-state/empty-state.component';\nimport { ComponentRendererComponent } from '../component-renderer/component-renderer.component';\nimport { PaginationComponent } from '../pagination/pagination.component';\nimport { FilterComponent } from '../filter/filter.component';\n\n/**\n * @description A versatile list component that supports various data display modes.\n * @summary This component provides a flexible way to display lists of data with support\n * for infinite scrolling, pagination, searching, and custom item rendering. It can fetch\n * data from various sources including models, functions, or direct data input.\n *\n * The component supports two main display types:\n * 1. Infinite scrolling - Loads more data as the user scrolls\n * 2. Pagination - Displays data in pages with navigation controls\n *\n * Additional features include:\n * - Pull-to-refresh functionality\n * - Search filtering\n * - Empty state customization\n * - Custom item rendering\n * - Event emission for interactions\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant L as ListComponent\n * participant D as Data Source\n * participant E as External Components\n *\n * U->>L: Initialize component\n * L->>L: ngOnInit()\n * L->>D: Request initial data\n * D-->>L: Return data\n * L->>L: Process and display data\n *\n * alt User scrolls (Infinite mode)\n * U->>L: Scroll to bottom\n * L->>D: Request more data\n * D-->>L: Return additional data\n * L->>L: Append to existing data\n * else User changes page (Paginated mode)\n * U->>L: Click page number\n * L->>L: handlePaginate()\n * L->>D: Request data for page\n * D-->>L: Return page data\n * L->>L: Replace displayed data\n * end\n *\n * alt User searches\n * U->>L: Enter search term\n * L->>L: handleSearch()\n * L->>D: Filter data by search term\n * D-->>L: Return filtered data\n * L->>L: Update displayed data\n * end\n *\n * alt User clicks item\n * U->>L: Click list item\n * L->>L: handleClick()\n * L->>E: Emit clickEvent\n * end\n *\n * @example\n * <ngx-decaf-list\n * [source]=\"dataSource\"\n * [limit]=\"10\"\n * [type]=\"'infinite'\"\n * [showSearchbar]=\"true\"\n * (clickEvent)=\"handleItemClick($event)\"\n * (refreshEvent)=\"handleRefresh($event)\">\n * </ngx-decaf-list>\n *\n * @extends {NgxBaseComponentDirective}\n * @implements {OnInit}\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-list',\n templateUrl: './list.component.html',\n styleUrls: ['./list.component.scss'],\n standalone: true,\n imports: [\n TranslatePipe,\n IonRefresher,\n IonButton,\n PaginationComponent,\n IonList,\n IonItem,\n IonThumbnail,\n IonSkeletonText,\n IonLabel,\n IonText,\n IonRefresherContent,\n IonInfiniteScroll,\n IonInfiniteScrollContent,\n IonThumbnail,\n IonSkeletonText,\n SearchbarComponent,\n EmptyStateComponent,\n FilterComponent,\n ComponentRendererComponent,\n ],\n host: { '[attr.id]': 'uid' },\n})\nexport class ListComponent\n extends NgxComponentDirective\n implements OnInit, OnDestroy\n{\n /**\n * @description The display mode for the list component.\n * @summary Determines how the list data is loaded and displayed. Options include:\n * - INFINITE: Loads more data as the user scrolls (infinite scrolling)\n * - PAGINATED: Displays data in pages with navigation controls\n *\n * @type {ListComponentsTypes}\n * @default ListComponentsTypes.INFINITE\n * @memberOf ListComponent\n */\n @Input()\n type: ListComponentsTypes = ListComponentsTypes.INFINITE;\n\n /**\n * @description Controls the visibility of the search bar.\n * @summary When set to true, displays a search bar at the top of the list that allows\n * users to filter the list items. The search functionality works by filtering the\n * existing data or by triggering a new data fetch with search parameters.\n *\n * @type {boolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n showSearchbar: boolean = true;\n\n /**\n * @description Direct data input for the list component.\n * @summary Provides a way to directly pass data to the list component instead of\n * fetching it from a source. When both data and source are provided, the component\n * will use the source to fetch data only if the data array is empty.\n *\n * @type {KeyValue[] | undefined}\n * @default undefined\n * @memberOf ListComponent\n */\n @Input()\n data?: KeyValue[] | undefined = undefined;\n\n /**\n * @description The data source for the list component.\n * @summary Specifies where the list should fetch its data from. This can be either:\n * - A string URL or endpoint identifier\n * - A function that returns data when called\n * The component will call this source when it needs to load or refresh data.\n *\n * @type {string | FunctionLike}\n * @required\n * @memberOf ListComponent\n */\n @Input()\n source!: string | FunctionLike;\n\n /**\n * @description The starting index for data fetching.\n * @summary Specifies the index from which to start fetching data. This is used\n * for pagination and infinite scrolling to determine which subset of data to load.\n *\n * @type {number}\n * @default 0\n * @memberOf ListComponent\n */\n @Input()\n start: number = 0;\n\n /**\n * @description The number of items to fetch per page or load operation.\n * @summary Determines how many items are loaded at once during pagination or\n * infinite scrolling. This affects the size of data chunks requested from the source.\n *\n * @type {number}\n * @default 10\n * @memberOf ListComponent\n */\n @Input()\n limit: number = 10;\n\n /**\n * @description Controls whether more data can be loaded.\n * @summary When set to true, the component will allow loading additional data\n * through infinite scrolling or pagination. When false, the component will not\n * attempt to load more data beyond what is initially displayed.\n *\n * @type {boolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n loadMoreData: boolean = true;\n\n /**\n * @description The style of dividing lines between list items.\n * @summary Determines how dividing lines appear between list items. Options include:\n * - \"inset\": Lines are inset from the edges\n * - \"full\": Lines extend the full width\n * - \"none\": No dividing lines\n *\n * @type {\"inset\" | \"full\" | \"none\"}\n * @default \"full\"\n * @memberOf ListComponent\n */\n @Input()\n lines: 'inset' | 'full' | 'none' = 'full';\n\n /**\n * @description Controls whether the list has inset styling.\n * @summary When set to true, the list will have inset styling with rounded corners\n * and margin around the edges. This creates a card-like appearance for the list.\n *\n * @type {boolean}\n * @default false\n * @memberOf ListComponent\n */\n @Input()\n inset: boolean = false;\n\n /**\n * @description The threshold for triggering infinite scroll loading.\n * @summary Specifies how close to the bottom of the list the user must scroll\n * before the component triggers loading of additional data. This is expressed\n * as a percentage of the list height.\n *\n * @type {string}\n * @default \"15%\"\n * @memberOf ListComponent\n */\n @Input()\n scrollThreshold: string = '15%';\n\n /**\n * @description The position where new items are added during infinite scrolling.\n * @summary Determines whether new items are added to the top or bottom of the list\n * when loading more data through infinite scrolling.\n *\n * @type {\"bottom\" | \"top\"}\n * @default \"bottom\"\n * @memberOf ListComponent\n */\n @Input()\n scrollPosition: 'bottom' | 'top' = 'bottom';\n\n /**\n * @description Custom text to display during loading operations.\n * @summary Specifies the text shown in the loading indicator when the component\n * is fetching data. If not provided, a default loading message will be used.\n *\n * @type {string | undefined}\n * @memberOf ListComponent\n */\n @Input()\n loadingText?: string;\n\n /**\n * @description Controls the visibility of the pull-to-refresh feature.\n * @summary When set to true, enables the pull-to-refresh functionality that allows\n * users to refresh the list data by pulling down from the top of the list.\n *\n * @type {boolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n showRefresher: boolean = true;\n\n /**\n * @description Controls the visibility of the create button.\n * @summary When set to true, displays a button to create new items in the list.\n *\n * @type {boolean}\n * @default false\n * @memberOf ListComponent\n */\n @Input()\n createButton: boolean = false;\n\n /**\n * @description The type of spinner to display during loading operations.\n * @summary Specifies the visual style of the loading spinner shown during data\n * fetching operations. Uses Ionic's predefined spinner types.\n *\n * @type {SpinnerTypes}\n * @default \"circular\"\n * @memberOf ListComponent\n */\n @Input()\n loadingSpinner: SpinnerTypes = 'circular';\n\n // /**\n // * @description Query parameters for data fetching.\n // * @summary Specifies additional query parameters to use when fetching data from\n // * the source. This can be provided as a string (JSON) or a direct object.\n // *\n // * @type {string | KeyValue | undefined}\n // * @memberOf ListComponent\n // */\n // @Input()\n // query?: string | KeyValue;\n\n /**\n * @description Controls whether the filtering functionality is enabled.\n * @summary When set to true, enables the filter component that allows users to create\n * complex search criteria with multiple field filters, conditions, and values.\n * When false, disables the filter interface entirely.\n *\n * @type {boolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n enableFilter: boolean = true;\n\n /**\n * @description Sorting parameters for data fetching.\n * @summary Specifies how the fetched data should be sorted. This can be provided\n * as a string (field name with optional direction) or a direct object.\n *\n * @type {string | KeyValue | undefined}\n * @memberOf ListComponent\n */\n @Input()\n sortDirection: OrderDirection = OrderDirection.DSC;\n\n /**\n * @description Sorting parameters for data fetching.\n * @summary Specifies how the fetched data should be sorted. This can be provided\n * as a string (field name with optional direction) or a direct object.\n *\n * @type {string | KeyValue | undefined}\n * @memberOf ListComponent\n */\n @Input()\n sortBy!: string;\n\n /**\n * @description Controls whether sorting functionality is disabled.\n * @summary When set to true, disables the sort controls and prevents users from\n * changing the sort order or field. The list will maintain its default or\n * programmatically set sort configuration without user interaction.\n *\n * @type {boolean}\n * @default false\n * @memberOf ListComponent\n */\n @Input()\n disableSort: boolean = false;\n\n /**\n * @description Configuration for the empty state display.\n * @summary Customizes how the empty state is displayed when no data is available.\n * This includes the title, subtitle, button text, icon, and navigation link.\n *\n * @type {Partial<IListEmptyOptions>}\n * @default {\n * title: 'empty.title',\n * subtitle: 'empty.subtitle',\n * showButton: false,\n * icon: 'alert-circle-outline',\n * buttonText: 'locale.empty.button',\n * link: ''\n * }\n * @memberOf ListComponent\n */\n @Input()\n empty: Partial<IListEmptyOptions> = {};\n\n /**\n * @description The current page number in paginated mode.\n * @summary Tracks which page is currently being displayed when the component\n * is in paginated mode. This is used for pagination controls and data fetching.\n *\n * @type {number}\n * @default 1\n * @memberOf ListComponent\n */\n page: number = 1;\n\n /**\n * @description The total number of pages available.\n * @summary Stores the calculated total number of pages based on the data size\n * and limit. This is used for pagination controls and boundary checking.\n *\n * @type {number}\n * @memberOf ListComponent\n */\n pages!: number;\n\n\n /**\n * @description Array used for rendering skeleton loading placeholders.\n * @summary Contains placeholder items that are displayed during data loading.\n * The length of this array determines how many skeleton items are shown.\n *\n * @type {string[]}\n * @default new Array(2)\n * @memberOf ListComponent\n */\n skeletonData: string[] = new Array(2);\n\n /**\n * @description The processed list items ready for display.\n * @summary Stores the current set of items being displayed in the list after\n * processing from the raw data source. This may be a subset of the full data\n * when using pagination or infinite scrolling.\n *\n * @type {KeyValue[]}\n * @memberOf ListComponent\n */\n items!: KeyValue[];\n\n /**\n * @description The current search query value.\n * @summary Stores the text entered in the search bar. This is used to filter\n * the list data or to send as a search parameter when fetching new data.\n *\n * @type {string | undefined}\n * @memberOf ListComponent\n */\n searchValue?: string | IFilterQuery | undefined;\n\n searching: boolean = false;\n\n /**\n * @description A paginator object for handling pagination operations.\n * @summary Provides a paginator object that can be used to retrieve and navigate\n * through data in chunks, reducing memory usage and improving performance.\n *\n * The paginator object is initialized in the `ngOnInit` lifecycle hook and is\n * used to fetch and display data in the pagination component. It is an instance\n * of the `Paginator` class from the `@decaf-ts/core` package, which provides\n * methods for querying and manipulating paginated data.\n *\n * @type {Paginator<Model>}\n * @memberOf PaginationComponent\n */\n paginator!: Paginator<Model> | undefined;\n\n /**\n * @description The last page number that was displayed.\n * @summary Keeps track of the previously displayed page number, which is useful\n * for handling navigation and search operations in paginated mode.\n *\n * @type {number}\n * @default 1\n * @memberOf ListComponent\n */\n lastPage: number = 1;\n\n\n /**\n * @description Event emitter for item click interactions.\n * @summary Emits an event when a list item is clicked. The event includes the data\n * of the clicked item, allowing parent components to respond to the interaction.\n *\n * @type {EventEmitter<KeyValue>}\n * @memberOf ListComponent\n */\n @Output()\n clickEvent: EventEmitter<ListItemCustomEvent | IBaseCustomEvent> =\n new EventEmitter<ListItemCustomEvent | IBaseCustomEvent>();\n\n /**\n * @description Subject for debouncing click events.\n * @summary Uses RxJS Subject to collect click events and emit them after a debounce\n * period. This prevents multiple rapid clicks from triggering multiple events.\n *\n * @private\n * @type {Subject<CustomEvent | ListItemCustomEvent | IBaseCustomEvent>}\n * @memberOf ListComponent\n */\n private clickItemSubject: Subject<\n CustomEvent | ListItemCustomEvent | IBaseCustomEvent\n > = new Subject<CustomEvent | ListItemCustomEvent | IBaseCustomEvent>();\n\n /**\n * @description Subject for debouncing repository observation events.\n * @summary RxJS Subject that collects repository change events and emits them after\n * a debounce period. This prevents multiple rapid repository changes from triggering\n * multiple list refresh operations, improving performance and user experience.\n *\n * @private\n * @type {Subject<any>}\n * @memberOf ListComponent\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private observerSubjet: Subject<any> = new Subject<any>();\n\n /**\n * @description Observer object for repository change notifications.\n * @summary Implements the Observer interface to receive notifications when the\n * underlying data repository changes. This enables automatic list updates when\n * data is created, updated, or deleted through the repository.\n *\n * @private\n * @type {Observer}\n * @memberOf ListComponent\n */\n private observer!: Observer;\n\n /**\n * @description List of available indexes for data querying and filtering.\n * @summary Provides a list of index names that can be used to optimize data querying and filtering\n * operations, especially in scenarios with large datasets.\n *\n * Indexes can significantly improve the performance of data retrieval by allowing the database\n * to quickly locate and retrieve relevant data based on indexed fields.\n *\n * @type {string[]}\n * @default []\n * @memberOf ListComponent\n */\n indexes!: string[];\n\n /**\n * @description Initializes a new instance of the ListComponent.\n * @summary Creates a new ListComponent and sets up the base component with the appropriate\n * component name. This constructor is called when Angular instantiates the component and\n * before any input properties are set. It passes the component name to the parent class\n * constructor to enable proper localization and component identification.\n *\n * The constructor is intentionally minimal, with most initialization logic deferred to\n * the ngOnInit lifecycle hook. This follows Angular best practices by keeping the constructor\n * focused on dependency injection and basic setup, while complex initialization that depends\n * on input properties is handled in ngOnInit.\n *\n * @memberOf ListComponent\n */\n constructor() {\n super('ListComponent');\n }\n\n /**\n * @description Initializes the component after Angular sets the input properties.\n * @summary Sets up the component by initializing event subscriptions, processing boolean\n * inputs, and loading the initial data. This method prepares the component for user\n * interaction by ensuring all properties are properly initialized and data is loaded.\n *\n * @returns {Promise<void>}\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant L as ListComponent\n * participant D as Data Source\n *\n * A->>L: ngOnInit()\n * L->>L: Set up click event debouncing\n * L->>L: Process boolean inputs\n * L->>L: Configure component based on inputs\n * L->>L: refresh()\n * L->>D: Request initial data\n * D-->>L: Return data\n * L->>L: Process and display data\n * L->>L: Configure empty state if needed\n * L->>L: initialize()\n *\n * @memberOf ListComponent\n */\n async ngOnInit(): Promise<void> {\n this.observer = {\n refresh: async (...args: unknown[]): Promise<void> =>\n this.observeRepository(...args),\n };\n\n this.clickItemSubject\n .pipe(debounceTime(100))\n .subscribe((event) =>\n this.clickEventEmit(event as ListItemCustomEvent | IBaseCustomEvent)\n );\n this.observerSubjet\n .pipe(debounceTime(100))\n .subscribe((args) => this.handleObserveEvent(args[0], args[1], args[2]));\n this.limit = Number(this.limit);\n this.start = Number(this.start);\n\n this.enableFilter = stringToBoolean(this.enableFilter);\n this.inset = stringToBoolean(this.inset);\n this.showRefresher = stringToBoolean(this.showRefresher);\n this.loadMoreData = stringToBoolean(this.loadMoreData);\n this.showSearchbar = stringToBoolean(this.showSearchbar);\n this.disableSort = stringToBoolean(this.disableSort);\n\n if (!this.operations || !this.operations.includes(OperationKeys.CREATE))\n this.createButton = false;\n\n if (typeof this.item?.['tag'] === 'boolean' && this.item?.['tag'] === true)\n this.item['tag'] = ComponentsTagNames.LIST_ITEM as string;\n this.empty = Object.assign({}, DefaultListEmptyOptions, this.empty);\n await this.refresh();\n if (!this.initialized) this.parseProps(this);\n this.initialized = true;\n if (this.isModalChild) this.changeDetectorRef.detectChanges();\n }\n\n /**\n * @description Cleans up resources when the component is destroyed.\n * @summary Performs cleanup operations when the component is being removed from the DOM.\n * This includes clearing references to models and data to prevent memory leaks.\n *\n * @returns {void}\n * @memberOf ListComponent\n */\n override ngOnDestroy(): void {\n super.ngOnDestroy();\n if (this._repository) (this._repository as any).unObserve(this.observer);\n this.data = this.model = this._repository = this.paginator = undefined;\n }\n\n /**\n * @description Handles repository observation events with debouncing.\n * @summary Processes repository change notifications and routes them appropriately.\n * For CREATE events with a UID, handles them immediately. For other events,\n * passes them to the debounced observer subject to prevent excessive updates.\n *\n * @param {...unknown[]} args - The repository event arguments including table, event type, and UID\n * @returns {Promise<void>}\n * @memberOf ListComponent\n */\n async observeRepository(...args: unknown[]): Promise<void> {\n const [table, event, uid] = args;\n if (event === OperationKeys.CREATE && !!uid)\n return this.handleObserveEvent(\n table as string,\n event,\n uid as string | number\n );\n return this.observerSubjet.next(args);\n }\n\n /**\n * @description Handles specific repository events and updates the list accordingly.\n * @summary Processes repository change events (CREATE, UPDATE, DELETE) and performs\n * the appropriate list operations. This includes adding new items, updating existing\n * ones, or removing deleted items from the list display.\n *\n * @param {string} table - The table/model name that changed\n * @param {OperationKeys} event - The type of operation (CREATE, UPDATE, DELETE)\n * @param {string | number} uid - The unique identifier of the affected item\n * @returns {Promise<void>}\n * @memberOf ListComponent\n */\n async handleObserveEvent(\n table: string,\n event: OperationKeys,\n uid: string | number\n ): Promise<void> {\n if (event === OperationKeys.CREATE) {\n if (uid) {\n await this.handleCreate(uid);\n } else {\n await this.refresh(true);\n }\n } else {\n if (event === OperationKeys.UPDATE) await this.handleUpdate(uid);\n if (event === OperationKeys.DELETE) this.handleDelete(uid);\n this.refreshEventEmit();\n }\n }\n\n /**\n * @description Function for tracking items in the list.\n * @summary Provides a tracking function for the `*ngFor` directive in the component template.\n * This function is used to identify and control the rendering of items in the list,\n * preventing duplicate or unnecessary rendering.\n *\n * The `trackItemFn` function takes two parameters: `index` (the index of the item in the list)\n * and `item` (the actual item from the list). It returns the tracking key, which in this case\n * is the union of the `uid` of the item with the model name.\n *\n * @param {number} index - The index of the item in the list.\n\n * @param {KeyValue | string | number} item - The actual item from the list.\n * @returns {string | number} The tracking key for the item.\n * @memberOf ListComponent\n */\n override trackItemFn(\n index: number,\n item: KeyValue | string | number\n ): string | number {\n return `${(item as KeyValue)?.['uid'] || (item as KeyValue)?.[this.pk]}-${index}`;\n }\n\n /**\n * Handles the create event from the repository.\n *\n * @param {string | number} uid - The ID of the item to create.\n * @returns {Promise<void>} A promise that resolves when the item is created and added to the list.\n */\n async handleCreate(uid: string | number): Promise<void> {\n const result = await this._repository?.read(uid);\n const item = this.mapResults([result as KeyValue])[0];\n this.items = this.data = [item, ...(this.items || [])];\n }\n\n /**\n * @description Handles the update event from the repository.\n * @summary Updates the list item with the specified ID based on the new data.\n *\n * @param {string | number} uid - The ID of the item to update\n * @returns {Promise<void>}\n * @private\n * @memberOf ListComponent\n */\n async handleUpdate(uid: string | number): Promise<void> {\n const item: KeyValue = this.itemMapper(\n (await this._repository?.read(uid)) || {},\n this.mapper\n );\n this.data = [];\n for (const key in this.items as KeyValue[]) {\n const child = this.items[key] as KeyValue;\n if (child['uid'] === item['uid']) {\n this.items[key] = Object.assign({}, child, item);\n break;\n }\n }\n setTimeout(() => {\n this.data = [...this.items];\n }, 0);\n }\n\n /**\n * @description Removes an item from the list by ID.\n * @summary Filters out an item with the specified ID from the data array and\n * refreshes the list display. This is typically used after a delete operation.\n *\n * @param {string} uid - The ID of the item to delete\n * @param {string} pk - The primary key field name\n * @returns {Promise<void>}\n *\n * @memberOf ListComponent\n */\n handleDelete(uid: string | number, pk?: string): void {\n if (!pk) pk = this.pk;\n this.items =\n this.data?.filter((item: KeyValue) => item['uid'] !== uid) || [];\n }\n\n /**\n * @description Handles click events from list items.\n * @summary Listens for global ListItemClickEvent events and passes them to the\n * debounced click subject. This allows the component to respond to clicks on\n * list items regardless of where they originate from.\n *\n * @param {ListItemCustomEvent | IBaseCustomEvent} event - The click event\n * @returns {void}\n *\n * @memberOf ListComponent\n */\n @HostListener('window:ListItemClickEvent', ['$event'])\n handleClick(event: ListItemCustomEvent | IBaseCustomEvent): void {\n this.clickItemSubject.next(event);\n }\n\n /**\n * @description Handles search events from the search bar.\n * @summary Processes search queries from the search bar component, updating the\n * displayed data based on the search term. The behavior differs between infinite\n * and paginated modes to provide the best user experience for each mode.\n *\n * @param {string | undefined} value - The search term or undefined to clear search\n * @returns {Promise<void>}\n *\n * @mermaid\n * flowchart TD\n * A[Search Event] --> B{Type is Infinite?}\n * B -->|Yes| C[Disable loadMoreData]\n * B -->|No| D[Enable loadMoreData]\n * C --> E{Search value undefined?}\n * E -->|Yes| F[Enable loadMoreData]\n * E -->|No| G[Store search value]\n * D --> G\n * F --> H[Reset page to 1]\n * G --> I[Refresh data]\n * H --> I\n *\n * @memberOf ListComponent\n */\n @HostListener('window:searchbarEvent', ['$event'])\n async handleSearch(value: string | IFilterQuery | undefined): Promise<void> {\n this.searching = value !== undefined;\n\n if (this.type === ListComponentsTypes.INFINITE) {\n this.loadMoreData = false;\n if (value === undefined) {\n this.loadMoreData = true;\n this.page = 1;\n }\n this.searchValue = value;\n if (this.isModalChild) this.changeDetectorRef.detectChanges();\n await this.refresh(true);\n } else {\n this.loadMoreData = true;\n this.searchValue = value;\n if (value === undefined) this.page = this.lastPage;\n await this.refresh(true);\n }\n }\n\n /**\n * @description Handles filter events from the filter component.\n * @summary Processes filter queries from the filter component and applies them\n * to the list data. This method acts as a bridge between the filter component\n * and the search functionality, converting filter queries into search operations.\n *\n * @param {IFilterQuery | undefined} value - The filter query object or undefined to clear filters\n * @returns {Promise<void>}\n * @memberOf ListComponent\n */\n async handleFilter(value: IFilterQuery | undefined): Promise<void> {\n await this.handleSearch(value);\n }\n\n /**\n * @description Clears the current search and resets the list.\n * @summary Convenience method that clears the search by calling handleSearch\n * with undefined. This resets the list to show all data without filtering.\n *\n * @returns {Promise<void>}\n * @memberOf ListComponent\n */\n async clearSearch(): Promise<void> {\n await this.handleSearch(undefined);\n if (this.isModalChild) this.changeDetectorRef.detectChanges();\n }\n\n /**\n * @description Emits a refresh event with the current data.\n * @summary Creates and emits a refresh event containing the current list data.\n * This notifies parent components that the list data has been refreshed.\n *\n * @param {KeyValue[]} [data] - Optional data to include in the event\n * @returns {void}\n *\n * @memberOf ListComponent\n */\n refreshEventEmit(data?: KeyValue[]): void {\n if (!data) data = this.items;\n this.skeletonData = new Array(1);\n this.refreshEvent.emit({\n name: ComponentEventNames.REFRESH,\n data: data || [],\n component: this.componentName,\n });\n }\n\n /**\n * @description Emits a click event for a list item.\n * @summary Processes and emits a click event when a list item is clicked.\n * This extracts the relevant data from the event and passes it to parent components.\n *\n * @private\n * @param {ListItemCustomEvent | IBaseCustomEvent} event - The click event\n * @returns {void}\n *\n * @memberOf ListComponent\n */\n private clickEventEmit(event: ListItemCustomEvent | IBaseCustomEvent): void {\n this.clickEvent.emit(event);\n }\n\n /**\n * @description Refreshes the list data from the configured source.\n * @summary This method handles both initial data loading and subsequent refresh operations,\n * including pull-to-refresh and infinite scrolling. It manages the data fetching process,\n * updates the component's state, and handles pagination or infinite scrolling logic based\n * on the component's configuration.\n *\n * The method performs the following steps:\n * 1. Sets the refreshing flag to indicate a data fetch is in progress\n * 2. Calculates the appropriate start and limit values based on pagination settings\n * 3. Fetches data from the appropriate source (model or request)\n * 4. Updates the component's data and emits a refresh event\n * 5. Handles pagination or infinite scrolling state updates\n * 6. Completes any provided event (like InfiniteScrollCustomEvent)\n *\n * @param {InfiniteScrollCustomEvent | RefresherCustomEvent | boolean} event - The event that triggered the refresh,\n * or a boolean flag indicating if this is a forced refresh\n * @returns {Promise<void>} A promise that resolves when the refresh operation is complete\n *\n * @mermaid\n * sequenceDiagram\n * participant L as ListComponent\n * participant D as Data Source\n * participant E as Event System\n *\n * L->>L: refresh(event)\n * L->>L: Set refreshing flag\n * L->>L: Calculate start and limit\n * alt Using model\n * L->>D: getFromModel(force, start, limit)\n * D-->>L: Return data\n * else Using request\n * L->>D: getFromRequest(force, start, limit)\n * D-->>L: Return data\n * end\n * L->>E: refreshEventEmit()\n * alt Infinite scrolling mode\n * L->>L: Check if reached last page\n * alt Last page reached\n * L->>L: Complete scroll event\n * L->>L: Disable loadMoreData\n * else More pages available\n * L->>L: Increment page number\n * L->>L: Complete scroll event after delay\n * end\n * else Paginated mode\n * L->>L: Clear refreshing flag after delay\n * end\n *\n * @memberOf ListComponent\n */\n @HostListener('window:BackButtonNavigationEndEvent', ['$event'])\n override async refresh(\n event: InfiniteScrollCustomEvent | RefresherCustomEvent | boolean = false\n ): Promise<void> {\n // if (typeof force !== 'boolean' && force.type === ComponentEventNames.BACK_BUTTON_NAVIGATION) {\n // const {refresh} = (force as CustomEvent).detail;\n // if (!refresh)\n // return false;\n // }\n this.refreshing = true;\n const start: number =\n this.page > 1 ? (this.page - 1) * this.limit : this.start;\n const limit: number = this.page * (this.limit > 12 ? 12 : this.limit);\n\n this.data = !this.model\n ? await this.getFromRequest(!!event, start, limit)\n : ((await this.getFromModel(!!event)) as KeyValue[]);\n\n if (this.type === ListComponentsTypes.INFINITE) {\n if (this.page === this.pages) {\n if ((event as InfiniteScrollCustomEvent)?.target)\n (event as InfiniteScrollCustomEvent).target.complete();\n this.loadMoreData = false;\n } else {\n this.page += 1;\n this.refreshing = false;\n setTimeout(() => {\n if (\n (event as InfiniteScrollCustomEvent)?.target &&\n (event as CustomEvent)?.type !==\n ComponentEventNames.BACK_BUTTON_NAVIGATION\n )\n (event as InfiniteScrollCustomEvent).target.complete();\n }, 200);\n }\n } else {\n setTimeout(() => {\n this.refreshing = false;\n }, 200);\n }\n }\n\n /**\n * @description Handles pagination events from the pagination component.\n * @summary Processes pagination events by updating the current page number and\n * refreshing the list data to display the selected page. This method is called\n * when a user interacts with the pagination controls to navigate between pages.\n *\n * @param {IPaginationCustomEvent} event - The pagination event containing page information\n * @returns {void}\n *\n * @memberOf ListComponent\n */\n handlePaginate(event: IPaginationCustomEvent): void {\n const { page } = event.data;\n this.page = page;\n this.refresh(true);\n }\n\n /**\n * @description Handles pull-to-refresh events from the refresher component.\n * @summary Processes refresh events triggered by the user pulling down on the list\n * or by programmatic refresh requests. This method refreshes the list data and\n * completes the refresher animation when the data is loaded.\n *\n * @param {InfiniteScrollCustomEvent | CustomEvent} [event] - The refresh event\n * @returns {Promise<void>} A promise that resolves when the refresh operation is complete\n *\n * @memberOf ListComponent\n */\n async handleRefresh(\n event?: InfiniteScrollCustomEvent | CustomEvent\n ): Promise<void> {\n await this.refresh((event as InfiniteScrollCustomEvent) || true);\n if (event instanceof CustomEvent)\n setTimeout(() => {\n // Any calls to load data go here\n (event.target as HTMLIonRefresherElement).complete();\n }, 400);\n }\n\n /**\n * @description Filters data based on a search string.\n * @summary Processes the current data array to find items that match the provided\n * search string. This uses the arrayQueryByString utility to perform the filtering\n * across all properties of the items.\n *\n * @param {KeyValue[]} results - The array of items to search through\n * @param {string} search - The search string to filter by\n * @returns {KeyValue[]} A promise that resolves to the filtered array of items\n *\n * @memberOf ListComponent\n */\n parseSearchResults(results: KeyValue[], search: string): KeyValue[] {\n const filtered = results.filter((item: KeyValue) =>\n Object.values(item).some((v) => {\n if (\n v\n .toString()\n .toLowerCase()\n .includes((search as string)?.toLowerCase())\n )\n return v;\n })\n );\n return filtered;\n }\n\n /**\n * @description Fetches data from a request source.\n * @summary Retrieves data from the configured source function or URL, processes it,\n * and updates the component's data state. This method handles both initial data loading\n * and subsequent refresh operations when using an external data source rather than a model.\n *\n * @param {boolean} force - Whether to force a refresh even if data already exists\n * @param {number} start - The starting index for pagination\n * @param {number} limit - The maximum number of items to retrieve\n * @returns {Promise<KeyValue[]>} A promise that resolves to the fetched data\n *\n * @memberOf ListComponent\n */\n async getFromRequest(\n force: boolean = false,\n start: number,\n limit: number\n ): Promise<KeyValue[]> {\n let data: KeyValue[] = [...(this.data || [])];\n\n if (\n !this.data?.length ||\n force ||\n (this.searchValue as string)?.length ||\n !!(this.searchValue as IFilterQuery)\n ) {\n // (self.data as ListItem[]) = [];\n if (\n !(this.searchValue as string)?.length &&\n !(this.searchValue as IFilterQuery)\n ) {\n if (!this.source && !this.data?.length) {\n this.log.info('No data and source passed to infinite list');\n return [];\n }\n if (this.source instanceof Function) {\n data = (await this.source()) as KeyValue[];\n if (!Array.isArray(data))\n data = data?.['response']?.['data'] || data?.['results'] || [];\n }\n\n if (!data?.length && this.data?.length) data = this.data as KeyValue[];\n this.data = [...(await this.parseResult(data))];\n if (this.data?.length)\n this.items =\n this.type === ListComponentsTypes.INFINITE\n ? (this.items || []).concat([...this.data.slice(start, limit)])\n : [...(data.slice(start, limit) as KeyValue[])];\n } else {\n const data = await this.parseResult(\n this.parseSearchResults(this.data as [], this.searchValue as string)\n );\n this.items = [...data];\n if (this.isModalChild) this.changeDetectorRef.detectChanges();\n }\n } else {\n const data = [...(await this.parseResult(this.data as []))];\n this.items =\n this.type === ListComponentsTypes.INFINITE\n ? [...(this.items || []), ...(data || [])]\n : [...(data || [])];\n if (this.isModalChild) this.changeDetectorRef.detectChanges();\n }\n\n if (this.loadMoreData && this.type === ListComponentsTypes.PAGINATED)\n this.getMoreData(this.data?.length || 0);\n return this.data || ([] as KeyValue[]);\n }\n\n /**\n * @description Fetches data from a model source.\n * @summary Retrieves data from the configured model using its pagination or find methods,\n * processes it, and updates the component's data state. This method handles both initial\n * data loading and subsequent refresh operations when using a model as the data source.\n *\n * @param {boolean} force - Whether to force a refresh even if data already exists\n * @param {number} start - The starting index for pagination\n * @param {number} limit - The maximum number of items to retrieve\n * @returns {Promise<KeyValue[]>} A promise that resolves to the fetched data\n *\n * @memberOf ListComponent\n */\n async getFromModel(force: boolean = false): Promise<KeyValue[]> {\n let data = [...(this.data || [])];\n let request: KeyValue[] = [];\n\n // getting model repository\n if (!this._repository) {\n this._repository = this.repository;\n if (this.model instanceof Model && this._repository)\n (this._repository as any).observe(this.observer);\n }\n\n const repo = this._repository as DecafRepository<Model>;\n if (\n !this.data?.length ||\n force ||\n (this.searchValue as string)?.length ||\n !!(this.searchValue as IFilterQuery)\n ) {\n try {\n if (\n !(this.searchValue as string)?.length &&\n !(this.searchValue as IFilterQuery)\n ) {\n (this.data as KeyValue[]) = [];\n // const rawQuery = this.parseQuery(self.model as Repository<Model>, start, limit);\n // request = this.parseResult(await (this.model as any)?.paginate(start, limit));\n if (!this.paginator) {\n this.paginator = await repo\n .select()\n .orderBy([this.pk as keyof Model, this.sortDirection])\n .paginate(this.limit);\n }\n request = await this.parseResult(this.paginator as Paginator<any>);\n } else {\n if (!this.indexes)\n this.indexes = Object.values(this.mapper) || [this.pk];\n\n const condition = this.parseConditions(\n this.searchValue as string | number | IFilterQuery\n );\n this.changeDetectorRef.detectChanges();\n request = await this.parseResult(\n await repo.query(\n condition,\n (this.sortBy || this.pk) as keyof Model,\n this.sortDirection\n )\n );\n data = [];\n this.changeDetectorRef.detectChanges();\n }\n data =\n this.type === ListComponentsTypes.INFINITE\n ? [...data.concat(request)]\n : [...request];\n } catch (error: unknown) {\n this.log.error(\n (error as Error)?.message ||\n `Unable to find ${this.model} on registry. Return empty array from component`\n );\n }\n }\n\n if (data?.length) {\n if (this.searchValue) {\n this.items = [...data];\n if (this.items?.length <= this.limit) this.loadMoreData = false;\n } else {\n this.items = [...data];\n }\n }\n if (this.type === ListComponentsTypes.PAGINATED && this.paginator)\n this.getMoreData(this.paginator.total);\n return data || ([] as KeyValue[]);\n }\n\n /**\n * @description Converts search values or filter queries into database conditions.\n * @summary Transforms search input or complex filter queries into Condition objects\n * that can be used for database querying. Handles both simple string/number searches\n * across indexed fields and complex filter queries with multiple criteria.\n *\n * For simple searches (string/number):\n * - Creates conditions that search across all indexed fields\n * - Uses equality for numeric values and regex for string values\n * - Combines conditions with OR logic to search multiple fields\n *\n * For complex filter queries:\n * - Processes each filter item with its specific condition type\n * - Supports Equal, Not Equal, Contains, Not Contains, Greater Than, Less Than\n * - Updates sort configuration based on the filter query\n * - Combines multiple filter conditions with OR logic\n *\n * @param {string | number | IFilterQuery} value - The search value or filter query object\n * @returns {Condition<Model>} A Condition object for database querying\n * @memberOf ListComponent\n */\n parseConditions(value: string | number | IFilterQuery): Condition<Model> {\n let _condition: Condition<Model>;\n if (\n typeof value === Primitives.STRING ||\n typeof value === Primitives.NUMBER\n ) {\n _condition = Condition.attribute<Model>(this.pk as keyof Model).eq(\n !isNaN(value as number) ? Number(value) : value\n );\n for (const index of this.indexes) {\n if (index === this.pk) continue;\n let orCondition;\n if (!isNaN(value as number)) {\n orCondition = Condition.attribute<Model>(index as keyof Model).eq(\n Number(value)\n );\n } else {\n orCondition = Condition.attribute<Model>(index as keyof Model).regexp(\n value as string\n );\n }\n _condition = _condition.or(orCondition);\n }\n } else {\n const { query, sort } = value as IFilterQuery;\n _condition = Condition.attribute<Model>(this.pk as keyof Model).dif(\n 'null'\n );\n\n if (query?.length) _condition = undefined as unknown as Condition<Model>;\n\n (query || []).forEach((item: IFilterQueryItem) => {\n const { value, condition, index } = item;\n let val = value as string | number;\n if (index === this.pk || !isNaN(val as number)) val = Number(val);\n let orCondition;\n switch (condition) {\n case 'Equal':\n orCondition = Condition.attribute<Model>(index as keyof Model).eq(\n val\n );\n break;\n case 'Not Equal':\n orCondition = Condition.attribute<Model>(index as keyof Model).dif(\n val\n );\n break;\n case 'Not Contains':\n orCondition = !Condition.attribute<Model>(\n index as keyof Model\n ).regexp(new RegExp(`^(?!.*${val}).*$`));\n break;\n case 'Contains':\n orCondition = Condition.attribute<Model>(\n index as keyof Model\n ).regexp(val as string);\n break;\n case 'Greater Than':\n orCondition = Condition.attribute<Model>(index as keyof Model).gte(\n val\n );\n break;\n case 'Less Than':\n orCondition = Condition.attribute<Model>(index as keyof Model).lte(\n val\n );\n break;\n }\n _condition = (\n !_condition\n ? orCondition\n : _condition.and(orCondition as unknown as Condition<Model>)\n ) as Condition<Model>;\n });\n\n this.sortBy = (sort?.value as keyof Model) || this.pk;\n this.sortDirection = sort?.direction || this.sortDirection;\n }\n return _condition as Condition<Model>;\n }\n\n /**\n * @description Processes query results into a standardized format.\n * @summary Handles different result formats from various data sources, extracting\n * pagination information when available and applying any configured data mapping.\n * This ensures consistent data structure regardless of the source.\n *\n * @protected\n * @param {KeyValue[] | Paginator} result - The raw query result\n * @returns {KeyValue[]} The processed array of items\n *\n * @memberOf ListComponent\n */\n protected async parseResult(\n result: KeyValue[] | Paginator<any>\n ): Promise<KeyValue[]> {\n if (!Array.isArray(result) && 'page' in result && 'total' in result) {\n const paginator = result as Paginator<Model>;\n try {\n result = await paginator.page(this.page);\n this.getMoreData(paginator.total);\n } catch (error: unknown) {\n this.log.info(\n (error as Error)?.message ||\n 'Unable to get page from paginator. Return empty array from component'\n );\n result = [];\n }\n } else {\n this.getMoreData((result as KeyValue[])?.length || 0);\n }\n return Object.keys(this.mapper || {}).length\n ? this.mapResults(result)\n : result;\n }\n\n /**\n * @description Updates pagination state based on data length.\n * @summary Calculates whether more data is available and how many pages exist\n * based on the total number of items and the configured limit per page.\n * This information is used to control pagination UI and infinite scrolling behavior.\n *\n * @param {number} length - The total number of items available\n * @returns {void}\n *\n * @memberOf ListComponent\n */\n getMoreData(length: number): void {\n if (this.type === ListComponentsTypes.INFINITE) {\n if (this.paginator) length = length * this.limit;\n if (length <= this.limit) {\n this.loadMoreData = false;\n } else {\n this.pages = Math.floor(length / this.limit);\n if (this.pages * this.limit < length) this.pages += 1;\n if (this.pages === 1) this.loadMoreData = false;\n }\n } else {\n this.pages = length;\n if (this.pages === 1) this.loadMoreData = false;\n }\n }\n\n /**\n * @description Maps a single item using the configured mapper.\n * @summary Transforms a data item according to the mapping configuration,\n * extracting nested properties and formatting values as needed. This allows\n * the component to display data in a format different from how it's stored.\n *\n * @protected\n * @param {KeyValue} item - The item to map\n * @param {KeyValue} mapper - The mapping configuration\n * @param {KeyValue} [props] - Additional properties to include\n * @returns {KeyValue} The mapped item\n *\n * @memberOf ListComponent\n */\n protected itemMapper(\n item: KeyValue,\n mapper: KeyValue,\n props?: KeyValue\n ): KeyValue {\n return Object.entries(mapper).reduce((accum: KeyValue, [key, value]) => {\n const arrayValue = value.split('.');\n if (!value) {\n accum[key] = value;\n } else {\n if (arrayValue.length === 1) {\n value = item?.[value] ? item[value] : '';\n // value = item?.[value] ? item[value] : value !== key ? value : \"\";\n if (isValidDate(value)) value = `${formatDate(value)}`;\n accum[key] = value;\n } else {\n let val;\n\n for (const _value of arrayValue)\n val = !val\n ? item[_value]\n : (typeof val === 'string' ? JSON.parse(val) : val)[_value];\n\n if (isValidDate(new Date(val))) val = `${formatDate(val)}`;\n\n accum[key] = val === null || val === undefined ? value : val;\n }\n }\n return Object.assign({}, props || {}, accum);\n }, {});\n }\n\n /**\n * @description Maps all result items using the configured mapper.\n * @summary Applies the itemMapper to each item in the result set, adding\n * common properties like operations and route information. This transforms\n * the raw data into the format expected by the list item components.\n *\n * @param {KeyValue[]} data - The array of items to map\n * @returns {KeyValue[]} The array of mapped items\n *\n * @memberOf ListComponent\n */\n mapResults(data: KeyValue[]): KeyValue[] {\n if (!data || !data.length) return [];\n // passing uid as prop to mapper\n this.mapper = { ...this.mapper, ...{ uid: this.pk } };\n const props = Object.assign({\n operations: this.operations,\n route: this.route,\n ...Object.keys(this.item).reduce((acc: KeyValue, key: string) => {\n acc[key] = this.item[key];\n return acc;\n }, {}),\n // ... (!this.item.render ? {} : Object.keys(this.item).reduce((acc: KeyValue, key: string) => {\n // acc[key] = this.item[key as keyof IListItemProp];\n // return acc;\n // }, {}))\n });\n return data.reduce((accum: KeyValue[], curr) => {\n accum.push({\n ...this.itemMapper(curr, this.mapper as KeyValue, props),\n ...{ pk: this.pk },\n });\n return accum;\n }, []);\n }\n\n parseSearchValue() {\n if (typeof this.searchValue === Primitives.STRING)\n return this.searchValue || '';\n const searchValue = this.searchValue as IFilterQuery;\n return (searchValue?.query as IFilterQueryItem[])\n .map((item) => `${item.index} ${item.condition} ${item.value}`)\n .join(', ');\n }\n}\n","\n@if (showRefresher) {\n <ion-refresher slot=\"fixed\" [pullFactor]=\"1\" [pullMin]=\"100\" [pullMax]=\"200\" (ionRefresh)=\"handleRefresh($event)\">\n <ion-refresher-content />\n </ion-refresher>\n}\n\n\n@if (showSearchbar) {\n <div [hidden]=\"!data?.length\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-grid-actions\">\n <div class=\"dcf-width-expand@m dcf-width-1-1\">\n @if (model && enableFilter) {\n @if (data?.length || searching) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n } @else {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n }\n </div>\n @if(createButton) {\n <div class=\"dcf-width-auto@m dcf-button-container dcf-width-1-1 dcf-flex-middle dcf-flex dcf-flex-center dcf-flex-right@m\">\n <div>\n <ion-button expand=\"block\" (click)=\"changeOperation(OperationKeys.CREATE)\">Create</ion-button>\n </div>\n </div>\n }\n </div>\n </div>\n}\n\n@if (initialized && data?.length) {\n <ion-list [id]=\"uid\" [inset]=\"inset\" [lines]=\"lines\">\n @if (item?.tag) {\n @for(child of items; track trackItemFn($index, child)) {\n <ngx-decaf-component-renderer\n [tag]=\"item.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]='{\n item: child,\n mapper: mapper,\n route: route\n }'>\n </ngx-decaf-component-renderer>\n }\n } @else {\n <ng-content></ng-content>\n }\n </ion-list>\n\n @if (loadMoreData) {\n @if (pages > 0 && type === 'paginated' && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n\n } @else {\n <ion-infinite-scroll\n [class]=\"searchValue?.length ? 'dcf-hidden' : ''\"\n\n [position]=\"scrollPosition\"\n [threshold]=\"scrollThreshold\"\n (ionInfinite)=\"handleRefresh($event)\">\n <ion-infinite-scroll-content [loadingSpinner]=\"loadingSpinner\" [loadingText]=\"loadingText\" />\n </ion-infinite-scroll>\n }\n }\n} @else {\n @if (refreshing) {\n @for(skl of skeletonData; track $index) {\n <ion-item>\n <ion-thumbnail slot=\"start\">\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n </ion-thumbnail>\n <ion-label>\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%;\"><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text></ion-text>\n </ion-label>\n </ion-item>\n }\n\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [model]=\"model\"\n [route]=\"route\"\n [borders]=\"borders\"\n [icon]=\"empty.icon\"\n className=\"dcf-empty-data\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\" />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"model\"\n [route]=\"route\"\n [borders]=\"borders\"\n className=\"empty-search\"\n [translatable]=\"true\"\n className=\"dcf-empty-data\"\n [title]=\"locale + '.search.title' | translate\"\n [subtitle]=\"locale + '.search.subtitle' | translate: {'0': parseSearchValue()}\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n}\n\n","/**\n * @module module:lib/components/list-item/list-item.component\n * @description List item component module.\n * @summary Exposes `ListItemComponent` which renders a single list item with\n * configurable icon, title, description, actions and navigation. The component\n * supports slide actions, popover menus and emits click events for parent\n * components to handle.\n *\n * @link {@link ListItemComponent}\n */\n\nimport { AfterViewInit, Component, ElementRef, EventEmitter, HostListener,Input, OnInit, Output, ViewChild } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport {\n IonButton,\n IonItem,\n IonLabel,\n IonList,\n IonContent,\n IonIcon,\n IonListHeader,\n IonPopover,\n IonItemSliding,\n IonItemOptions,\n IonItemOption\n} from '@ionic/angular/standalone';\nimport * as AllIcons from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { StringOrBoolean } from '../../engine/types';\nimport { getWindowWidth, windowEventEmitter, removeFocusTrap, stringToBoolean } from '../../utils/helpers';\nimport { ComponentEventNames } from '../../engine/constants';\nimport {ListItemCustomEvent} from '../../engine/interfaces';\nimport { Dynamic } from '../../engine/decorators';\nimport { NgxComponentDirective } from '../../engine/NgxComponentDirective';\n\n\n\n/**\n * @description A component for displaying a list item with various customization options.\n * @summary The ListItemComponent is an Angular component that extends NgxBaseComponentDirective. It provides a flexible and customizable list item interface with support for icons, buttons, and various text elements. The component also handles actions and navigation based on user interactions.\n *\n * @class\n * @extends NgxBaseComponentDirective\n *\n * @param {string} [lines='none'] - Determines the line style of the item. Can be 'inset', 'inseet', or 'none'.\n * @param {Record<string, any>} item - The data item to be displayed in the list item.\n * @param {string} icon - The name of the icon to be displayed.\n * @param {'start' | 'end'} [iconSlot='start'] - The position of the icon within the item.\n * @param {StringOrBoolean} [button=true] - Determines if the item should behave as a button.\n * @param {string} [title] - The main title of the list item.\n * @param {string} [description] - A description for the list item.\n * @param {string} [info] - Additional information for the list item.\n * @param {string} [subinfo] - Sub-information for the list item.\n *\n * @example\n * <ngx-decaf-list-item\n * [item]=\"dataItem\"\n * icon=\"star\"\n * title=\"Item Title\"\n * description=\"Item Description\"\n * (clickEvent)=\"handleItemClick($event)\">\n * </ngx-decaf-list-item>\n *\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant V as View\n * participant U as User\n * C->>V: Initialize component\n * V->>U: Display list item\n * U->>V: Click on item or action\n * V->>C: Trigger handleAction()\n * C->>C: Process action\n * C->>V: Update view or navigate\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-list-item',\n templateUrl: './list-item.component.html',\n styleUrls: ['./list-item.component.scss'],\n standalone: true,\n imports: [\n TranslatePipe,\n IonList,\n IonListHeader,\n IonItem,\n IonItemSliding,\n IonItemOptions,\n IonItemOption,\n IonIcon,\n IonLabel,\n IonButton,\n IonContent,\n IonPopover\n ],\n host: {'[attr.id]': 'uid'},\n})\nexport class ListItemComponent extends NgxComponentDirective implements OnInit, AfterViewInit {\n\n @ViewChild('component', { read: ElementRef, static: false })\n override component!: ElementRef;\n\n /**\n * @description Reference to the action menu popover component.\n * @summary ViewChild reference that provides access to the HTMLIonPopoverElement\n * used for displaying action menus. This reference is used to programmatically\n * control the popover, such as dismissing it when necessary.\n *\n * @type {HTMLIonPopoverElement}\n * @memberOf ListItemComponent\n */\n @ViewChild('actionMenuComponent')\n actionMenuComponent!: HTMLIonPopoverElement;\n\n /**\n * @description Controls the display of lines around the list item.\n * @summary Determines how lines are displayed around the list item borders.\n * 'inset' shows lines with padding, 'full' shows full-width lines, and 'none'\n * removes all lines. This affects the visual separation between list items.\n *\n * @type {'inset' | 'full' | 'none'}\n * @default 'inset'\n * @memberOf ListItemComponent\n */\n @Input()\n lines: 'inset' | 'full' | 'none' = 'full';\n\n /**\n * @description The data object associated with this list item.\n * @summary Contains the raw data that this list item represents. This object\n * is used to extract display information and for passing to event handlers\n * when the item is interacted with. It overrides the base item property.\n *\n * @type {Record<string, unknown>}\n * @memberOf ListItemComponent\n */\n @Input()\n override item!: Record<string, unknown>;\n\n /**\n * @description The name of the icon to display in the list item.\n * @summary Specifies which icon to display using Ionic's icon system.\n * The icon name should correspond to an available Ionic icon or a custom\n * icon that has been registered with the icon registry.\n *\n * @type {string}\n * @memberOf ListItemComponent\n */\n @Input()\n icon!: string;\n\n /**\n * @description Position of the icon within the list item.\n * @summary Determines whether the icon appears at the start (left in LTR languages)\n * or end (right in LTR languages) of the list item. This affects the overall\n * layout and visual hierarchy of the item content.\n *\n * @type {'start' | 'end'}\n * @default 'start'\n * @memberOf ListItemComponent\n */\n @Input()\n iconSlot: 'start' | 'end' ='start';\n\n /**\n * @description Controls whether the list item behaves as a clickable button.\n * @summary When set to true, the list item will have button-like behavior including\n * hover effects, click handling, and appropriate accessibility attributes.\n * When false, the item is displayed as static content without interactive behavior.\n *\n * @type {StringOrBoolean}\n * @default true\n * @memberOf ListItemComponent\n */\n @Input()\n button: StringOrBoolean = true;\n\n /**\n * @description The main title text displayed in the list item.\n * @summary Sets the primary text content that appears prominently in the list item.\n * This is typically the most important information about the item and is displayed\n * with emphasis in the component's visual hierarchy.\n *\n * @type {string}\n * @memberOf ListItemComponent\n */\n @Input()\n title?: string;\n\n /**\n * @description Secondary descriptive text for the list item.\n * @summary Provides additional context or details about the item. This text\n * is typically displayed below the title with less visual emphasis.\n * Useful for providing context without cluttering the main title.\n *\n * @type {string}\n * @memberOf ListItemComponent\n */\n @Input()\n description?: string;\n\n /**\n * @description Additional information text for the list item.\n * @summary Displays supplementary information that provides extra context\n * about the item. This could include metadata, status information, or\n * other relevant details that don't fit in the title or description.\n *\n * @type {string}\n * @memberOf ListItemComponent\n */\n @Input()\n info?: string;\n\n /**\n * @description Sub-information text displayed in the list item.\n * @summary Provides tertiary level information that complements the info field.\n * This is typically used for additional metadata or contextual details\n * that are useful but not critical for understanding the item.\n *\n * @type {string}\n * @memberOf ListItemComponent\n */\n @Input()\n subinfo?: string;\n\n /**\n * @description Event emitter for list item click interactions.\n * @summary Emits custom events when the list item is clicked or when actions\n * are performed on it. The emitted event contains information about the action,\n * the item data, and other relevant context for parent components to handle.\n *\n * @type {EventEmitter<ListItemCustomEvent>}\n * @memberOf ListItemComponent\n */\n @Output()\n clickEvent: EventEmitter<ListItemCustomEvent> = new EventEmitter<ListItemCustomEvent>();\n\n /**\n * @description Flag indicating whether slide items are currently enabled.\n * @summary Controls the visibility of slide actions based on screen size and\n * available operations. When true, users can swipe on the item to reveal\n * action buttons for operations like edit and delete.\n *\n * @type {boolean}\n * @default false\n * @memberOf ListItemComponent\n */\n showSlideItems: boolean = false;\n\n /**\n * @description Current window width in pixels.\n * @summary Stores the current browser window width which is used to determine\n * responsive behavior, such as when to show or hide slide items based on\n * screen size. Updated automatically on window resize events.\n *\n * @type {number}\n * @memberOf ListItemComponent\n */\n windowWidth!: number;\n\n /**\n * @description Flag indicating whether the action menu popover is currently open.\n * @summary Tracks the state of the action menu to prevent multiple instances\n * from being opened simultaneously and to ensure proper cleanup when actions\n * are performed. Used for managing the popover lifecycle.\n *\n * @type {boolean}\n * @default false\n * @memberOf ListItemComponent\n */\n actionMenuOpen: boolean = false;\n\n\n\n /**\n * @description Creates an instance of ListItemComponent.\n * @summary Initializes a new ListItemComponent by calling the parent class constructor\n * with the component name for logging and identification purposes. Also registers\n * all available Ionic icons to ensure they can be displayed in the component.\n *\n * @memberOf ListItemComponent\n */\n constructor() {\n super(\"ListItemComponent\");\n addIcons(AllIcons);\n this.enableDarkMode = true;\n }\n\n /**\n * @description Initializes the component after Angular first displays the data-bound properties.\n * @summary Sets up the component by determining slide item visibility, processing boolean inputs,\n * building CSS class names based on properties, and capturing the current window width.\n * This method prepares the component for user interaction by ensuring all properties are\n * properly initialized and responsive behavior is configured.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant L as ListItemComponent\n * participant W as Window\n *\n * A->>L: ngOnInit()\n * L->>L: enableSlideItems()\n * L->>L: Process button boolean\n * L->>L: Build className with flex classes\n * alt operations exist\n * L->>L: Add 'action' class\n * end\n * L->>W: getWindowWidth()\n * W-->>L: Return current width\n * L->>L: Store windowWidth\n *\n * @return {Promise<void>}\n * @memberOf ListItemComponent\n */\n async ngOnInit(): Promise<void> {\n this.showSlideItems = this.enableSlideItems();\n this.button = stringToBoolean(this.button);\n this.className = `${this.className} dcf-flex dcf-flex-middle grid-item`;\n if (this.operations?.length)\n this.className += ` action`;\n this.windowWidth = getWindowWidth() as number;\n }\n\n async ngAfterViewInit(): Promise<void> {\n this.checkDarkMode();\n }\n\n /**\n * @description Handles user interactions and actions performed on the list item.\n * @summary This method is the central action handler for list item interactions. It manages\n * event propagation, dismisses open action menus, removes focus traps, and either emits\n * events for parent components to handle or performs navigation based on the component's\n * route configuration. This method supports both event-driven and navigation-driven architectures.\n *\n * @param {CrudOperations} action - The type of CRUD operation being performed\n * @param {Event} event - The browser event that triggered the action\n * @param {HTMLElement} [target] - Optional target element for the event\n * @return {Promise<boolean|void>} A promise that resolves to navigation success or void for events\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant L as ListItemComponent\n * participant P as Parent Component\n * participant N as Router\n * participant E as Event System\n *\n * U->>L: Perform action (click/swipe)\n * L->>L: stopImmediatePropagation()\n * alt actionMenuOpen\n * L->>L: Dismiss action menu\n * end\n * L->>L: removeFocusTrap()\n * alt No route configured\n * L->>E: windowEventEmitter()\n * L->>P: clickEvent.emit()\n * else Route configured\n * L->>N: redirect(action, uid)\n * N-->>L: Return navigation result\n * end\n *\n * @memberOf ListItemComponent\n */\n async handleAction(action: CrudOperations, event: Event, target?: HTMLElement): Promise<boolean|void> {\n event.stopImmediatePropagation();\n if (this.actionMenuOpen)\n await this.actionMenuComponent.dismiss();\n // forcing trap focus\n removeFocusTrap();\n if (!this.route) {\n const event = {target: target, action, pk: this.pk, data: this.uid, name: ComponentEventNames.CLICK, component: this.componentName } as ListItemCustomEvent;\n windowEventEmitter(`ListItem${ComponentEventNames.CLICK}`, event);\n return this.clickEvent.emit(event);\n }\n return await this.redirect(action, (typeof this.uid === 'number' ? `${this.uid}`: this.uid));\n }\n\n /**\n * @description Responsive handler that enables or disables slide items based on screen size and operations.\n * @summary This method is automatically called when the window is resized and also during component\n * initialization. It determines whether slide actions should be available based on the current\n * window width and the presence of UPDATE or DELETE operations. Slide items are typically hidden\n * on larger screens where there's space for dedicated action buttons.\n *\n * @return {boolean} True if slide items should be shown, false otherwise\n *\n * @mermaid\n * sequenceDiagram\n * participant W as Window\n * participant L as ListItemComponent\n * participant U as UI\n *\n * W->>L: resize event\n * L->>W: getWindowWidth()\n * W-->>L: Return current width\n * L->>L: Store windowWidth\n * alt No operations OR width > 639px\n * L->>U: showSlideItems = false\n * else Operations include UPDATE/DELETE\n * L->>U: showSlideItems = true\n * end\n * L-->>U: Return showSlideItems value\n *\n * @memberOf ListItemComponent\n */\n @HostListener('window:resize', ['$event'])\n enableSlideItems(): boolean {\n this.windowWidth = getWindowWidth() as number;\n if (!this.operations?.length || this.windowWidth > 639)\n return this.showSlideItems = false;\n this.showSlideItems = this.operations.includes(OperationKeys.UPDATE) || this.operations.includes(OperationKeys.DELETE);\n return this.showSlideItems;\n }\n\n /**\n * @description Animates and removes an element from the DOM.\n * @summary This method applies CSS animation classes to create a smooth fade-out effect\n * before removing the element from the DOM. The animation enhances user experience by\n * providing visual feedback when items are deleted or removed from lists. The timing\n * is coordinated with the CSS animation duration to ensure the element is removed\n * after the animation completes.\n *\n * @param {HTMLElement} element - The DOM element to animate and remove\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant L as ListItemComponent\n * participant E as HTMLElement\n * participant D as DOM\n *\n * L->>E: Add animation classes\n * Note over E: uk-animation-fade, uk-animation-medium, uk-animation-reverse\n * E->>E: Start fade animation\n * L->>L: setTimeout(600ms)\n * Note over L: Wait for animation to complete\n * L->>D: element.remove()\n * D->>D: Remove element from DOM\n *\n * @memberOf ListItemComponent\n */\n removeElement(element: HTMLElement): void {\n element.classList.add('uk-animation-fade', 'uk-animation-medium', 'uk-animation-reverse');\n setTimeout(() => {element.remove()}, 600)\n }\n\n /**\n * @description Navigates to a new route based on the specified action and item ID.\n * @summary This method constructs a navigation URL using the component's route configuration,\n * the specified action, and an item identifier. It uses Ionic's Router to perform\n * forward navigation with appropriate animations. This method is typically used for\n * CRUD operations where each action (create, read, update, delete) has its own route.\n *\n * @param {string} action - The action to be performed (e.g., 'edit', 'view', 'delete')\n * @param {string} [id] - The unique identifier of the item to be acted upon\n * @return {Promise<boolean>} A promise that resolves to true if navigation was successful\n *\n * @mermaid\n * sequenceDiagram\n * participant L as ListItemComponent\n * participant N as Router\n * participant R as Router\n *\n * L->>L: redirect(action, id)\n * L->>L: Construct URL: /{route}/{action}/{id}\n * L->>N: navigateForward(url)\n * N->>R: Navigate to constructed URL\n * R-->>N: Return navigation result\n * N-->>L: Return boolean success\n *\n * @memberOf ListItemComponent\n */\n async redirect(action: string, id?: string): Promise<boolean> {\n return await this.router.navigateByUrl(`/${this.route}/${action}/${id || this.uid}`);\n }\n\n /**\n * @description Presents the actions menu popover for the list item.\n * @summary This method handles the display of a contextual action menu when triggered by user\n * interaction (typically a long press or right-click). It stops event propagation to prevent\n * unwanted side effects, removes any existing focus traps for accessibility, configures the\n * popover with the triggering event, and opens the action menu. The menu typically contains\n * available CRUD operations for the item.\n *\n * @param {Event} event - The event that triggered the action menu request\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant L as ListItemComponent\n * participant P as Popover\n * participant A as Accessibility\n *\n * U->>L: Trigger action menu (long press/right-click)\n * L->>L: stopImmediatePropagation()\n * L->>A: removeFocusTrap()\n * L->>P: Set event reference\n * L->>L: actionMenuOpen = true\n * L->>P: Display popover with actions\n *\n * @memberOf ListItemComponent\n */\n presentActionsMenu(event: Event): void {\n event.stopImmediatePropagation();\n // forcing trap focus\n removeFocusTrap();\n this.actionMenuComponent.event = event;\n this.actionMenuOpen = true;\n }\n}\n","\n@if (title || description) {\n <ion-item-sliding>\n <ion-item\n [id]=\"uid\"\n [lines]=\"lines\"\n [button]=\"button\"\n [class]=\"className\"\n (click)=\"operations?.includes('read') ? handleAction('read', $event, component) : ''\"\n #component\n >\n @if (icon && lines !== 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\" />\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-flex dcf-flex-middle dcf-grid-collapse\" dcf-grid>\n @if (icon && lines === 'inset') {\n <div class=\"dcf-icon dcf-grid-icon\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\" />\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n @if (title) {\n <ion-label class=\"dcf-item-title\">\n {{ uid !== title ? (uid + ' - ' + title) : title }}\n </ion-label>\n }\n @if (description) {\n <div class=\"dcf-description\" [innerHTML]=\"description\"></div>\n }\n </div>\n @if (info || subinfo) {\n <div class=\"dcf-width-auto@s dcf-width-expand dcf-info dcf-flex dcf-flex-right@s\">\n <div>\n @if (info) {\n <span [innerHTML]=\"info\"></span>\n }\n @if (subinfo) {\n <div class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\" ></div>\n }\n </div>\n </div>\n }\n\n <div class=\"dcf-width-auto dcf-flex dcf-flex-middle dcf-flex-right\">\n @if ((operations.includes('delete') || operations.includes('update')) && uid) {\n\n <div class=\"dcf-visible@s\" id=\"dcf-actions\">\n <ion-button class=\"\" shape=\"round\" fill=\"clear\" color=\"primary\" (click)=\"presentActionsMenu($event)\">\n <ion-icon slot=\"icon-only\" aria-hidden=\"true\" name=\"ellipsis-vertical-outline\" />\n </ion-button>\n <ion-popover\n #actionMenuComponent\n side=\"bottom\"\n alignment=\"left\"\n\n [isOpen]=\"actionMenuOpen\"\n (didDismiss)=\"actionMenuOpen = false\">\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-list lines=\"none\">\n <ion-list-header>\n <h4 class=\"dcf-text-capitalize\" [innerHTML]=\"'actions' | translate\"></h4>\n </ion-list-header>\n @for (operation of ['update', 'delete']; track operation) {\n @if (operations.includes(operation)) {\n <ion-item [button]=\"true\" (click)=\"handleAction(operation, $event, component)\">\n <ion-avatar class=\"dcf-flex dcf-flex-middle\" aria-hidden=\"true\" slot=\"start\">\n @if (operation === 'update') {\n <ion-icon color=\"primary\" aria-hidden=\"true\" name=\"create-outline\" />\n } @else {\n <ion-icon color=\"danger\" aria-hidden=\"true\" name=\"trash\" />\n }\n </ion-avatar>\n <ion-label class=\"dcf-text-capitalize\">{{ operation | translate }}</ion-label>\n </ion-item>\n }\n }\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n </div>\n }\n @if (windowWidth > 639) {\n <div id=\"end\">\n <ng-content select=\"[slot='end']\"></ng-content>\n </div>\n }\n </div>\n </div>\n </div>\n </ion-item>\n @if (showSlideItems && uid) {\n <ion-item-options side=\"end\" (ionSwipe)=\"operations.length === 1 ? handleAction(operations[0], $event, component) : ''\">\n @if (operations?.includes('update')) {\n <ion-item-option class=\"dcf-update\" (click)=\"handleAction('update', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\" />\n </ion-item-option>\n }\n @if (operations?.includes('delete')) {\n <ion-item-option class=\"dcf-delete\" (click)=\"handleAction('delete', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\" />\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n","/**\n * @module module:lib/components/stepped-form/stepped-form.component\n * @description Stepped form component module.\n * @summary Provides `SteppedFormComponent` which implements a multi-page form\n * UI with navigation, validation and submission support. Useful for forms that\n * need to be split into logical steps/pages.\n *\n * @link {@link SteppedFormComponent}\n */\n\nimport { Component, Input, OnInit, OnDestroy } from '@angular/core';\nimport { FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { IonButton, IonSkeletonText, IonText } from '@ionic/angular/standalone';\nimport { arrowForwardOutline, arrowBackOutline } from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { UIElementMetadata, UIModelMetadata} from '@decaf-ts/ui-decorators';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport { ComponentEventNames } from '../../engine/constants';\nimport { Dynamic } from '../../engine/decorators';\nimport { NgxFormService } from '../../services/NgxFormService';\nimport { getLocaleContext } from '../../i18n/Loader';\nimport { LayoutComponent } from '../layout/layout.component';\nimport { NgxFormDirective } from '../../engine/NgxFormDirective';\nimport { FormParent } from '../../engine/types';\n\n\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-stepped-form',\n templateUrl: './stepped-form.component.html',\n styleUrls: ['./stepped-form.component.scss'],\n imports: [\n TranslatePipe,\n ReactiveFormsModule,\n IonSkeletonText,\n IonText,\n IonButton,\n LayoutComponent\n ],\n standalone: true,\n host: {'[attr.id]': 'uid'},\n})\nexport class SteppedFormComponent extends NgxFormDirective implements OnInit, OnDestroy {\n\n /**\n * @description Array of UI model metadata for all form fields.\n * @summary Contains the complete collection of UI model metadata that defines\n * the structure, validation, and presentation of form fields across all pages.\n * Each metadata object contains information about field type, validation rules,\n * page assignment, and display properties.\n *\n * @type {UIModelMetadata[]}\n * @memberOf SteppedFormComponent\n */\n @Input()\n override children!: UIModelMetadata[] | { title: string; description: string; items?: UIModelMetadata[] }[];\n\n\n /**\n * @description The locale to be used for translations.\n * @summary Specifies the locale identifier to use when translating component text.\n * This can be set explicitly via input property to override the automatically derived\n * locale from the component name. The locale is typically a language code (e.g., 'en', 'fr')\n * or a language-region code (e.g., 'en-US', 'fr-CA') that determines which translation\n * set to use for the component's text content.\n *\n * @type {string}\n * @memberOf SteppedFormComponent\n */\n @Input()\n paginated: boolean = true;\n\n\n // /**\n // * @description Optional action identifier for form submission context.\n // * @summary Specifies a custom action name that will be included in the submit event.\n // * If not provided, defaults to the standard submit event constant. Used to\n // * distinguish between different types of form submissions within the same component.\n // *\n // * @type {string | undefined}\n // */\n // @Input()\n // action?: string;\n\n\n\n /**\n * @description Number of pages in the stepped form.\n * @summary Represents the total number of steps/pages in the multi-step form.\n * This value is automatically calculated based on the page properties of the children\n * or can be explicitly set. Each page represents a logical group of form fields.\n *\n * @type {number}\n * @default 1\n * @memberOf SteppedFormComponent\n */\n @Input()\n override pages: number | {title: string; description: string}[] = 1;\n\n /**\n * List of titles and descriptions for each page of the stepped form.\n * Each object in the array represents a page, containing a title and a description.\n *\n * @example\n * pageTitles = [\n * { title: 'Personal Information', description: 'Fill in your personal details.' },\n * { title: 'Address', description: 'Provide your residential address.' }\n * ];\n */\n @Input()\n pageTitles: { title: string; description: string}[] = [];\n\n\n /**\n * @description The CRUD operation type for this form.\n * @summary Defines the type of operation being performed (CREATE, READ, UPDATE, DELETE).\n * This affects form behavior, validation rules, and field accessibility. For example,\n * READ operations might disable form fields, while CREATE operations enable all fields.\n *\n * @type {CrudOperations}\n * @default OperationKeys.CREATE\n * @memberOf SteppedFormComponent\n */\n @Input()\n override operation: CrudOperations = OperationKeys.CREATE;\n\n /**\n * @description The initial page to display when the form loads.\n * @summary Specifies which page of the multi-step form should be shown first.\n * This allows starting the form at any step, useful for scenarios like editing\n * existing data where you might want to jump to a specific section.\n *\n * @type {number}\n * @default 1\n * @memberOf SteppedFormComponent\n */\n @Input()\n startPage: number = 1;\n\n // /**\n // * @description Angular reactive FormGroup or FormArray for form state management.\n // * @summary The form instance that manages all form controls, validation, and form state.\n // * When using FormArray, each array element represents a page's FormGroup. When using\n // * FormGroup, it contains all form controls for the entire stepped form.\n // *\n // * @type {FormGroup | FormArray | undefined}\n // * @memberOf SteppedFormComponent\n // */\n // @Input()\n // formGroup!: FormGroup | FormArray | undefined;\n\n /**\n * @description Array representing the structure of pages.\n * @summary Contains metadata about each page, including page numbers and indices.\n * This array is built during initialization to organize the form fields into\n * logical pages and provide navigation structure.\n *\n * @type {UIModelMetadata[]}\n * @memberOf SteppedFormComponent\n */\n pagesArray: UIModelMetadata[] = [];\n\n\n // /**\n // * @description Custom event handlers for form actions.\n // * @summary A record of event handler functions keyed by event names that can be\n // * triggered during form operations. These handlers provide extensibility for\n // * custom business logic and can be invoked for various form events and actions.\n // *\n // * @type {HandlerLike}\n // */\n // @Input()\n // handlers!: HandlerLike;\n\n\n\n /**\n * @description Event emitter for form submission.\n * @summary Emits events when the form is submitted, typically on the last page\n * when all validation passes. The emitted event contains the form data and\n * event type information for parent components to handle.\n *\n * @type {EventEmitter<IBaseCustomEvent>}\n * @memberOf SteppedFormComponent\n */\n // @Output()\n // submitEvent: EventEmitter<ICrudFormEvent> = new EventEmitter<ICrudFormEvent>();\n\n /**\n * @description Creates an instance of SteppedFormComponent.\n * @summary Initializes a new SteppedFormComponent instance and registers the required\n * Ionic icons for navigation buttons (forward and back arrows).\n *\n * @memberOf SteppedFormComponent\n */\n constructor() {\n super(\"SteppedFormComponent\");\n addIcons({arrowForwardOutline, arrowBackOutline});\n this.enableDarkMode = true;\n }\n\n /**\n * @description Initializes the component after Angular first displays the data-bound properties.\n * @summary Sets up the stepped form by organizing children into pages, calculating the total\n * number of pages, and initializing the active page. This method processes the UI model metadata\n * to create a logical page structure and ensures proper page assignments for all form fields.\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular Lifecycle\n * participant S as SteppedFormComponent\n * participant F as Form Service\n *\n * A->>S: ngOnInit()\n * S->>S: Set activeIndex = startPage\n * S->>S: Calculate total pages\n * S->>S: Assign page props to children\n * S->>S: getCurrentFormGroup(activeIndex)\n * S->>F: Extract FormGroup for active page\n * F-->>S: Return activeFormGroup\n *\n * @memberOf SteppedFormComponent\n */\n override async ngOnInit(): Promise<void> {\n if (!this.locale)\n this.locale = getLocaleContext(\"SteppedFormComponent\")\n this.activeIndex = this.startPage;\n if (typeof this.pages === 'object') {\n this.pageTitles = this.pages;\n } else {\n if (!this.pageTitles.length)\n this.pageTitles = Array.from({ length: this.pages }, () => ({ title: '', description: ''}));\n }\n\n this.pages = this.pageTitles.length;\n\n if (this.paginated) {\n if (!this.parentForm)\n this.parentForm = (this.formGroup?.root || this.formGroup) as FormParent;\n this.children = [... (this.children as UIModelMetadata[]).map((c) => {\n if (!c.props)\n c.props = {};\n const page = c.props['page'] || 1;\n // prevent page overflow\n c.props['page'] = page > this.pages ? this.pages : page;\n return c;\n })];\n this.getActivePage(this.activeIndex);\n } else {\n this.children = this.pageTitles.map((page, index) => {\n const pageNumber = index + 1;\n const items = (this.children as UIModelMetadata[]).filter(({ props }: UIElementMetadata) => props?.['page'] === pageNumber);\n return {\n page: pageNumber,\n title: page.title,\n description: page.description,\n items\n };\n });\n // this.formGroup = new FormGroup(\n // (this.formGroup as FormArray).controls.reduce((acc, control, index) => {\n // acc[index] = control as FormGroup;\n // return acc;\n // }, {} as Record<string, FormGroup>)\n // );\n }\n this.initialized = true;\n }\n\n /**\n * @description Cleanup method called when the component is destroyed.\n * @summary Unsubscribes from any active timer subscriptions to prevent memory leaks.\n * This is part of Angular's component lifecycle and ensures proper resource cleanup.\n *\n * @memberOf SteppedFormComponent\n */\n override ngOnDestroy(): void {\n super.ngOnDestroy();\n if (this.timerSubscription)\n this.timerSubscription.unsubscribe();\n }\n\n /**\n * @description Handles navigation to the next page or form submission.\n * @summary Validates the current page's form fields and either navigates to the next page\n * or submits the entire form if on the last page. Form validation must pass before\n * proceeding. On successful submission, emits a submit event with form data.\n *\n * @param {boolean} lastPage - Whether this is the last page of the form\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant S as SteppedFormComponent\n * participant F as Form Service\n * participant P as Parent Component\n *\n * U->>S: Click Next/Submit\n * S->>F: validateFields(activeFormGroup)\n * F-->>S: Return validation result\n * alt Not last page and valid\n * S->>S: activeIndex++\n * S->>S: getCurrentFormGroup(activeIndex)\n * else Last page and valid\n * S->>F: getFormData(formGroup)\n * F-->>S: Return form data\n * S->>P: submitEvent.emit({data, name: SUBMIT})\n * end\n *\n * @memberOf SteppedFormComponent\n */\n handleNext(lastPage: boolean = false): void {\n const isValid = NgxFormService.validateFields(this.formGroup as FormGroup);\n // const isValid = this.paginated ?\n // NgxFormService.validateFields(this.formGroup as FormGroup) :\n // (this.formGroup as FormArray)?.controls.every(control => NgxFormService.validateFields(control as FormGroup));\n if (!lastPage) {\n if (isValid) {\n this.activeIndex = this.activeIndex + 1;\n this.getActivePage(this.activeIndex);\n }\n } else {\n if (isValid) {\n const rootForm = this.formGroup?.root || this.formGroup;\n const data = Object.assign({}, ...Object.values(NgxFormService.getFormData(rootForm as FormGroup)));\n this.submitEvent.emit({\n data,\n component: this.componentName,\n name: this.action || ComponentEventNames.SUBMIT,\n handlers: this.handlers,\n });\n }\n }\n }\n\n /**\n * @description Handles navigation to the previous page.\n * @summary Moves the user back to the previous page in the stepped form.\n * This method decrements the active page number and updates the form\n * group and children to display the previous page's content.\n *\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant U as User\n * participant S as SteppedFormComponent\n *\n * U->>S: Click Back\n * S->>S: activeIndex--\n * S->>S: getCurrentFormGroup(activeIndex)\n * Note over S: Update active form and children\n *\n * @memberOf SteppedFormComponent\n */\n handleBack(): void {\n if (!this.paginated)\n return this.location.back();\n this.activeIndex = this.activeIndex - 1;\n this.getActivePage(this.activeIndex);\n }\n\n\n\n // async submit(event?: SubmitEvent, eventName?: string, componentName?: string): Promise<boolean | void> {\n // if (event) {\n // event.preventDefault();\n // event.stopImmediatePropagation();\n // }\n\n // if (!NgxFormService.validateFields(this.formGroup as FormGroup))\n // return false;\n // const data = NgxFormService.getFormData(this.formGroup as FormGroup);\n // this.submitEvent.emit({\n // data,\n // component: componentName || this.componentName,\n // name: eventName || this.action || ComponentEventNames.SUBMIT,\n // handlers: this.handlers,\n // });\n // }\n}\n","<form\n class=\"dcf-steped-form\"\n [class.paginated]=\"paginated\"\n novalidate\n #component\n>\n @if (paginated) {\n <div class=\"dcf-page-steps\">\n <div class=\"dcf-grid dcf-grid-collapse skip\">\n @for (page of pageTitles; track $index) {\n <div class=\"dcf-flex dcf-flex-middle\">\n <div\n class=\"dcf-step\"\n [class.dcf-active]=\"activeIndex === $index + 1\"\n [class.dcf-passed]=\"$index + 1 < activeIndex\"\n >\n {{ $index + 1 }}\n </div>\n @if (page?.title || page?.description) {\n <div class=\"dcf-information dcf-visible@s\">\n @if (page?.title) {\n <div class=\"dcf-title\">{{ page?.title | translate }}</div>\n }\n @if (page?.description) {\n <div class=\"dcf-description\">\n {{ page?.description | translate }}\n </div>\n }\n <div class=\"dcf-separator\"></div>\n </div>\n }\n @if ($index < pageTitles.length - 1) {\n <div class=\"dcf-arrow-container\">\n <svg\n width=\"8\"\n height=\"12\"\n viewBox=\"0 0 8 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M1.5 1L6.5 6L1.5 11\" />\n </svg>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (\n pageTitles[activeIndex - 1]?.title ||\n pageTitles[activeIndex - 1]?.description\n ) {\n <div class=\"dcf-current-step\">\n <div>\n @if (pageTitles[activeIndex - 1]?.title) {\n <div class=\"dcf-title\">\n {{ pageTitles[activeIndex - 1]?.title | translate }}\n </div>\n }\n @if (pageTitles[activeIndex - 1]?.description) {\n <div class=\"dcf-description\">\n {{ pageTitles[activeIndex - 1]?.description | translate }}\n </div>\n }\n </div>\n </div>\n }\n\n @if (initialized && activePage?.length) {\n <ngx-decaf-layout\n [className]=\"'dcf-stepped-form-grid paginated dcf-grid-nested'\"\n [children]=\"activePage || []\"\n [parentForm]=\"formGroup || parentForm\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [match]=\"false\"\n [cardBody]=\"cardBody\"\n [cardType]=\"cardType\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [match]=\"false\"\n />\n } @else {\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%\"\n ><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text\n ></ion-text>\n <br />\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%\"\n ><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text\n ></ion-text>\n }\n <div\n class=\"dcf-buttons-container dcf-grid dcf-grid-collapse dcf-flex dcf-flex-left\"\n >\n <div class=\"dcf-width-1-2@s\">\n <ion-button color=\"light\" (click)=\"handleBack()\" [disabled]=\"activeIndex <= 1\">{{ locale + \".previous\" | translate }}</ion-button>\n </div>\n\n <div class=\"dcf-width-1-2@s\">\n <ion-button fill=\"solid\" (click)=\"handleNext(activeIndex === pages ? true : false)\">\n @if (activeIndex === pages) {\n {{ locale + \".submit\" | translate }}\n } @else {\n {{ locale + \".next\" | translate }}\n }\n </ion-button>\n </div>\n </div>\n } @else {\n <div class=\"dcf-single-step\">\n @for (item of children; track $index) {\n <ngx-decaf-card\n [className]=\"className\"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <div>\n @if (item.title || item.description) {\n <div class=\"dcf-information\">\n <div>\n @if (item.title) {\n <div class=\"dcf-title\">{{ item.title | translate }}</div>\n }\n @if (item.description) {\n <div class=\"dcf-description\">\n {{ item.description | translate }}\n </div>\n }\n </div>\n </div>\n }\n <div [class.dcf-margin-bottom]=\"cardType === 'blank'\">\n @if (initialized && item.items?.length) {\n <ngx-decaf-layout\n [className]=\"'dcf-stepped-form-grid dcf-grid-nested'\"\n [children]=\"item.items || []\"\n [parentForm]=\"formGroup || parentForm\"\n [flexMode]=\"props.flexMode || false\"\n [gap]=\"'small'\"\n [cardBody]=\"cardBody\"\n [cardType]=\"cardType\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [match]=\"false\"\n />\n }\n </div>\n </div>\n </ngx-decaf-card>\n }\n <div\n class=\"dcf-buttons-container dcf-grid dcf-grid-small dcf-flex dcf-flex-right\"\n >\n <div class=\"dcf-width-auto@s dcf-width-1-1\">\n <ion-button color=\"light\" (click)=\"handleBack()\">\n {{ locale + \".cancel\" | translate }}\n </ion-button>\n </div>\n\n <div class=\"dcf-width-auto@s dcf-width-1-1\">\n <ion-button fill=\"solid\" (click)=\"handleNext(true)\">\n {{ locale + \".submit\" | translate }}\n </ion-button>\n </div>\n </div>\n </div>\n }\n</form>\n","import { CommonModule } from '@angular/common';\nimport { Component, ElementRef, EventEmitter, Input, Output, ViewChild, OnInit, OnDestroy } from '@angular/core';\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport {\n IonItem, IonLabel, IonList,\n IonButton\n } from '@ionic/angular/standalone';\n import { TranslatePipe } from '@ngx-translate/core';\nimport { HTML5InputTypes } from '@decaf-ts/ui-decorators';\nimport { Dynamic } from '../../engine/decorators';\nimport { NgxFormFieldDirective } from '../../engine/NgxFormFieldDirective';\nimport { ElementSize, FlexPosition, PossibleInputTypes } from '../../engine/types';\nimport { ElementSizes, ComponentEventNames } from '../../engine/constants';\nimport { IBaseCustomEvent, IFileUploadError } from '../../engine/interfaces';\nimport { presentNgxLightBoxModal } from '../modal/modal.component';\nimport { CardComponent } from '../card/card.component';\nimport { IconComponent } from '../icon/icon.component';\n\n\nconst FileErrors = {\n notAllowed: 'not_allowed',\n maxSize: 'max_size',\n} as const;\n\n/**\n * @description File upload component for Angular applications.\n * @summary This component provides a user interface for uploading files with support for drag-and-drop,\n * file validation, and preview functionality. It integrates seamlessly with Angular reactive forms\n * and supports multiple file uploads, directory mode, and custom file size limits.\n *\n * @class FileUploadComponent\n * @example\n * ```typescript\n * <ngx-decaf-file-upload [formGroup]=\"formGroup\" [name]=\"'fileInput'\" [multiple]=\"true\"></ngx-decaf-file-upload>\n * ```\n * @mermaid\n * sequenceDiagram\n * participant User\n * participant FileUploadComponent\n * User->>FileUploadComponent: Select or drag files\n * FileUploadComponent->>FileUploadComponent: Validate files\n * FileUploadComponent->>FileUploadComponent: Emit change event\n * User->>FileUploadComponent: Remove file\n * FileUploadComponent->>FileUploadComponent: Update file list\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-file-upload',\n templateUrl: './file-upload.component.html',\n styleUrls: ['./file-upload.component.scss'],\n standalone: true,\n imports: [CommonModule, ReactiveFormsModule, CardComponent, IconComponent, IonList, IonLabel, IonItem, TranslatePipe, IonButton],\n})\nexport class FileUploadComponent extends NgxFormFieldDirective implements OnInit, OnDestroy {\n\n @ViewChild('component', { static: true })\n override component!: ElementRef<HTMLInputElement>;\n\n /**\n * @description Parent form group.\n * @summary References the parent form group to which this field belongs.\n * This is necessary for integrating the field with Angular's reactive forms.\n *\n * @type {FormGroup}\n */\n @Input()\n override formGroup: FormGroup | undefined;\n\n /**\n * @summary The flat field name used as the form control identifier in immediate parent FormGroup.\n * @description Specifies the name of the field, which is used as the FormControl identifier in immediate parent FormGroup.\n * This value must be unique within the immediate parent FormGroup context and should not contain dots or nesting.\n *\n * @type {string}\n */\n @Input()\n override name!: string;\n\n /**\n * @description Angular FormControl instance for this field.\n * @summary The specific FormControl instance that manages this field's state, validation,\n * and value. This provides direct access to Angular's reactive forms functionality\n * for this individual field within the broader form structure.\n *\n * @type {FormControl}\n */\n @Input()\n override formControl!: FormControl;\n\n /**\n * @description Whether the field is required.\n * @summary When true, the field must have a value for the form to be valid.\n * Required fields are typically marked with an indicator in the UI.\n *\n * @type {boolean}\n */\n @Input()\n override required?: boolean;\n\n /**\n * @description Allows multiple file selection.\n * @summary When true, the user can select multiple files for upload.\n *\n * @type {boolean}\n * @default false\n */\n @Input()\n override multiple: boolean = false;\n\n /**\n * @description Specifies the input type for the file upload field.\n * @summary Defines the type of input element used for file uploads, such as file or directory.\n *\n * @type {PossibleInputTypes}\n * @default HTML5InputTypes.FILE\n */\n @Input()\n override type: PossibleInputTypes = HTML5InputTypes.FILE;\n\n /**\n * @description Label for the file upload field.\n * @summary Provides a user-friendly label for the file upload input.\n *\n * @type {string | undefined}\n */\n @Input()\n label?: string;\n\n /**\n * @description Label for the upload button.\n * @summary Specifies the text displayed on the file upload button.\n *\n * @type {string | undefined}\n */\n @Input()\n buttonLabel?: string;\n\n /**\n * @description Size of the file upload component.\n * @summary Determines the visual size of the file upload component, such as large, small, or default.\n *\n * @type {Extract<ElementSize, 'large' | 'small' | 'default'>}\n * @default ElementSizes.large\n */\n @Input()\n size: Extract<ElementSize, 'large' | 'small' | 'default'> = ElementSizes.large;\n\n /**\n * @description Flex positioning of the container's content.\n * @summary Controls how child elements are positioned within the container when flex layout\n * is enabled. Options include 'center', 'top', 'bottom', 'left', 'right', and combinations\n * like 'top-left'. This property is only applied when the flex property is true.\n *\n * @type {FlexPosition}\n * @default 'center'\n */\n @Input()\n position: FlexPosition = 'center';\n\n\n /**\n * @description Accepted file types for upload.\n * @summary Specifies the file types that are allowed for upload, such as images or documents.\n *\n * @type {string | string[]}\n * @default ['image/*']\n */\n @Input()\n accept: string | string[] = ['image/*'];\n\n /**\n * @description Whether to show an icon in the file upload field.\n * @summary When true, an icon is displayed alongside the file upload input.\n *\n * @type {boolean}\n * @default true\n */\n @Input()\n showIcon: boolean = true;\n\n /**\n * @description Enables directory mode for file uploads.\n * @summary When true, the user can upload entire directories instead of individual files.\n *\n * @type {boolean}\n * @default false\n */\n @Input()\n enableDirectoryMode: boolean = false;\n\n /**\n * @description Maximum file size allowed for upload.\n * @summary Specifies the maximum size (in MB) for files that can be uploaded.\n *\n * @type {number}\n * @default 1\n */\n @Input()\n maxFileSize: number = 1;\n\n /**\n * @description Event emitted when the file upload field changes.\n * @summary Emits an event containing details about the change in the file upload field.\n *\n * @type {EventEmitter<IBaseCustomEvent>}\n */\n @Output()\n changeEvent: EventEmitter<IBaseCustomEvent> = new EventEmitter<IBaseCustomEvent>();\n\n /**\n * @description Preview of the first file in the upload list.\n * @summary Stores the data URL of the first file in the upload list for preview purposes.\n * This is typically used to display a thumbnail or preview image.\n *\n * @type {string | undefined}\n */\n preview: string | undefined = undefined;\n\n /**\n * @description List of files selected for upload.\n * @summary Contains the files selected by the user for upload. This array is updated\n * whenever files are added or removed from the upload list.\n *\n * @type {File[]}\n */\n files: File[] = [];\n\n /**\n * @description List of errors encountered during file validation.\n * @summary Stores validation errors for files that do not meet the specified criteria,\n * such as file type or size restrictions. Each error includes the file name, size, and error message.\n *\n * @type {IFileUploadError[]}\n */\n errors: IFileUploadError[] = [];\n\n /**\n * @description Indicates whether a drag operation is in progress.\n * @summary This flag is set to true when a file is being dragged over the upload area.\n * It is used to provide visual feedback to the user during drag-and-drop operations.\n *\n * @type {boolean}\n * @default false\n */\n dragging: boolean = false;\n\n /**\n * @description Counter for drag events.\n * @summary Tracks the number of drag events to ensure proper handling of drag-and-drop\n * operations. The counter is incremented on drag enter and decremented on drag leave.\n *\n * @type {number}\n * @default 0\n */\n private dragCounter: number = 0;\n\n constructor() {\n super(\"FileUploadComponent\");\n }\n\n /**\n * @description Lifecycle hook that is called after Angular has initialized all data-bound properties of a directive.\n * @summary Sets up the component by enabling directory mode if specified, formatting the accepted file types,\n * and converting the maximum file size from megabytes to bytes.\n *\n * @returns {void}\n */\n ngOnInit(): void {\n if (this.enableDirectoryMode) {\n this.multiple = true;\n }\n if (Array.isArray(this.accept)) {\n this.accept = this.accept.join(',');\n }\n // Convert maxFileSize from MB to bytes\n this.maxFileSize = this.maxFileSize * 1024 * 1024;\n }\n\n /**\n * @description Lifecycle hook that is called when a directive, pipe, or service is destroyed.\n * @summary Cleans up the component by calling the parent ngOnDestroy method and clearing the file upload state.\n *\n * @returns {Promise<void> | void}\n */\n override ngOnDestroy(): Promise<void> | void {\n super.ngOnDestroy();\n this.handleClear();\n }\n\n /**\n * @description Handles the click event to trigger file selection.\n * @summary Simulates a click on the hidden file input element to open the file selection dialog.\n * This method is used to allow users to select files programmatically.\n *\n * @returns {void}\n */\n handleClickToSelect(): void {\n const element = this.component.nativeElement;\n if (element)\n (element.querySelector('#dcf-file-input') as HTMLButtonElement)?.click();\n }\n\n /**\n * @description Handles the file selection event.\n * @summary Processes the files selected by the user, validates them, and updates the file list.\n * This method is triggered when the user selects files using the file input element.\n *\n * @param {Event} event - The file selection event.\n * @returns {void}\n */\n handleSelection(event: Event): void {\n this.clearErrors();\n const input = event.target as HTMLInputElement;\n if (input.files) {\n const fileList = Array.from(input.files);\n this.handleSelectionConfirm(fileList);\n input.value = '';\n }\n }\n\n /**\n * @description Handles the drop event for drag-and-drop file uploads.\n * @summary Processes the files dropped by the user, validates them, and updates the file list.\n * This method is triggered when the user drops files onto the upload area.\n *\n * @param {DragEvent} event - The drag-and-drop event.\n * @returns {void}\n */\n handleDrop(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this.dragCounter = 0;\n this.dragging = false;\n this.clearErrors();\n if (!event.dataTransfer) return;\n const fileList = Array.from(event.dataTransfer.files);\n this.handleSelectionConfirm(fileList);\n }\n\n /**\n * @description Handles the drag over event for drag-and-drop file uploads.\n * @summary Sets the dragging flag to true to provide visual feedback during drag-and-drop operations.\n * This method is triggered when the user drags files over the upload area.\n *\n * @param {DragEvent} event - The drag over event.\n * @returns {void}\n */\n handleDragOver(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this.dragging = true;\n }\n\n /**\n * @description Handles the drag leave event for drag-and-drop file uploads.\n * @summary Decrements the drag counter and clears the dragging flag when the counter reaches zero.\n * This method is triggered when the user drags files out of the upload area.\n *\n * @param {DragEvent} event - The drag leave event.\n * @returns {void}\n */\n handleDragLeave(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this.dragCounter = Math.max(0, this.dragCounter - 1);\n if (this.dragCounter === 0) {\n this.dragging = false;\n }\n }\n\n /**\n * @description Clears the file list and validation errors.\n * @summary Resets the file upload component by clearing the selected files, preview, and errors.\n * This method is used to reset the component state.\n *\n * @returns {void}\n */\n handleClear(): void {\n this.clearErrors();\n this.preview = undefined;\n this.files = [];\n }\n\n /**\n * @description Confirms the file selection and updates the component state.\n * @summary Validates each file in the selection, updates the file list, and emits\n * the change event. If multiple or directory mode is enabled, adds files to the existing list.\n * Otherwise, replaces the existing files with the new selection.\n *\n * @param {File[]} files - The array of files selected by the user.\n * @returns {Promise<void>}\n */\n private async handleSelectionConfirm(files: File[]): Promise<void> {\n const validFiles: File[] = [];\n for (const file of files) {\n const isValid = this.validateFile(file);\n if (isValid === true) {\n validFiles.push(file);\n } else {\n this.errors.push({\n name: file.name,\n error: isValid,\n size: file.size\n });\n }\n }\n if (this.multiple || this.enableDirectoryMode) {\n this.files = this.files.concat(validFiles);\n } else {\n this.files = [validFiles[0]];\n }\n if(this.files.length) {\n const dataValues = await this.getDataURLs(this.files)\n this.setValue(JSON.stringify(dataValues));\n }\n\n await this.getPreview();\n this.changeEventEmit();\n }\n\n /**\n * @description Validates a single file against the component's constraints.\n * @summary Checks the file type and size against the accepted values and limits.\n * Returns true if the file is valid, or an error code if it is not.\n *\n * @param {File} file - The file to be validated.\n * @returns {true | string} - Returns true if valid, error code otherwise.\n */\n private validateFile(file: File): true | string {\n if (this.accept && this.accept !== '*') {\n const acceptedExtensions = Array.isArray(this.accept) ?\n this.accept : this.accept.split(',').map(ext => ext.trim());\n const accept = acceptedExtensions.some(ext => {\n if (ext === '*')\n return true;\n if (ext.endsWith('/*'))\n return file.type.startsWith(ext.replace(/\\/\\*$/, ''));\n const fileExtension = file.type.split('/').pop() || '';\n return file.type === ext || fileExtension === ext || file.name.toLowerCase().endsWith(ext.replace('.', ''));\n });\n if (!accept)\n return FileErrors.notAllowed;\n }\n if (this.maxFileSize && file.size > this.maxFileSize)\n return FileErrors.maxSize;\n return true;\n }\n\n /**\n * @description Displays a preview of the selected file in a lightbox.\n * @summary If the file is an image, its data URL is retrieved and displayed in a modal lightbox.\n * The lightbox shows the image at its natural size, constrained to the viewport dimensions.\n *\n * @param {File | string} [file] - The file to be previewed. If not provided, the current preview file is used.\n * @returns {Promise<void>}\n */\n async showFilePreview(file: File | string, fileExtension: string = 'image/'): Promise<void> {\n\n let content: string | undefined;\n if(file instanceof File) {\n const dataUrl = await this.getDataURLs(file) as string[];\n if(dataUrl && dataUrl.length)\n file = dataUrl[0];\n }\n if(fileExtension.includes('image/'))\n content = '<img src=\"' + file + '\" style=\"max-width: 100%; height: auto;\" />';\n\n if(fileExtension.includes('xml')) {\n const parseXml = (xmlString: string): string | undefined => {\n try {\n xmlString = (xmlString as string).replace(/^data:[^;]+;base64,/, '').replace(/\\s+/g, '')\n const decodedString = atob(xmlString);\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(decodedString, \"text/xml\");\n\n // const encoder = new TextEncoder(); // gera bytes UTF-8\n // const utf8Bytes = encoder.encode(xmlDoc.documentElement.outerHTML);\n // return new TextDecoder(\"utf-8\").decode(utf8Bytes);\n\n return xmlDoc.documentElement.innerHTML;\n\n } catch (error: unknown) {\n this.log.error((error as Error)?.message);\n return undefined;\n }\n\n }\n content = parseXml(file as string);\n content = `<div class=\"dfc-padding\">${content}</div>`;\n }\n await presentNgxLightBoxModal(content || \"\");\n }\n\n /**\n * @description Checks if a file is an image based on its MIME type.\n * @summary Determines if the file can be accepted as an image by checking\n * if its type starts with 'image/'.\n *\n * @param {File} file - The file to be checked.\n * @returns {boolean} - True if the file is an image, false otherwise.\n */\n isImageFile(file: File): boolean {\n return file && file.type.startsWith('image/');\n }\n\n /**\n * @description Removes a file from the selection.\n * @summary Updates the file list to exclude the file at the specified index.\n * Emits the change event and updates the preview if necessary.\n *\n * @param {number} index - The index of the file to be removed.\n * @returns {Promise<void>}\n */\n async removeFile(index: number): Promise<void> {\n if (index <= this.files.length)\n this.files = [...this.files.filter((_, i) => i !== index)];\n await this.getPreview();\n this.changeEventEmit();\n }\n\n /**\n * @description Retrieves the preview image for the selected files.\n * @summary If the first selected file is an image, its data URL is retrieved and set as the preview.\n * If the file is not an image, the preview is cleared.\n *\n * @returns {Promise<void>}\n */\n private async getPreview(): Promise<void> {\n this.preview = undefined;\n const file = this.files && this.files.length ? this.files[0] : null;\n if (file) {\n const dataUrl = await this.getDataURLs(file) as string[];\n if(dataUrl && dataUrl.length)\n this.preview = dataUrl[0];\n }\n\n }\n\n /**\n * @description Emits the change event for the file upload field.\n * @summary Triggers the change event, notifying any listeners that the value has changed.\n * The event contains the updated value, component name, and event type.\n *\n * @returns {void}\n */\n private changeEventEmit(): void {\n this.changeEvent.emit({\n data: this.value,\n component: this.componentName,\n name: ComponentEventNames.CHANGE,\n });\n }\n\n /**\n * @description Retrieves the data URLs for the selected files.\n * @summary Converts the selected image files to data URLs using FileReader.\n * The resulting data URLs can be used for previewing images in the browser.\n *\n * @param {File[] | File} [files] - The files for which to generate data URLs.\n * If not provided, the currently selected files are used.\n *\n * @returns {Promise<string[] | undefined>} - A promise that resolves to an array of data URLs, or undefined if an error occurs.\n */\n private async getDataURLs(files?: File[] | File): Promise<string[] | undefined> {\n if(!files)\n files = this.files;\n if(!Array.isArray(files))\n files = [files];\n // files = files.filter(f => f.type && f.type.startsWith('image/'));\n return this.readFile(files).then(urls => {\n // validate generated DataURLs\n const invalid = urls.some(u => !this.isValidDataURL(u));\n if (invalid)\n return undefined;\n if (this.multiple || this.enableDirectoryMode)\n return urls;\n return urls.length ? [urls[0]] : undefined;\n }).catch(() => {\n return undefined;\n });\n }\n\n /**\n * @description Validates the format of a data URL.\n * @summary Checks if the data URL is a non-empty string and matches the expected pattern\n * for base64-encoded image data URLs. Uses a regular expression to validate the format.\n *\n * @param {string | undefined} dataURL - The data URL to be validated.\n * @returns {boolean} - True if the data URL is valid, false otherwise.\n */\n private isValidDataURL(dataURL: string | undefined): boolean {\n if (!dataURL || typeof dataURL !== 'string') {\n return false;\n }\n\n // Regex para qualquer MIME type seguido de ;base64\n const match = dataURL.match(/^data:([a-zA-Z0-9.+-\\\\/]+);base64,([A-Za-z0-9+/=\\s]+)$/);\n if (!match)\n return false;\n\n const payload = match[2];\n try {\n if (typeof atob === 'function') {\n // remove espaços e tenta decodificar\n atob(payload.replace(/\\s+/g, ''));\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * @description Clears all error messages from the component.\n * @summary Resets the error state, removing all error messages from the display.\n *\n * @returns {void}\n */\n private clearErrors(): void {\n this.errors = [];\n }\n\n /**\n * @description Reads the selected files as data URLs.\n * @summary Uses the FileReader API to read each file as a data URL.\n * Returns a promise that resolves to an array of data URLs.\n *\n * @param {File[]} files - The files to be read.\n * @returns {Promise<string[]>} - A promise that resolves to an array of data URLs.\n */\n private readFile(files: File[]): Promise<string[]> {\n return Promise.all(files.map(file => new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onerror = () => reject(reader.error);\n reader.onload = () => resolve(String(reader.result || ''));\n reader.readAsDataURL(file);\n })));\n }\n\n}\n","<div class=\"decaf-file-component\" #component>\n <input\n id=\"dcf-file-input\"\n type=\"file\"\n placeholder=\"Select files\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"handleSelection($event)\"\n [multiple]=\"multiple\"\n hidden\n [attr.webkitdirectory]=\"enableDirectoryMode ? true : null\"\n />\n\n <ngx-decaf-card [className]=\"className\" [body]=\"'blank'\">\n <div>\n <div\n [class]=\"\n 'dcf-drop-area '\n + ' dcf-' + size\n + ' dcf-flex dcf-flex-' + position\n + ' dcf-text-' + position\n \"\n\n [class.dcf-dragging]=\"dragging\"\n [class.dcf-has-files]=\"files.length\"\n (drop)=\"!files?.length ? handleDrop($event) : dragging = false\"\n (dragover)=\"!files?.length ? handleDragOver($event) : dragging = false\"\n (dragleave)=\"!files?.length ? handleDragLeave($event) : dragging = false\"\n >\n <div>\n @if (!preview) {\n @if(showIcon) {\n <ngx-decaf-icon name=\"cloud-upload-outline\" size=\"large\" />\n }\n <p class=\"dcf-drag-description\">{{ label ? (label | translate) : (locale + \".drag_file\" | translate) }}</p>\n <ion-button class=\"dcf-button-select\" (click)=\"handleClickToSelect()\" size=\"small\">\n {{ buttonLabel ? (buttonLabel | translate) : (locale + \".buttons.select\" | translate) }}\n </ion-button>\n <div #container>\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n } @else {\n @if ((!directoryMode && !multiple) ) {\n <div class=\"dcf-preview dcf-grid dcf-grid-match dcf-grid-collapse\">\n <div class=\"dcf-width-1-4@m dcf-width-1-3@s dcf-flex dcf-flex-center dcf-flex-middle\">\n <div class=\"dcf-preview-image\">\n <ion-img\n [src]=\"preview\"\n [title]=\"locale + '.preview' | translate\"\n [alt]=\"locale + '.preview' | translate\"\n />\n <div class=\"dcf-overlay\">\n <ion-button (click)=\"showFilePreview(preview)\" fill=\"clear\" color=\"light\" size=\"small\">\n {{ locale + \".buttons.preview\" | translate }}\n </ion-button>\n </div>\n </div>\n </div>\n <div class=\"description dcf-flex dcf-flex-middle dcf-width-expand@s\">\n <div>\n <p class=\"dcf-title\">{{ locale + \".preview\" | translate }}</p>\n <p class=\"subtitle\">{{ files[0].name }}</p>\n <ion-button (click)=\"handleClear()\" fill=\"clear\" color=\"danger\" size=\"small\">{{ locale + \".buttons.clear\" | translate }} </ion-button>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"dcf-margin-bottom\">\n {{ locale + \".selection\" | translate: { \"0\": files.length > 10 ? files.length : `0${files.length}` } }}\n @if(errors.length > 0) {\n <br /><span class=\"dcf-error-message\">{{ locale + \".selection_error\" | translate: { \"0\": errors.length > 10 ? errors.length : `0${errors.length}` } }}</span>\n }\n </div>\n <div class=\"dcf-preview-list-container\">\n <ion-list class=\"dcf-preview-list\">\n @for (file of errors; track $index) {\n <ion-item lines=\"full\" class=\"dcf-error-item\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <div class=\"dcf-error-message\" slot=\"end\">\n {{ locale + \".errors.\" + file.error | translate: { \"0\": file.error === 'max_size' ? maxFileSize / 1024 / 1024 : file.name.split(\".\") } }}\n </div>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n </ion-item>\n }\n\n @for (file of files; track $index) {\n <ion-item lines=\"full\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n <div class=\"dcf-flex dcf-flex-middle\" slot=\"end\">\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n (click)=\"showFilePreview(file, file.type)\"\n [name]=\"'image-outline'\"\n />\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n [name]=\"'trash-outline'\"\n (click)=\"removeFile($index)\"\n [color]=\"'danger'\"\n [size]=\"'small'\"\n />\n </div>\n </ion-item>\n }\n </ion-list>\n </div>\n }\n }\n </div>\n\n\n </div>\n </div>\n </ngx-decaf-card>\n</div>\n\n<!-- <ion-card-header>\n <ion-card-title>Upload de Imagem</ion-card-title>\n </ion-card-header>\n\n <ion-card-content>\n <div\n class=\"dcf-drop-area\"\n [class.dragging]=\"dragging\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n >\n <div class=\"dcf-drop-content\">\n <ion-icon name=\"cloud-upload-outline\" size=\"large\"></ion-icon>\n <p>Arraste e solte aqui ou</p>\n <ion-button size=\"small\" fill=\"outline\" (click)=\"triggerFileSelect()\">Selecionar arquivo</ion-button>\n </div>\n </div>\n\n <input\n #fileInput\n type=\"file\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"onFileSelected($event)\"\n hidden\n />\n\n <div *ngIf=\"previewUrl\" class=\"dcf-preview\">\n <ion-item>\n <div slot=\"start\">\n <ion-img [src]=\"previewUrl\"></ion-img>\n </div>\n <ion-label>\n <h3>Pré-visualização</h3>\n <p *ngIf=\"files.length\">{{ files[0].name }}</p>\n </ion-label>\n </ion-item>\n </div>\n\n <ion-list *ngIf=\"files.length\">\n <ion-list-header>\n <ion-label>Arquivos selecionados</ion-label>\n </ion-list-header>\n <ion-item *ngFor=\"let f of files; let i = index\">\n <ion-label>{{ f.name }}</ion-label>\n <ion-note slot=\"end\">{{ (f.size / 1024 / 1024) | number:'1.1-1' }} MB</ion-note>\n <ion-button fill=\"clear\" slot=\"end\" (click)=\"removeFile(i)\">\n <ion-icon slot=\"icon-only\" name=\"close-circle\"></ion-icon>\n </ion-button>\n </ion-item>\n </ion-list>\n\n <div *ngIf=\"errors.length\">\n <ion-list>\n <ion-item *ngFor=\"let err of errors\">\n <ion-icon name=\"alert-circle\" slot=\"start\" color=\"danger\"></ion-icon>\n <ion-label color=\"danger\">{{ err }}</ion-label>\n </ion-item>\n </ion-list>\n </div>\n\n <ion-row class=\"dcf-actions\">\n <ion-col>\n <ion-button expand=\"block\" (click)=\"triggerFileSelect()\">Selecionar</ion-button>\n </ion-col>\n <ion-col>\n <ion-button expand=\"block\" color=\"danger\" fill=\"outline\" (click)=\"clear()\">Limpar</ion-button>\n </ion-col>\n </ion-row>\n </ion-card-content> -->\n","/**\n * @module module:lib/components/for-angular-components.module\n * @description Aggregate module for library components.\n * @summary Bundles and exports all UI components from `src/lib/components` as an\n * Angular `NgModule`. This module re-exports components like `ListComponent`,\n * `PaginationComponent`, `SearchbarComponent`, and others so they can be imported\n * together in consumer applications.\n *\n * @link {@link ForAngularComponentsModule}\n */\n\nimport { NgModule } from '@angular/core';\nimport { CrudFieldComponent } from './crud-field/crud-field.component';\nimport { CrudFormComponent } from './crud-form/crud-form.component';\nimport { ModelRendererComponent } from './model-renderer/model-renderer.component';\nimport { SearchbarComponent } from './searchbar/searchbar.component';\nimport { EmptyStateComponent } from './empty-state/empty-state.component';\nimport { ListItemComponent } from './list-item/list-item.component';\nimport { ComponentRendererComponent } from './component-renderer/component-renderer.component';\nimport { PaginationComponent } from './pagination/pagination.component';\nimport { ListComponent } from './list/list.component';\nimport { FieldsetComponent } from './fieldset/fieldset.component';\nimport { LayoutComponent } from './layout/layout.component';\nimport { FilterComponent } from './filter/filter.component';\nimport { SteppedFormComponent } from './stepped-form/stepped-form.component';\nimport { IconComponent } from './icon/icon.component';\nimport { CardComponent } from './card/card.component';\nimport { FileUploadComponent } from './file-upload/file-upload.component';\n\nconst Components = [\n ModelRendererComponent,\n ComponentRendererComponent,\n CrudFieldComponent,\n CrudFormComponent,\n EmptyStateComponent,\n ListComponent,\n ListItemComponent,\n SearchbarComponent,\n PaginationComponent,\n CrudFormComponent,\n FieldsetComponent,\n LayoutComponent,\n FilterComponent,\n SteppedFormComponent,\n IconComponent,\n CardComponent,\n FileUploadComponent\n];\n\n@NgModule({\n imports: [...Components],\n declarations: [],\n schemas: [],\n exports: [...Components],\n})\nexport class ForAngularComponentsModule {}\n","/**\n * @module module:lib/components/index\n * @description Barrel exports for components.\n * @summary Re-exports the component modules and individual components from\n * `src/lib/components` so consumers can import them from a single entrypoint.\n * This file exposes components such as `ListComponent`, `PaginationComponent`,\n * `SearchbarComponent`, and the `ForAngularComponentsModule`.\n *\n * @link {@link ForAngularComponentsModule}\n */\n\n// Component exports\nexport * from './component-renderer/component-renderer.component';\nexport * from './crud-field/crud-field.component';\nexport * from './crud-form/crud-form.component';\nexport * from './empty-state/empty-state.component';\nexport * from './fieldset/fieldset.component';\nexport * from './filter/filter.component';\nexport * from './layout/layout.component';\nexport * from './list/list.component';\nexport * from './list-item/list-item.component';\nexport * from './model-renderer/model-renderer.component';\nexport * from './pagination/pagination.component';\nexport * from './searchbar/searchbar.component';\nexport * from './stepped-form/stepped-form.component';\nexport * from './modal/modal.component';\nexport * from './icon/icon.component';\nexport * from './card/card.component';\nexport * from './file-upload/file-upload.component';\n// Module export\nexport * from './for-angular-components.module';\n","/**\n * @module lib/engine/interfaces\n * @description Type and interface definitions used by the Angular rendering engine.\n * @summary Exposes interfaces for component input metadata, rendering outputs, form events,\n * and supporting types used across the engine and components.\n */\nimport { FormArray, FormControl, FormGroup } from '@angular/forms';\nimport { ElementRef, EnvironmentInjector, Injector, Type } from '@angular/core';\nimport { OrderDirection } from '@decaf-ts/core';\nimport { AngularFieldDefinition, FieldUpdateMode, KeyValue, StringOrBoolean } from './types';\nimport { CrudOperationKeys, FieldProperties, IPagedComponentProperties } from '@decaf-ts/ui-decorators';\nimport { FormParent } from './types';\nimport { Model } from '@decaf-ts/decorator-validation';\n\n\n/**\n * @description Interface for models that can be rendered\n * @summary Defines the basic structure for models that can be rendered by the engine.\n * Contains an optional rendererId that uniquely identifies the rendered instance.\n * @interface IRenderedModel\n * @property {string} [rendererId] - Optional unique ID for the rendered model instance\n * @memberOf module:engine\n */\nexport interface IRenderedModel {\n rendererId?: string;\n}\n\n\n/**\n * @description Interface for components that hold an ElementRef\n * @summary Defines a component holder interface that provides access to the underlying DOM element through ElementRef\n * @interface IComponentHolder\n * @memberOf module:engine\n */\nexport interface IComponentHolder {\n /**\n * @description Reference to the component's DOM element\n * @property {ElementRef} component - The ElementRef instance providing access to the native DOM element\n */\n component: ElementRef;\n}\n\n/**\n * @description Interface for form components that hold both an ElementRef and a FormGroup\n * @summary Extends IComponentHolder to include a FormGroup for form handling capabilities\n * @interface IFormElement\n * @memberOf module:engine\n */\nexport interface IFormElement extends IComponentHolder {\n /**\n * @description The Angular FormGroup associated with this form element\n * @property {FormGroup|undefined} formGroup - The form group instance for managing form controls and validation\n */\n formGroup: FormParent | undefined;\n}\n\n\n/**\n * @description Interface for fieldset item representation in the UI.\n * @summary Defines the structure for items displayed in the reorderable list within the fieldset.\n * Each item represents a value added to the fieldset with display properties for the UI.\n * @memberOf module:engine\n */\nexport interface IFieldSetItem {\n /** @description Sequential index number for ordering items in the list */\n index: number;\n /** @description Primary display text for the item */\n title: string;\n /** @description Optional secondary text providing additional item details */\n description?: string;\n}\n\n/**\n * @description Interface for fieldset validation event data.\n * @summary Defines the structure of validation events emitted when form validation occurs.\n * Used for communication between form components and the fieldset container.\n * @memberOf module:engine\n */\nexport interface IFieldSetValidationEvent {\n /** @description The FormGroup containing the validated form controls */\n formGroup: FormArray | FormGroup;\n /** @description The current form value being validated */\n value: unknown;\n /** @description Whether the form validation passed or failed */\n isValid: boolean;\n}\n\n\n/**\n * @description Interface for individual filter query items\n * @summary Defines the structure of a single filter criterion in a filter query.\n * Each item represents one condition to be applied to the data, consisting of\n * an index (field name), a condition (comparison operator), and a value to compare against.\n * @interface IFilterQueryItem\n * @property {string} [index] - Optional field name or index to filter on\n * @property {string} [condition] - Optional comparison condition (e.g., 'Equal', 'Contains', 'Greater Than')\n * @property {string} [value] - Optional value to compare the field against\n * @memberOf module:engine\n */\nexport interface IFilterQueryItem {\n index?: string,\n condition?: string,\n value?: string\n};\n\n/**\n * @description Interface for sorting configuration objects\n * @summary Defines the structure for specifying sort criteria including the field\n * to sort by and the direction of the sort (ascending or descending).\n * @interface ISortObject\n * @property {string} value - The field name or property to sort by\n * @property {OrderDirection} direction - The sort direction (ASC or DSC)\n * @memberOf module:engine\n */\nexport interface ISortObject {\n value: string,\n direction: OrderDirection\n};\n\n/**\n * @description Interface for complete filter query configuration\n * @summary Defines the complete structure for filter and sort operations.\n * Combines multiple filter criteria with sorting configuration to provide\n * comprehensive data filtering and ordering capabilities.\n * @interface IFilterQuery\n * @property {IFilterQueryItem[] | undefined} query - Array of filter criteria or undefined for no filtering\n * @property {ISortObject} sort - Sorting configuration specifying field and direction\n * @memberOf module:engine\n */\nexport interface IFilterQuery {\n query: IFilterQueryItem[] | undefined,\n sort: ISortObject\n}\n\n\n/**\n * @description Component input properties\n * @summary Extends FieldProperties with additional properties specific to Angular components.\n * Includes update mode for form controls and optional FormGroup and FormControl references.\n * @interface IComponentProperties\n * @property {FieldUpdateMode} [updateMode] - When the field value should be updated\n * @property {FormGroup} [formGroup] - Optional FormGroup reference\n * @property {FormControl} [formControl] - Optional FormControl reference\n * @memberOf module:engine\n */\nexport interface IComponentProperties extends FieldProperties, IPagedComponentProperties {\n model?: Model | string;\n props?: FieldProperties;\n}\n\n\nexport interface IFormComponentProperties extends IComponentProperties {\n updateMode?: FieldUpdateMode;\n formGroup?: FormGroup;\n operation?: CrudOperationKeys | undefined;\n formControl?: FormControl;\n mergeInParent?: boolean;\n}\n\n\n/**\n * @description Component configuration structure\n * @summary Defines the configuration for dynamically creating Angular components.\n * Contains the component name, input properties, injector, and optional child components.\n * @interface IComponentConfig\n * @property {string} component - The name of the component to render\n * @property {IComponentProperties} inputs - The input properties for the component\n * @property {EnvironmentInjector | Injector} injector - The Angular injector for dependency injection\n * @property {IComponentConfig[]} [children] - Optional child component configurations\n * @memberOf module:engine\n */\nexport interface IComponentConfig {\n component: string;\n inputs: IComponentProperties;\n injector: EnvironmentInjector | Injector;\n children?: IComponentConfig[];\n}\n\n/**\n * @description Metadata structure for Angular components\n * @summary Defines the structure of metadata for Angular components, including\n * change detection strategy, selector, standalone status, imports, template, and styles.\n * This is used for reflection and dynamic component creation.\n * @interface ComponentMetadata\n * @property {number} changeDetection - The change detection strategy number\n * @property {string} selector - The CSS selector for the component\n * @property {boolean} standalone - Whether the component is standalone\n * @property imports - Array of imported modules/components\n * @property {string} template - The HTML template for the component\n * @property {string[]} styles - Array of CSS styles for the component\n * @memberOf module:engine\n */\nexport interface ComponentMetadata {\n changeDetection: number;\n selector: string;\n standalone: boolean;\n imports: (new (...args: unknown[]) => unknown)[];\n template: string;\n styles: string[];\n}\n\n\n/**\n * @description Output structure from the Angular rendering engine\n * @summary Defines the structure of the output produced by the NgxRenderingEngine\n * when rendering a component. Contains the component type, inputs, injector,\n * content nodes, and child components.\n * @typedef {Object} AngularDynamicOutput\n * @property {Type<unknown>} component - The Angular component type\n * @property {string} [rendererId] - Optional unique ID for the rendered component\n * @property {Record<string, unknown>} [inputs] - Optional input properties for the component\n * @property {Injector} [injector] - Optional Angular injector for dependency injection\n * @property {Node[][]} [content] - Optional content nodes for projection\n * @property {AngularDynamicOutput[]} [children] - Optional child components\n * @property {Type<unknown>} [instance] - Optional component instance\n * @property {FormGroup} [formGroup] - Optional component FormGroup\n * @property {FormControl} [formControl] - Optional component FormControl\n * @memberOf module:engine\n */\nexport interface AngularDynamicOutput {\n component?: Type<unknown>;\n rendererId?: string;\n inputs?: Record<string, unknown>;\n injector?: Injector;\n content?: Node[][];\n children?: AngularDynamicOutput[];\n formGroup?: FormGroup;\n page?: number;\n formControl?: FormControl;\n projectable?: boolean;\n}\n\n\n/**\n * @description Base option type for input components\n * @summary Defines the common structure for options used in select, radio, and checkbox inputs.\n * Contains properties for the display text, value, disabled state, CSS class, and icon.\n * @interface InputOption\n * @property {string} text - The display text for the option\n * @property {string|number} value - The value associated with the option\n * @property {StringOrBoolean} [disabled] - Whether the option is disabled\n * @property {string} [className] - CSS class name for styling the option\n * @property {string} [icon] - Icon to display with the option\n * @memberOf module:engine\n */\nexport interface InputOption {\n text: string;\n value: string | number;\n disabled?: StringOrBoolean;\n className?: string;\n icon?: string;\n}\n\n/**\n * @description Interface for list component refresh events\n * @summary Defines the structure of a refresh event for list components.\n * Contains an array of key-value pairs representing the new data for the list.\n * @interface IListComponentRefreshEvent\n * @property {KeyValue[]} data - Array of key-value pairs representing the new data\n * @memberOf module:engine\n */\nexport interface IListComponentRefreshEvent {\n data: KeyValue[];\n}\n\n\n/**\n * @description Form service control structure\n * @summary Defines the structure for a form control managed by the form service.\n * Contains the FormGroup control and the associated field properties for rendering.\n * @interface FormServiceControl\n * @property {FormGroup} control - The Angular FormGroup for the control\n * @property {AngularFieldDefinition} props - The field properties for rendering the control\n * @memberOf module:engine\n */\nexport interface FormServiceControl {\n control: FormGroup;\n props: AngularFieldDefinition;\n}\n\n\n/**\n * @description Interface for list item custom events\n * @summary Defines the structure of custom events triggered by list items.\n * Extends IBaseCustomEvent with additional properties for the action and primary key.\n * @interface ListItemCustomEvent\n * @property {string} action - The action performed on the list item\n * @property {string} [pk] - Optional primary key of the affected item\n * @property {any} data - The data associated with the event (inherited from IBaseCustomEvent)\n * @property {HTMLElement} [target] - The target element (inherited from IBaseCustomEvent)\n * @property {string} [name] - The name of the event (inherited from IBaseCustomEvent)\n * @property {string} component - The component that triggered the event (inherited from IBaseCustomEvent)\n * @memberOf module:engine\n */\nexport interface ListItemCustomEvent extends IBaseCustomEvent {\n action: string;\n pk?: string;\n}\n\n\n/**\n * @description Base interface for custom events\n * @summary Defines the base structure for custom events in the application.\n * Contains properties for the event data, target element, name, and component.\n * @interface IBaseCustomEvent\n * @property {any} data - The data associated with the event\n * @property {HTMLElement} [target] - The target element that triggered the event\n * @property {string} [name] - The name of the event\n * @property {string} component - The component that triggered the event\n * @memberOf module:engine\n */\nexport interface IBaseCustomEvent {\n name: string;\n component?: string;\n data?: unknown;\n target?: HTMLElement;\n}\n\n\nexport interface IModelPageCustomEvent extends IBaseCustomEvent {\n success: boolean;\n message?: string;\n}\n\n\n/**\n * @description Configuration for internationalization (i18n) resource file paths\n * @summary Defines the structure for configuring i18n resource file paths with prefix and suffix.\n * Used by the translation system to locate and load language resource files.\n * @interface I18nResourceConfig\n * @property {string} prefix - The prefix to be used for the resource file path\n * @property {string} suffix - The suffix to be appended to the resource file path\n * @memberOf module:engine\n */\nexport interface I18nResourceConfig {\n prefix: string,\n suffix: string\n}\n\n/**\n * @description Internationalization token configuration\n * @summary Defines the structure for i18n tokens, including resource configurations and versioned suffix flag.\n * @interface I18nToken\n * @property {I18nResourceConfig[]} resources - Array of i18n resource configurations\n * @property {boolean} versionedSuffix - Whether to use a versioned suffix for resources\n * @memberOf module:engine\n */\nexport interface I18nToken {\n resources: I18nResourceConfig[];\n versionedSuffix: boolean;\n}\n\n\n/**\n * @description CRUD form event type\n * @summary Extends IBaseCustomEvent to include optional handlers for CRUD form operations.\n * This event type is used for form-related actions like create, read, update, and delete operations.\n * @interface ICrudFormEvent\n * @property {Record<string, unknown>} [handlers] - Optional handlers for form operations\n * @property {string} name - The name of the event (inherited from IBaseCustomEvent)\n * @property {string} [component] - The component that triggered the event (inherited from IBaseCustomEvent)\n * @property {unknown} [data] - The data associated with the event (inherited from IBaseCustomEvent)\n * @property {HTMLElement} [target] - The target element (inherited from IBaseCustomEvent)\n * @memberOf module:engine\n */\nexport interface ICrudFormEvent extends IBaseCustomEvent {\n handlers?: Record<string, unknown>;\n};\n\n/**\n * @description Pagination custom event\n * @summary Event emitted by pagination components to signal page navigation.\n * Extends IBaseCustomEvent and carries a payload with the target page number and navigation direction.\n * @interface IPaginationCustomEvent\n * @property {Object} data - The pagination data payload\n * @property {number} data.page - The target page number\n * @property {'next' | 'previous'} data.direction - The navigation direction\n * @memberOf module:engine\n */\nexport interface IPaginationCustomEvent extends IBaseCustomEvent {\n data: {\n page: number;\n direction: 'next' | 'previous';\n };\n}\n\n/**\n * @description Menu item definition\n * @summary Represents a single item in a navigation or contextual menu.\n * Includes the visible label and optional metadata such as accessibility title, target URL, icon, and color.\n * @interface IMenuItem\n * @property {string} label - The visible text label for the menu item\n * @property {string} [title] - Optional accessibility title or tooltip text\n * @property {string} [url] - Optional target URL for navigation\n * @property {string} [icon] - Optional icon identifier to display with the menu item\n * @property {string} [color] - Optional color theme for the menu item\n * @memberOf module:engine\n */\nexport interface IMenuItem {\n label: string;\n title?: string;\n url?: string;\n icon?: string;\n color?: string;\n}\n\n/**\n * @description Form reactive submit event data\n * @summary Defines the structure of data emitted when a reactive form is submitted.\n * Contains the processed form data as key-value pairs.\n * @interface IFormReactiveSubmitEvent\n * @property {Record<string, unknown>} data - The form data as key-value pairs\n * @memberOf module:engine\n */\nexport interface IFormReactiveSubmitEvent {\n data: Record<string, unknown>;\n}\n\n/**\n * @description CRUD form options configuration\n * @summary Defines the configuration options for CRUD form buttons including submit and clear buttons.\n * Each button can be customized with text, icon, and icon position.\n * @interface ICrudFormOptions\n * @property {Object} buttons - Configuration for form action buttons\n * @property {Object} buttons.submit - Submit button configuration\n * @property {string} [buttons.submit.icon] - Optional icon for the submit button\n * @property {'start' | 'end'} [buttons.submit.iconSlot] - Position of the icon relative to text\n * @property {string} [buttons.submit.text] - Text label for the submit button\n * @property {Object} [buttons.clear] - Optional clear button configuration\n * @property {string} [buttons.clear.icon] - Optional icon for the clear button\n * @property {'start' | 'end'} [buttons.clear.iconSlot] - Position of the icon relative to text\n * @property {string} [buttons.clear.text] - Text label for the clear button\n * @memberOf module:engine\n */\nexport interface ICrudFormOptions {\n buttons: {\n submit: {\n icon?: string;\n iconSlot?: 'start' | 'end';\n text?: string;\n };\n clear?: {\n icon?: string;\n iconSlot?: 'start' | 'end';\n text?: string;\n };\n };\n}\n\n/**\n * @description Empty list display options\n * @summary Defines the configuration for displaying an empty state in list components\n * when no data is available. Includes text, button, icon, and link settings.\n * @interface IListEmptyOptions\n * @property {string} title - Title text or translation key for empty state\n * @property {string} subtitle - Subtitle text or translation key for empty state\n * @property {boolean} showButton - Whether to show an action button in empty state\n * @property {string} buttonText - Button text or translation key\n * @property {string} link - Navigation link for the button\n * @property {string} icon - Icon identifier for the empty state\n * @memberOf module:engine\n */\nexport interface IListEmptyOptions {\n title: string;\n subtitle: string;\n showButton: boolean;\n buttonText: string;\n link: string;\n icon: string;\n}\n\n/**\n * @description Event emitted when the viewport/window size changes.\n * @summary Provides the new width and height in pixels for responsive handlers.\n *\n * Typical usage: subscribed by UI layout services or components to react to\n * window resizing and adjust layouts or trigger reflows.\n *\n * @example\n * const e: IWindowResizeEvent = { width: window.innerWidth, height: window.innerHeight };\n */\nexport interface IWindowResizeEvent {\n /** The new width of the window (innerWidth) in pixels */\n width: number;\n /** The new height of the window (innerHeight) in pixels */\n height: number;\n}\n\n\n\nexport interface IFileUploadError {\n name: string;\n size?: number;\n error: string\n}\n","/**\n * @description Abstract base class for dynamic Angular modules\n * @summary The DynamicModule serves as a base class for Angular modules that need to be\n * dynamically loaded or configured at runtime. It provides a common type for the rendering\n * engine to identify and work with dynamic modules.\n * @class DynamicModule\n * @example\n * ```typescript\n * @NgModule({\n * declarations: [MyComponent],\n * imports: [CommonModule]\n * })\n * export class MyDynamicModule extends DynamicModule {}\n * ```\n */\nexport abstract class DynamicModule {}\n","/**\n * @module module:lib/engine/NgxEventHandler\n * @description Event handler base class used by Decaf components.\n * @summary Defines NgxEventHandler which standardizes event handling logic and provides\n * logging support for handlers that process custom events emitted by components.\n *\n * @link {@link NgxEventHandler}\n */\nimport { LoggedClass } from \"@decaf-ts/logging\";\nimport { IBaseCustomEvent } from \"./interfaces\";\nimport { DecafComponent, DecafEventHandler } from \"@decaf-ts/ui-decorators\";\nimport { Router } from \"@angular/router\";\n\nexport abstract class NgxEventHandler extends DecafEventHandler {\n async refresh(args?: unknown[]): Promise<void> {\n this.log.for(this.refresh).debug(`Refresh called with args: ${args}`);\n }\n}\n","/**\n * @module lib/engine/NgxPageDirective\n * @description Base page component for Decaf Angular applications.\n * @summary Provides a page-level base class (NgxPageDirective) that extends NgxComponentDirective and\n * offers page-focused utilities such as menu management, title handling and router event hooks.\n * @link {@link NgxPageDirective}\n */\nimport { AfterViewInit, Directive, Inject, inject, OnInit } from \"@angular/core\";\nimport { NgxComponentDirective} from \"./NgxComponentDirective\";\nimport { Title } from \"@angular/platform-browser\";\nimport { IMenuItem } from \"./interfaces\";\nimport { CPTKN } from \"../for-angular-common.module\";\nimport { NavigationEnd, NavigationStart } from \"@angular/router\";\nimport { removeFocusTrap } from \"../utils/helpers\";\nimport { KeyValue } from \"./types\";\nimport { MenuController } from \"@ionic/angular\";\n\n\n/**\n * @description Base directive for page-level components in Decaf Angular applications.\n * @summary Abstract directive that provides foundational functionality for page components.\n * Extends NgxComponentDirective to add page-specific features including menu management,\n * page title handling, and Ionic lifecycle hooks. This directive serves as the base class for\n * all page-level components, providing consistent behavior for navigation, routing, and UI state.\n * @class NgxPageDirective\n * @extends {NgxComponentDirective}\n * @memberOf module:lib/engine/NgxPageDirective\n */\n@Directive()\nexport abstract class NgxPageDirective extends NgxComponentDirective implements OnInit, AfterViewInit {\n\n /**\n * @description Application name for display or identification purposes.\n * @summary Stores the name of the application, which can be used for display in headers,\n * titles, or for logging and identification throughout the app.\n * @type {string}\n * @memberOf module:lib/engine/NgxPageDirective\n */\n appName?: string;\n\n /**\n * @description Page title text for the current view.\n * @summary Stores the title text to be displayed for this page. This can be set dynamically\n * based on the current route or menu configuration and is used to update the browser's\n * title bar or page header.\n * @type {string}\n * @default ''\n * @memberOf module:lib/engine/NgxPageDirective\n */\n title: string = '';\n\n\n /**\n * @description Global key-value pairs for application-wide settings.\n * @summary This property stores global configuration values that can be accessed\n * throughout the application. It is typically used to manage shared state or\n * settings that are relevant across multiple components or services.\n * @type {KeyValue}\n * @memberOf module:lib/engine/NgxPageDirective\n */\n globals!: KeyValue;\n\n\n /**\n * @description Ionic menu controller service for menu management.\n * @summary Injected service that provides programmatic control over Ionic menu components.\n * This service allows the component to open, close, toggle, and manage menu states within\n * the application. It provides access to menu functionality for implementing navigation\n * and layout features that require menu interaction.\n * @protected\n * @type {MenuController}\n * @memberOf module:lib/engine/NgxPageDirective\n */\n protected menuController: MenuController = inject(MenuController);\n\n\n /**\n * @description Menu items array for page navigation.\n * @summary Contains the collection of menu items available for this page. Each menu item\n * defines a navigation option with properties like label, URL, icon, and visibility settings.\n * This array is used to construct the application's navigation menu and can be filtered or\n * customized per page.\n * @protected\n * @type {IMenuItem[]}\n * @default []\n * @memberOf module:lib/engine/NgxPageDirective\n */\n protected menu: IMenuItem[] = [];\n\n /**\n * @description Angular Title service for browser title management.\n * @summary Injected service that provides control over the browser's document title.\n * Used to dynamically set the page title based on the current route or active menu item,\n * improving SEO and user experience.\n * @protected\n * @type {Title}\n * @memberOf module:lib/engine/NgxPageDirective\n */\n protected titleService: Title = inject(Title);\n\n\n /**\n * @description Flag indicating whether the page should display the navigation menu.\n * @summary Controls the visibility and availability of the application menu for this page.\n * When set to true, the menu is enabled and accessible to users. When false, the menu\n * is disabled, which is useful for pages like login screens or standalone views that\n * should not show navigation options.\n * @protected\n * @type {boolean}\n * @default true\n * @memberOf module:lib/engine/NgxPageDirective\n */\n protected hasMenu: boolean = true;\n\n\n /**\n * @description Currently active route path for the page (without leading slash).\n * @summary This protected property stores the current route segment used by the\n * page to determine the displayed title and menu state. It is updated on\n * NavigationEnd events (see ngAfterViewInit) and consumed by the `pageTitle`\n * getter and `setPageTitle()` method. When undefined the component will\n * attempt to resolve the route from the router URL.\n * @protected\n * @type {string | undefined}\n * @default undefined\n */\n protected currentRoute?: string;\n\n /**\n * @description Constructor for NgxPageDirective.\n * @summary Initializes the page directive with optional locale root and menu visibility settings.\n * Calls the parent NgxComponentDirective constructor to set up base functionality including\n * logging, localization, and component identification.\n * @param {string} [localeRoot] - Optional locale root key for internationalization\n * @param {boolean} [hasMenu=true] - Whether this page should display the menu\n * @memberOf module:lib/engine/NgxPageDirective\n */\n // eslint-disable-next-line @angular-eslint/prefer-inject\n constructor(@Inject(CPTKN) localeRoot: string = \"NgxPageDirective\", @Inject(CPTKN) hasMenu: boolean = true) {\n super(localeRoot);\n this.hasMenu = hasMenu;\n // subscribe to media service color scheme changes\n this.mediaService.colorScheme$.subscribe();\n }\n\n get pageTitle(): string {\n if(this.title)\n return this.title;\n if(this.locale)\n return `${this.locale}.title`;\n if(this.currentRoute)\n return this.currentRoute?.charAt(0).toUpperCase() + this.currentRoute?.slice(1) || 'Decaf For Angular';\n return \"\";\n }\n\n ngOnInit(): Promise<void> | void{\n // connect component to media service for color scheme toggling\n this.mediaService.colorSchemeObserver(this.component);\n this.currentRoute = this.router.url.replace('/', '');\n this.setPageTitle(this.currentRoute);\n }\n\n /**\n * @description Ionic lifecycle hook called when the page is about to enter view.\n * @summary This lifecycle hook is triggered just before the page becomes visible to the user.\n * It enables or disables the application menu based on the hasMenu property, allowing pages\n * to control whether the menu should be accessible. This is useful for pages like login screens\n * where the menu should be hidden.\n * @return {Promise<void>} A promise that resolves when menu state is updated\n * @memberOf module:lib/engine/NgxPageDirective\n */\n\tasync ngAfterViewInit(): Promise<void> {\n this.router.events.subscribe(async event => {\n if(event instanceof NavigationEnd) {\n const url = (event?.url || \"\").replace('/', '');\n this.hasMenu = url !== \"login\" && url !== \"\";\n this.currentRoute = url;\n this.setPageTitle(this.currentRoute);\n this.title = this.pageTitle;\n }\n if (event instanceof NavigationStart)\n removeFocusTrap();\n });\n await this.menuController.enable(this.hasMenu);\n\t}\n\n\n\n /**\n * @description Sets the browser page title based on the current route.\n * @summary Updates the browser's document title by finding the active menu item that matches\n * the provided route. If a matching menu item is found, it sets the title using the format\n * \"Decaf For Angular - {menu title or label}\". This improves SEO and provides clear context\n * to users about the current page. If a custom menu array is provided, it uses that instead\n * of the component's default menu.\n * @protected\n * @param {string} route - The current route path to match against menu items\n * @param {IMenuItem[]} [menu] - Optional custom menu array to search (uses this.menu if not provided)\n * @return {void}\n * @memberOf module:lib/engine/NgxPageDirective\n */\n protected async setPageTitle(route?: string, menu?: IMenuItem[]): Promise<void> {\n if(!route)\n route = this.router.url.replace('/', '');\n if(!menu)\n menu = this.menu;\n const activeMenu = menu.find(item => item?.url?.includes(route));\n if(activeMenu) {\n const title = activeMenu?.title || activeMenu?.label;\n this.titleService.setTitle(`${await this.translate(title)} ${this.appName ? `- ${this.appName}` : ''}`);\n if(!this.title)\n this.title = title;\n }\n }\n\n}\n","import { Directive, Input } from '@angular/core';\nimport {\n InternalError,\n IRepository,\n NotFoundError,\n OperationKeys,\n} from '@decaf-ts/db-decorators';\nimport { EventIds, Repository } from '@decaf-ts/core';\nimport { Model, Primitives } from '@decaf-ts/decorator-validation';\nimport { NgxPageDirective } from './NgxPageDirective';\nimport { ComponentEventNames } from './constants';\nimport { IBaseCustomEvent, IModelPageCustomEvent } from './interfaces';\nimport { KeyValue, DecafRepository } from './types';\nimport { Constructor, Metadata } from '@decaf-ts/decoration';\nimport { getModelAndRepository } from '../for-angular-common.module';\n\n@Directive()\nexport abstract class NgxModelPageDirective extends NgxPageDirective {\n /**\n * @description Primary key value of the current model instance.\n * @summary Specifies the primary key value for the current model record being displayed or\n * manipulated by the component. This identifier is used for CRUD operations that target\n * specific records, such as read, update, and delete operations. The value corresponds to\n * the field designated as the primary key in the model definition.\n * @type {EventIds}\n * @memberOf module:lib/engine/NgxComponentDirective\n */\n @Input()\n override modelId!: EventIds;\n\n /**\n * @description The CRUD operation type to be performed on the model.\n * @summary Specifies which operation (Create, Read, Update, Delete) this component instance\n * should perform. This determines the UI behavior, form configuration, and available actions.\n * The operation affects form validation, field availability, and the specific repository\n * method called during data submission.\n *\n * @type {OperationKeys.CREATE | OperationKeys.READ | OperationKeys.UPDATE | OperationKeys.DELETE}\n * @default OperationKeys.READ\n * @memberOf ModelPage\n */\n @Input()\n override operation:\n | OperationKeys.CREATE\n | OperationKeys.READ\n | OperationKeys.UPDATE\n | OperationKeys.DELETE = OperationKeys.READ;\n\n /**\n * @description The name of the model class to operate on.\n * @summary Identifies which registered model class this component should work with.\n * This name is used to resolve the model constructor from the global model registry\n * and instantiate the appropriate repository for data operations. The model must\n * be properly registered using the @Model decorator for resolution to work.\n *\n * @type {string}\n * @memberOf ModelPage\n */\n @Input()\n modelName!: string;\n\n /**\n * @description Array of operations allowed for the current model instance.\n * @summary Dynamically determined list of operations that are permitted based on\n * the current context and model state. Initially contains CREATE and READ operations,\n * with UPDATE and DELETE added when a modelId is present. This controls which\n * action buttons are displayed and which operations are accessible to the user.\n *\n * @type {OperationKeys[]}\n * @default [OperationKeys.CREATE, OperationKeys.READ]\n * @memberOf ModelPage\n */\n allowedOperations: OperationKeys[] = [\n OperationKeys.CREATE,\n OperationKeys.READ,\n ];\n\n /**\n * @description Current model data loaded from the repository.\n * @summary Stores the raw data object representing the current model instance retrieved\n * from the repository. This property holds the actual data values for the model being\n * displayed or edited, and is set to undefined when no data is available or when an\n * error occurs during data loading.\n * @type {KeyValue | undefined}\n * @default undefined\n * @memberOf NgxModelPageDirective\n */\n modelData: KeyValue | undefined = undefined;\n\n /**\n * @description Error message from failed operations.\n * @summary Stores error messages that occur during repository operations such as\n * data loading, creation, update, or deletion. When set, this indicates an error\n * state that should be displayed to the user. Cleared on successful operations.\n * @type {string | undefined}\n * @default undefined\n * @memberOf NgxModelPageDirective\n */\n errorMessage: string | undefined = undefined;\n\n // constructor(@Inject(CPTKN) hm: boolean = true, @Inject(CPTKN) protected toastController?: ToastController) {\n // super(\"NgxModelPageDirective\");\n // }\n\n override get pageTitle(): string {\n if (!this.modelName && this.model instanceof Model)\n this.modelName = this.model?.constructor?.name || '';\n if (!this.operation)\n return this.title ? this.title : `Listing ${this.modelName}`;\n const operation =\n this.operation.charAt(0).toUpperCase() +\n this.operation.slice(1).toLowerCase();\n return this.modelName ? `${operation} ${this.modelName}` : this.title;\n }\n /**\n * @description Lazy-initialized repository getter with model resolution.\n * @summary Creates and returns a repository instance for the specified model name.\n * Resolves the model constructor from the global registry, instantiates the repository,\n * and creates a new model instance. Throws an InternalError if the model is not\n * properly registered with the @Model decorator.\n *\n * @return {DecafRepository<Model>} The repository instance for the current model\n *\n * @throws {InternalError} When the model is not found in the registry\n */\n override get repository(): DecafRepository<Model> | undefined {\n try {\n if (!this._repository) {\n const constructor = Model.get(this.modelName);\n if (!constructor)\n throw new InternalError(\n 'Cannot find model. was it registered with @model?'\n );\n this._repository = Repository.forModel(constructor);\n if (!this.pk) this.pk = Model.pk(constructor) as string;\n this.model = new constructor() as Model;\n }\n } catch (error: unknown) {\n this.log.warn(\n `Error getting repository for model: ${this.modelName}. ${(error as Error).message}`\n );\n this._repository = undefined;\n // throw new InternalError((error as Error)?.message || (error as string));\n }\n return this._repository as DecafRepository<Model>;\n }\n\n /**\n * @description Angular lifecycle hook for component initialization.\n * @summary Initializes the component by setting up the logger instance using the getLogger\n * utility. This ensures that logging is available throughout the component's lifecycle\n * for error tracking and debugging purposes.\n */\n async ionViewWillEnter(): Promise<void> {\n // await super.ionViewWillEnter();\n if (this.modelId)\n this.allowedOperations = this.allowedOperations.concat([\n OperationKeys.UPDATE,\n OperationKeys.DELETE,\n ]);\n this.getLocale(this.modelName as string);\n await this.refresh(this.modelId);\n this.initialized = true;\n }\n\n /**\n * @description Refreshes the component data by loading the specified model instance.\n * @summary Loads model data from the repository based on the current operation type.\n * For READ, UPDATE, and DELETE operations, fetches the existing model data using\n * the provided unique identifier. Handles errors gracefully by logging them through\n * the logger instance.\n *\n * @param {string} [uid] - The unique identifier of the model to load; defaults to modelId\n */\n override async refresh(uid?: EventIds): Promise<void> {\n if (!uid)\n uid = this.modelId;\n try {\n this._repository = this.repository;\n switch (this.operation) {\n case OperationKeys.READ:\n case OperationKeys.UPDATE:\n case OperationKeys.DELETE:\n this.model = (await this.handleGet(uid || this.modelId)) as Model;\n break;\n }\n } catch (error: unknown) {\n if (error instanceof NotFoundError) {\n this.errorMessage = error.message;\n }\n this.log.error(error as Error | string);\n }\n }\n\n /**\n * @description Generic event handler for component events.\n * @summary Processes incoming events from child components and routes them to appropriate\n * handlers based on the event name. Currently handles SUBMIT events by delegating to\n * the submit method. This centralized event handling approach allows for easy\n * extension and consistent event processing.\n *\n * @param {IBaseCustomEvent} event - The event object containing event data and metadata\n */\n override async handleEvent(\n event: IBaseCustomEvent,\n repository?: DecafRepository<Model>\n ): Promise<void> {\n const { name } = event;\n switch (name) {\n case ComponentEventNames.SUBMIT:\n await this.submit(event, repository);\n break;\n }\n }\n\n /**\n * @description Handles form submission events for CRUD operations.\n * @summary Processes form submission by executing the appropriate repository operation\n * based on the current operation type. Handles CREATE, UPDATE, and DELETE operations,\n * processes the form data, refreshes the repository cache, navigates back to the previous\n * page, and displays success notifications. Comprehensive error handling ensures robust\n * operation with detailed logging.\n *\n * @param {IBaseCustomEvent} event - The submit event containing form data\n * @return {Promise<IModelPageCustomEvent|void>} Promise that resolves on success or throws on error\n */\n override async submit(\n event: IBaseCustomEvent,\n repository?: DecafRepository<Model>,\n redirect: boolean = false\n ): Promise<IModelPageCustomEvent | void> {\n try {\n if (!repository) repository = this._repository as DecafRepository<Model>;\n\n // const pk = this.pk || Model.pk(repository.class as Constructor<Model>);\n const operation = this.operation;\n const { data } = event;\n if (data) {\n const model = this.parseData(data || {}, operation, repository);\n let result;\n switch (operation) {\n case OperationKeys.CREATE:\n result = await (!Array.isArray(model)\n ? repository.create(model as unknown as Model)\n : repository.createAll(model as unknown as Model[]));\n break;\n case OperationKeys.UPDATE:\n result = await (!Array.isArray(model)\n ? repository.update(model as unknown as Model)\n : repository.updateAll(model as unknown as Model[]));\n break;\n case OperationKeys.DELETE:\n result = await (!Array.isArray(model)\n ? repository.delete(model as string | number)\n : repository.deleteAll(model as string[] | number[]));\n break;\n }\n\n const message = await this.translate(\n !Array.isArray(result)\n ? `operations.${operation}.${result ? 'success' : 'error'}`\n : `operations.multiple`\n );\n\n if (result) {\n // repository.refresh(this.modelName, this.operation, this.modelId as EventIds);\n if (redirect) this.location.back();\n }\n return {\n ...event,\n success: result ? true : false,\n message,\n };\n }\n } catch (error: unknown) {\n return {\n ...event,\n success: false,\n message: error instanceof Error ? error.message : (error as string),\n };\n }\n }\n\n async create(\n data: Partial<Model>,\n repository: DecafRepository<Model>\n ): Promise<IModelPageCustomEvent | void> {\n alert('create');\n console.log(repository);\n console.log(data);\n }\n\n /**\n * @description Retrieves a model instance from the repository by unique identifier.\n * @summary Fetches a specific model instance using the repository's read method.\n * Handles both string and numeric identifiers by automatically converting numeric\n * strings to numbers. If no identifier is provided, logs an informational message\n * and navigates back to the previous page. Returns undefined for missing instances.\n *\n * @param {string} uid - The unique identifier of the model instance to retrieve\n * @return {Promise<Model | undefined>} Promise resolving to the model instance or undefined\n */\n async handleGet(\n uid?: EventIds,\n repository?: IRepository<any>,\n modelName?: string\n ): Promise<Model | undefined> {\n if (!uid) {\n this.log.info(\n 'No key passed to model page read operation, backing to last page'\n );\n this.location.back();\n return undefined;\n }\n\n if(!modelName)\n modelName = this.modelName;\n\n const getRepository = async (\n modelName: string,\n parent?: string,\n model?: KeyValue\n ): Promise<DecafRepository<Model> | undefined> => {\n if (this._repository) return this._repository as DecafRepository<Model>;\n const constructor = Model.get(modelName);\n if (constructor) {\n const properties = Metadata.properties(\n constructor as Constructor<Model>\n ) as string[];\n // if (!model) model = {} as KeyValue;\n for (const prop of properties) {\n const type = Metadata.type(\n constructor as Constructor<Model>,\n prop\n ).name;\n const context = getModelAndRepository(type as string);\n if (!context) return getRepository(type, prop, model);\n const { repository } = context;\n if (modelName === this.modelName) {\n const data = await this.handleGet(uid, repository, modelName);\n this.model = Model.build({ [prop]: data }, modelName);\n }\n\n // else {\n // model[prop as string] = Model.build({}, type);\n // }\n }\n // (this.model as KeyValue)[parent as string] = Model.build(\n // model,\n // modelName\n // );\n }\n };\n\n repository = (repository ||\n (await getRepository(modelName as string))) as IRepository<Model>;\n if (!repository) return this.model as Model;\n const type = Metadata.type(repository.class, Model.pk(repository.class) as string).name;\n try {\n const result = await (repository).read(\n ([Primitives.NUMBER, Primitives.BIGINT].includes(type.toLowerCase())\n ? Number(uid)\n : uid) as string\n );\n return result;\n } catch (error: unknown) {\n this.log\n .for(this.handleGet)\n .info(\n `Error getting model instance with id ${uid}: ${(error as Error).message}`\n );\n return undefined;\n }\n }\n\n /**\n * @description Parses and transforms form data for repository operations.\n * @summary Converts raw form data into the appropriate format for repository operations.\n * For DELETE operations, returns the primary key value (string or number). For CREATE\n * and UPDATE operations, builds a complete model instance using the Model.build method\n * with proper primary key assignment for updates.\n *\n * @param {Partial<Model>} data - The raw form data to be processed\n * @return {Model | string | number} Processed data ready for repository operations\n * @private\n */\n private parseData(\n data: KeyValue | KeyValue[],\n operation: OperationKeys,\n repository: DecafRepository<Model>\n ): Model | Model[] | EventIds {\n operation = (\n operation === OperationKeys.READ\n ? OperationKeys.DELETE\n : operation.toLowerCase()\n ) as OperationKeys;\n\n if (Array.isArray(data)) {\n data = data.map((item) =>\n this.parseData(item, operation, repository as DecafRepository<Model>)\n );\n return data as Model[];\n }\n\n let uid = this.modelId as EventIds;\n const pk = Model.pk(repository.class as Constructor<Model>);\n const type = Metadata.type(repository.class as Constructor<Model>, pk).name;\n uid = [Primitives.NUMBER, Primitives.BIGINT].includes(type.toLowerCase())\n ? Number(uid)\n : uid;\n if (operation !== OperationKeys.DELETE)\n return Model.build(\n this.modelId ? Object.assign(data, { [pk]: uid }) : data,\n repository.class.name\n ) as Model;\n return uid as EventIds;\n }\n}\n","/**\n * @module engine\n * @description Angular rendering engine for Decaf applications\n * @summary The engine module provides core functionality for rendering Angular components\n * in Decaf applications. It includes constants, decorators, rendering engines, and utility types\n * that enable dynamic component creation, property mapping, and component lifecycle management.\n * Key exports include {@link NgxRenderingEngine}, {@link DynamicModule}, and various decorators\n * for component configuration.\n */\nexport * from './constants';\nexport * from './decorators';\nexport * from './types';\nexport * from './interfaces';\nexport * from './DynamicModule';\nexport * from './NgxRenderingEngine';\nexport * from './NgxFormFieldDirective';\nexport * from '../services/NgxFormService';\nexport * from './NgxEventHandler';\nexport * from './NgxModelPageDirective';\nexport * from './NgxPageDirective';\nexport * from './NgxFormDirective';\nexport * from './NgxParentComponentDirective';\nexport * from './NgxComponentDirective';\nexport * from '../services/NgxMediaService';\n","/**\n * @module module:lib/public-apis\n * @description Public exports for the for-angular package.\n * @summary Re-exports the public API surface for the Decaf for-Angular integration. Consumers\n * should import from this barrel to access components, engine utilities, directives, helpers,\n * and i18n loaders provided by the library.\n *\n * @link {@link ForAngularCommonModule}\n */\nimport '@decaf-ts/ui-decorators';\nexport * from './components';\nexport * from './engine';\nexport * from './directives';\nexport * from './utils';\nexport * from './i18n/Loader';\nexport * from './for-angular-common.module';\n/**\n * @description Angular integration for the Decaf framework\n * @summary This module provides Angular components and services for integrating with the Decaf framework.\n * It includes components for rendering models, CRUD operations, and form handling, as well as\n * rendering engines and utility functions to facilitate Angular application development with Decaf.\n * @module for-angular\n */\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-apis';\n"],"names":["isValidDate","AllIcons"],"mappings":"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"}
|