@decaf-ts/for-angular 0.0.17 → 0.0.18
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/assets/i18n/en.json +3 -73
- package/assets/i18n/pt.json +5 -74
- package/components/crud-field/crud-field.component.d.ts +12 -3
- package/components/crud-form/crud-form.component.d.ts +36 -14
- package/components/empty-state/empty-state.component.d.ts +9 -10
- package/components/fieldset/fieldset.component.d.ts +9 -0
- package/components/filter/filter.component.d.ts +11 -2
- package/engine/NgxBaseComponent.d.ts +39 -39
- package/engine/NgxCrudFormField.d.ts +2 -1
- package/engine/NgxRenderingEngine.d.ts +44 -16
- package/engine/interfaces.d.ts +10 -0
- package/engine/types.d.ts +8 -0
- package/esm2022/components/crud-field/crud-field.component.mjs +23 -3
- package/esm2022/components/crud-form/crud-form.component.mjs +33 -18
- package/esm2022/components/empty-state/empty-state.component.mjs +11 -10
- package/esm2022/components/fieldset/fieldset.component.mjs +7 -4
- package/esm2022/components/filter/filter.component.mjs +16 -6
- package/esm2022/components/layout/layout.component.mjs +3 -3
- package/esm2022/components/list-item/list-item.component.mjs +4 -4
- package/esm2022/components/pagination/pagination.component.mjs +6 -6
- package/esm2022/engine/NgxBaseComponent.mjs +48 -53
- package/esm2022/engine/NgxCrudFormField.mjs +1 -1
- package/esm2022/engine/NgxRenderingEngine.mjs +20 -4
- package/esm2022/engine/interfaces.mjs +1 -1
- package/esm2022/engine/types.mjs +1 -1
- package/esm2022/helpers/utils.mjs +49 -32
- package/esm2022/i18n/Loader.mjs +82 -0
- package/fesm2022/decaf-ts-for-angular.mjs +288 -134
- package/fesm2022/decaf-ts-for-angular.mjs.map +1 -1
- package/helpers/utils.d.ts +42 -17
- package/i18n/Loader.d.ts +48 -0
- package/package.json +10 -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.module.ts","../../../src/lib/helpers/utils.ts","../../../src/lib/helpers/index.ts","../../../src/lib/engine/NgxFormService.ts","../../../src/lib/engine/NgxRenderingEngine.ts","../../../src/lib/components/component-renderer/component-renderer.component.ts","../../../src/lib/components/component-renderer/component-renderer.component.html","../../../src/lib/engine/NgxCrudFormField.ts","../../../src/lib/engine/decorators.ts","../../../src/lib/components/crud-field/crud-field.component.ts","../../../src/lib/components/crud-field/crud-field.component.html","../../../src/lib/engine/interfaces.ts","../../../src/lib/engine/DynamicModule.ts","../../../src/lib/engine/NgxBaseComponent.ts","../../../src/lib/engine/index.ts","../../../src/lib/components/crud-form/constants.ts","../../../src/lib/components/crud-form/crud-form.component.ts","../../../src/lib/components/crud-form/crud-form.component.html","../../../src/lib/components/empty-state/empty-state.component.ts","../../../src/lib/components/empty-state/empty-state.component.html","../../../src/lib/directives/collapsable.directive.ts","../../../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/model-renderer/model-renderer.component.ts","../../../src/lib/components/model-renderer/model-renderer.component.html","../../../src/lib/components/layout/layout.component.ts","../../../src/lib/components/layout/layout.component.html","../../../src/lib/components/list-item/list-item.component.ts","../../../src/lib/components/list-item/list-item.component.html","../../../src/lib/components/pagination/pagination.component.ts","../../../src/lib/components/pagination/pagination.component.html","../../../src/lib/components/list/constants.ts","../../../src/lib/components/list/list.component.ts","../../../src/lib/components/list/list.component.html","../../../src/lib/components/for-angular-components.module.ts","../../../src/lib/components/index.ts","../../../src/lib/public-apis.ts","../../../src/lib/decaf-ts-for-angular.ts"],"sourcesContent":["import { UIKeys } from '@decaf-ts/ui-decorators';\nimport { VALIDATION_PARENT_KEY } from '@decaf-ts/decorator-validation';\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.\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 * @const AngularEngineKeys\n * @memberOf module:engine\n */\nexport const AngularEngineKeys = {\n REFLECT: `${UIKeys.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 FORM_GROUP_COMPONENT_PROPS: 'componentProps'\n};\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 * @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:engine\n */\nexport const FormConstants = {\n VALID: 'VALID',\n INVALID: 'INVALID',\n};\n\n/**\n * @description Event name constants\n * @summary Enum containing constants for event names used throughout the application.\n * These are used to standardize event naming and handling.\n * @enum {string}\n * @readonly\n * @property {string} BACK_BUTTON_NAVIGATION - Event fired when back button navigation ends\n * @property {string} REFRESH_EVENT - Event fired when a refresh action occurs\n * @property {string} CLICK_EVENT - Event fired when a click action occurs\n * @property {string} SUBMIT_EVENT - Event fired when a form submission occurs\n * @memberOf module:engine\n */\nexport const EventConstants = {\n BACK_BUTTON_NAVIGATION: 'backButtonNavigationEndEvent',\n REFRESH: 'RefreshEvent',\n CLICK: 'ClickEvent',\n SUBMIT: 'SubmitEvent',\n VALIDATION_ERROR: 'validationErrorEvent',\n FIELDSET_ADD_GROUP: 'fieldsetAddGroupEvent',\n FIELDSET_UPDATE_GROUP: 'fieldsetUpdateGroupEvent',\n FIELDSET_REMOVE_GROUP: 'fieldsetRemoveGroupEvent',\n // FIELDSET_GROUP_VALIDATION: 'fieldsetGroupValidationEvent'\n}\n\n/**\n * @description Logger level constants\n * @summary Enum defining the logging levels used in the application's logging system.\n * Lower values represent more verbose logging, while higher values represent more critical logs.\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:engine\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 Enum defining the possible navigation directions in the application.\n * Used for controlling navigation flow and animation directions.\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:engine\n */\nexport enum RouteDirections {\n BACK = 'back',\n FORWARD = 'forward',\n ROOT = 'root',\n}\n\n\n/**\n * @description Component tag name constants\n * @summary Enum defining the tag names for custom components used in the application.\n * These tag names are used for component registration and rendering.\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 * @memberOf module:engine\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}\n\n/**\n * @description Base component property name constants\n * @summary Enum defining the standard property names used by base components in the application.\n * These property names are used for consistent property access across components.\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} 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 * @memberOf module:engine\n */\nexport enum BaseComponentProps {\n MODEL = 'model',\n LOCALE = 'locale',\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}\n\n\n","import { AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn } from '@angular/forms';\nimport {\n ComparisonValidationKeys,\n DEFAULT_PATTERNS,\n PathProxy,\n PathProxyEngine,\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 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 { name, type } = fieldProps;\n const { validatorKey, props } = resolveValidatorKeyProps(key, fieldProps[key as keyof FieldProperties], type);\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(type, type === HTML5InputTypes.CHECKBOX ? name : 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 if(!props['types'] && !props['customTypes'])\n props['types'] = props['type'];\n errs = validator.hasErrors(value, props, proxy);\n } catch (e: unknown) {\n errs = `${key} validator failed to validate: ${e}`;\n console.warn(errs);\n }\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","import { NgModule, CUSTOM_ELEMENTS_SCHEMA, ModuleWithProviders, NO_ERRORS_SCHEMA} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport {\n IonApp,\n IonRouterOutlet,\n IonSplitPane,\n IonImg,\n IonContent,\n IonText,\n IonButton,\n IonRouterLink,\n IonTitle\n} from '@ionic/angular/standalone';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { TranslateModule, TranslatePipe } from '@ngx-translate/core';\nimport { Logger, Logging } from '@decaf-ts/logging';\nimport { FunctionLike } from './engine';\n\nconst ComponentsAndModules = [\n IonApp,\n IonRouterOutlet,\n IonSplitPane,\n IonImg,\n IonText,\n IonTitle,\n IonButton,\n IonRouterLink,\n IonContent,\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n TranslateModule,\n TranslatePipe,\n];\n\nconst log = Logging.for(\"for-angular\");\nexport function getLogger(instance: string | FunctionLike | unknown): Logger {\n return log.for(instance as string | FunctionLike);\n}\n\n/**\n * @description Main Angular module for the Decaf framework\n * @summary The ForAngularModule 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 *\n * @class ForAngularModule\n * @example\n * ```typescript\n * // In your app module:\n * @NgModule({\n * imports: [\n * ForAngularModule.forRoot(),\n * // other imports\n * ],\n * // ...\n * })\n * export class AppModule {}\n * ```\n */\n@NgModule({\n imports: ComponentsAndModules,\n declarations: [],\n exports: ComponentsAndModules,\n schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],\n})\nexport class ForAngularModule {\n /**\n * @description Creates a module with providers for root module import\n * @summary This static method provides the proper way to import the ForAngularModule in the application's\n * root module. It returns a ModuleWithProviders object that includes the ForAngularModule itself.\n * Using forRoot() ensures that the module and its providers are properly initialized and only\n * instantiated once in the application.\n *\n * @return {ModuleWithProviders<ForAngularModule>} The module with its providers\n */\n static forRoot(): ModuleWithProviders<ForAngularModule> {\n return {\n ngModule: ForAngularModule,\n };\n }\n}\n","import { 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.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()?.[key as keyof Document];\n return doc instanceof Document ?\n doc : 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 | object,\n suffix?: string\n): string {\n if (typeof instance !== 'string')\n instance =\n (instance as FunctionLike).name || (instance as object)?.constructor?.name;\n\n let name: string | string[] = instance;\n\n if (suffix) name = `${instance}${suffix.charAt(0).toUpperCase() + suffix.slice(1)}`;\n\n name = name\n .replace(/_|-/g, '')\n .replace(/(?:^\\w|[A-Z]|\\b\\w)/g, (word: string, index: number) => {\n if (index > 1) word = '.' + word;\n return word.toLowerCase();\n })\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 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 generateLocaleFromString(\n locale: string,\n phrase: string | undefined\n): string {\n if (!phrase) return '';\n if (!locale || phrase.includes(`${locale}.`)) return phrase;\n return `${locale}.${phrase}`;\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 * Converts a string representation of a boolean or a boolean value to a boolean type.\n *\n * @export\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 */\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 * Checks if a value is a valid Date object\n *\n * @param {(string | Date | number)} date - The value to check. Can be a Date object, a timestamp number, or a date string\n * @return {boolean} Returns true if the value is a valid Date object (not NaN), otherwise false\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 * Formats a date into a localized string representation\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 * @return {(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 */\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 * Attempts to parse a date string, Date object, or number into a valid Date object\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 * @return {(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 */\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 * Maps an item object using a provided mapper object and optional additional properties.\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 */\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 * Maps an array of data objects using a provided mapper object.\n *\n * @template T - The type of the resulting mapped items.\n * @param {any[]} 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 *\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 */\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 // caso o item filtrado não possua nenhum valor, passar o objeto original\n accum.push(hasValues ? item : curr);\n return accum;\n }, []);\n}\n\n\nexport function removeFocusTrap(): void {\n const doc = getWindowDocument();\n if(doc?.activeElement)\n (doc.activeElement as HTMLElement)?.blur();\n}\n\nexport function cleanSpaces(value: string, lowercase = false): string {\n value = `${value}`.trim().replace(/\\s+/g, ' ');\n return lowercase ? value.toLowerCase() : value;\n}\n","/**\n * @module helpers\n * @description Utility helpers for Angular Decaf applications\n * @summary The helpers 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 './utils';\n","import { escapeHtml, FieldProperties, HTML5CheckTypes, HTML5InputTypes, parseToNumber } from '@decaf-ts/ui-decorators';\nimport { FieldUpdateMode, FormParentGroup, KeyValue } from './types';\nimport { IComponentConfig, IComponentInput } from './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 './ValidatorFactory';\nimport { cleanSpaces } from '../helpers';\nimport { OperationKeys } from '@decaf-ts/db-decorators';\nimport { AngularEngineKeys, 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 *\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 *\n * @type {WeakMap<AbstractControl, FieldProperties>}\n * @private\n * @static\n * @memberOf NgxFormService\n */\n private static controls = 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 *\n * @type {Map<string, FormGroup>}\n * @private\n * @static\n * @memberOf NgxFormService\n */\n private static formRegistry = new Map<string, FormGroup>();\n /**\n * @description Adds a form to the registry.\n * @summary Registers a FormGroup with a unique identifier. Throws an error if the identifier is already in use.\n * @param {string} formId - The unique identifier for the form.\n * @param {FormGroup} formGroup - The FormGroup to be registered.\n * @throws {Error} If a FormGroup with the given id is already registered.\n */\n static addRegistry(formId: string, formGroup: FormGroup): 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 Removes a form from the registry.\n * @summary Deletes a FormGroup from the registry using its unique identifier.\n * @param {string} formId - The unique identifier of the form to be removed.\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 * @param {FormGroup} formGroup - The root FormGroup.\n * @param {string} path - The path to the control.\n * @return {FormParentGroup} A tuple containing the parent FormGroup and the control name.\n */\n private static resolveParentGroup(formGroup: FormGroup, path: string, componentProps: IComponentInput, parentProps: KeyValue): FormParentGroup {\n const isMultiple = parentProps?.['multiple'] || parentProps?.['type'] === 'Array' || false;\n const parts = path.split('.');\n const controlName = parts.pop() as string;\n const {childOf} = componentProps\n let currentGroup = formGroup;\n\n function setArrayComponentProps(formGroupArray: FormArray) {\n const props = (formGroupArray as KeyValue)[AngularEngineKeys.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) ? new FormArray([new FormGroup({})]) : new FormGroup({});\n (partFormGroup as KeyValue)[AngularEngineKeys.FORM_GROUP_COMPONENT_PROPS] = {\n childOf: childOf || '',\n isMultiple: isMultiple,\n name: part,\n pk: componentProps?.['pk'] || parentProps?.['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\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\n currentGroup.addControl(part, partFormGroup);\n }\n }\n if(childOf && currentGroup instanceof FormArray)\n setArrayComponentProps(currentGroup);\n\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 *\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 *\n * @static\n * @memberOf NgxFormService\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)?.[AngularEngineKeys.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.\n *\n * @param {FormGroup} formGroup - The root form group containing the parent FormArray\n * @param {string} parentName - The name of the parent FormArray to add the group to\n * @param {number} [index=1] - The index position where the new group should be added\n * @return {FormGroup} The newly created and added FormGroup\n *\n * @static\n * @memberOf NgxFormService\n */\n static addGroupToParent(formGroup: FormGroup, parentName: string, index: number = 1): FormGroup {\n const componentProps = this.getComponentPropsFromGroupArray(formGroup, ModelKeys.MODEL, parentName);\n Object.entries(componentProps as KeyValue).forEach(([, value]) => {\n return this.addFormControl(formGroup, value, {multiple: true}, index);\n });\n\n return this.getGroupFromParent(formGroup, parentName, index);\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 *\n * @param {FormGroup} 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 *\n * @static\n * @memberOf NgxFormService\n */\n static getGroupFromParent(formGroup: FormGroup, 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, parentName, index);\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 *\n * @param {FormGroup} formGroup - The FormGroup to check for uniqueness\n * @param {number} index - The index of the current group within the FormArray\n * @param {OperationKeys} [operation=OperationKeys.CREATE] - The type of operation being performed\n * @return {boolean} True if the value is unique, false otherwise\n *\n * @static\n * @memberOf NgxFormService\n */\n static isUniqueOnGroup(formGroup: FormGroup, index: number, operation: OperationKeys = OperationKeys.CREATE): boolean {\n const formGroupArray = formGroup.parent as FormArray;\n const pk = this.getComponentPropsFromGroupArray(formGroupArray, BaseComponentProps.PK as string) as string;\n const controlName = Object.keys(formGroup.controls)[0];\n\n // only check for unique if is the pk control\n if(controlName !== pk)\n return true;\n const controlValue = cleanSpaces(`${formGroup.get(pk)?.value}`, true);\n if(operation === OperationKeys.CREATE)\n return !formGroupArray.controls.some((group, i) => i !== index && cleanSpaces(`${group.get(pk)?.value}`, true) === controlValue);\n\n return !formGroupArray.controls.some((group, i) =>\n i !== index && controlValue === cleanSpaces(`${group.get(pk)?.value}`, true)\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 *\n * @param {FormArray | FormGroup} formGroup - The FormGroup or FormArray to enable all controls for\n * @return {void}\n *\n * @static\n * @memberOf NgxFormService\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.\n *\n * @param {FormGroup} formGroup - The form group to add the control to\n * @param {IComponentInput} componentProps - The component properties defining the control configuration\n * @param {KeyValue} [parentProps={}] - Properties from the parent component for context\n * @param {number} [index=0] - The index for multiple controls in FormArrays\n * @return {void}\n *\n * @private\n * @static\n * @memberOf NgxFormService\n */\n private static addFormControl(formGroup: FormGroup, componentProps: IComponentInput, parentProps: KeyValue = {}, index: number = 0): void {\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, 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 parentGroup.addControl(controlName, control);\n }\n\n componentProps['formGroup'] = parentGroup;\n componentProps['formControl'] = parentGroup.get(controlName) as FormControl;\n componentProps['multiple'] = isMultiple\n\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 * @param {string} formId - The unique identifier of the form.\n * @param {string} [path] - The path to the control within the form.\n * @return {AbstractControl} The requested AbstractControl.\n * @throws {Error} If the form is not found in the registry or the control is not found in the form.\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 * @description Creates a form from component configurations.\n * @summary Generates a FormGroup based on an array of component configurations and optionally registers it.\n * @param {string} id - The unique identifier for the form.\n * @param {IComponentConfig[]} components - An array of component configurations.\n * @param {boolean} [registry=false] - Whether to register the created form.\n * @return {FormGroup} The created FormGroup.\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 * @param {string} id - The unique identifier of the form.\n * @param {FieldProperties} componentProperties - The properties of the component to create the control from.\n * @return {AbstractControl} The form or created control.\n */\n static addControlFromProps(id: string, componentProperties: FieldProperties, parentProps?: FieldProperties): AbstractControl {\n const form = this.formRegistry.get(id) ?? new FormGroup({});\n if (!this.formRegistry.has(id))\n this.addRegistry(id, form);\n\n if (componentProperties.path)\n this.addFormControl(form, componentProperties, parentProps);\n\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 * @param {FormGroup} formGroup - The FormGroup to extract data from.\n * @return {Record<string, unknown>} An object containing the form data.\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 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\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 }\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 * @param {AbstractControl} control - The control or form group to validate.\n * @param {string} [path] - The path to the control within the form.\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 */\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 return 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 * @param {FieldProperties} props - The component properties.\n * @return {ValidatorFn[]} An array of validator functions.\n */\n private static validatorsFromProps(props: FieldProperties): 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, k);\n });\n }\n\n /**\n * @description Creates a FormControl from component properties.\n * @summary Generates a FormControl with validators based on the provided component properties.\n * @param {FieldProperties} props - The component properties.\n * @param {FieldUpdateMode} [updateMode='change'] - The update mode for the control.\n * @return {FormControl} The created FormControl.\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 && props.type !== HTML5InputTypes.CHECKBOX\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.\n * @summary Gets the FieldProperties associated with a FormControl from the internal WeakMap.\n * @param {FormControl} control - The FormControl to get properties for.\n * @return {FieldProperties} The properties associated with the control.\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.\n * @summary Traverses up the DOM tree to find the nearest parent element with the specified tag.\n * @param {HTMLElement} el - The starting element.\n * @param {string} tag - The tag name to search for.\n * @return {HTMLElement} The found parent element.\n * @throws {Error} If no parent with the specified tag is found.\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.\n * @summary Associates a control with its properties in the internal WeakMap.\n * @param {AbstractControl} control - The control to register.\n * @param {FieldProperties} props - The properties to associate with the control.\n */\n static register(control: AbstractControl, props: FieldProperties) {\n this.controls.set(control, props);\n }\n\n /**\n * @description Unregisters a control.\n * @summary Removes a control and its associated properties from the internal WeakMap.\n * @param {AbstractControl} control - The control to unregister.\n * @return {boolean} True if the control was successfully unregistered, false otherwise.\n */\n static unregister(control: AbstractControl): boolean {\n return this.controls.delete(control);\n }\n\n /**\n * @description Resets a form group.\n * @summary Recursively resets all controls in a form group, clearing values, errors, and marking them as pristine and untouched.\n * @param {FormGroup} formGroup - The form group to reset.\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 { FieldDefinition, RenderingEngine } from '@decaf-ts/ui-decorators';\nimport { AngularFieldDefinition, KeyValue } from './types';\nimport { AngularDynamicOutput } from './interfaces';\nimport { AngularEngineKeys } from './constants';\nimport { Constructor, Model} from '@decaf-ts/decorator-validation';\nimport { InternalError } from '@decaf-ts/db-decorators';\nimport {\n ComponentMirror,\n ComponentRef,\n EnvironmentInjector,\n Injector,\n reflectComponentType,\n TemplateRef,\n Type,\n ViewContainerRef,\n} from '@angular/core';\nimport { NgxFormService } from './NgxFormService';\n\n/**\n * @description Angular implementation of the RenderingEngine with enhanced features\n * @summary This class extends the base RenderingEngine to provide Angular-specific rendering capabilities\n * with additional features compared to NgxRenderingEngine. It handles the conversion of field definitions\n * to Angular components, manages component registration, and provides utilities for component creation\n * and input handling. This implementation uses Angular's newer component APIs.\n *\n * @template AngularFieldDefinition - Type for Angular-specific field definitions\n * @template AngularDynamicOutput - Type for Angular-specific component output\n *\n * @class NgxRenderingEngine\n * @example\n * ```typescript\n * const engine = NgxRenderingEngine.get();\n * engine.initialize();\n * const output = engine.render(myModel, {}, viewContainerRef, injector, templateRef);\n * ```\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 */\nexport class NgxRenderingEngine extends RenderingEngine<AngularFieldDefinition, AngularDynamicOutput> {\n\n /**\n * @description Registry of registered components\n * @summary Static registry that maps component names to their constructors.\n * This allows the engine to look up components by name when rendering.\n * @type {Record<string, { constructor: Constructor<unknown> }>}\n */\n private static _components: Record<string, { constructor: Constructor<unknown> }>;\n\n /**\n * @description Collection of child component outputs\n * @summary Stores the outputs of child components during rendering.\n * @type {AngularDynamicOutput[]}\n */\n private _childs!: AngularDynamicOutput[];\n\n /**\n * @description Current model being rendered\n * @summary Reference to the model currently being processed by the rendering engine.\n * @type {Model}\n */\n private _model!: Model;\n\n private static _operation: string | undefined = undefined;\n\n /**\n * @description Static reference to the current instance\n * @summary Singleton instance reference for the rendering engine.\n * @type {Type<unknown> | undefined}\n */\n private static _instance: Type<unknown> | undefined;\n\n\n\n /**\n * @description Creates a new instance of NgxRenderingEngine\n * @summary Initializes the rendering engine with the 'angular' engine type.\n * This constructor sets up the base configuration needed for Angular-specific rendering.\n */\n constructor() {\n super('angular');\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, and child component rendering.\n * The method validates input properties against the component's metadata and processes\n * child components recursively.\n *\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 * @return {AngularDynamicOutput} The Angular component output with component reference and inputs\n *\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 */\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 ): AngularDynamicOutput {\n const cmp = (fieldDef as KeyValue)?.['component'] || 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(`Metadata for component ${fieldDef.tag} not found.`);\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(({ propName }) => propName === input);\n if (!isMapped) delete inputs[input];\n return !isMapped;\n });\n\n if (unmappedKeys.length > 0)\n console.warn(`Unmapped input properties for component ${fieldDef.tag}: ${unmappedKeys.join(', ')}`);\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 // const hiddenOn = inputs?.hidden || [];\n const result: AngularDynamicOutput = {\n component,\n inputs,\n injector,\n };\n\n if (fieldDef.rendererId)\n (result.inputs as Record<string, unknown>)['rendererId'] = fieldDef.rendererId;\n\n // process children\n if (fieldDef.children?.length) {\n result.children = fieldDef.children.map((child) => {\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 // create a child form and add its controls as properties of child.props\n NgxFormService.addControlFromProps(registryFormId, child.props, inputs);\n return this.fromFieldDefinition(child, vcr, injector, tpl, registryFormId);\n });\n }\n\n // generating DOM\n vcr.clear();\n const template = vcr.createEmbeddedView(tpl, injector).rootNodes;\n const componentInstance = NgxRenderingEngine.createComponent(\n component,\n { ...inputs, model: this._model },\n componentMetadata,\n vcr,\n injector,\n template,\n );\n\n result.instance = NgxRenderingEngine._instance = componentInstance.instance as Type<unknown>;\n\n return result;\n }\n\n\n /**\n * @description Creates an Angular component instance\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 *\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 */\n static createComponent(component: Type<unknown>, inputs: KeyValue = {}, metadata: ComponentMirror<unknown>, vcr: ViewContainerRef, injector: Injector, template: Node[] = []): ComponentRef<unknown> {\n const componentInstance = vcr.createComponent(component as Type<unknown>, {\n environmentInjector: injector as EnvironmentInjector,\n projectableNodes: [template],\n });\n this.setInputs(componentInstance, inputs, metadata);\n return componentInstance;\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 *\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 */\n getDecorators(model: Model, globalProps: Record<string, unknown>): FieldDefinition<AngularFieldDefinition> {\n return this.toFieldDefinition(model, globalProps);\n }\n\n /**\n * @description Destroys the current engine instance\n * @summary This static method clears the current instance reference, effectively\n * destroying the singleton instance of the rendering engine. This can be used\n * to reset the engine state or to prepare for a new instance creation.\n *\n * @return {Promise<void>} A promise that resolves when the instance is destroyed\n */\n static async destroy(): Promise<void> {\n NgxRenderingEngine._instance = undefined;\n }\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 *\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 *\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 */\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 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 KeyValue;\n if(!NgxRenderingEngine._operation)\n NgxRenderingEngine._operation = props?.['operation'] || undefined;\n result = this.fromFieldDefinition(fieldDef, vcr, injector, tpl, formId);\n\n (result!.instance! as KeyValue)['formGroup'] = NgxFormService.getControlFromForm(formId);\n NgxFormService.removeRegistry(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 *\n * @return {Promise<void>} A promise that resolves when initialization is complete\n */\n override async initialize(): Promise<void> {\n if (this.initialized)\n return;\n // ValidatableByType[]\n 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 *\n * @param {string} name - The name to register the component under\n * @param {Constructor<unknown>} constructor - The component constructor\n * @return {void}\n */\n static registerComponent(name: string, constructor: Constructor<unknown>): 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 *\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 */\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 Generates a key for reflection metadata\n * @summary This static method generates a key for reflection metadata by prefixing the input key\n * with the Angular engine's reflection prefix. This is used for storing and retrieving\n * metadata in a namespaced way to avoid conflicts with other metadata.\n *\n * @param {string} key - The base key to prefix\n * @return {string} The prefixed key for reflection metadata\n */\n static override key(key: string): string {\n return `${AngularEngineKeys.REFLECT}${key}`;\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 *\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 *\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 */\n static setInputs(component: ComponentRef<unknown>, inputs: KeyValue, metadata: ComponentMirror<unknown>): void {\n function parseInputValue(component: ComponentRef<unknown>, input: KeyValue) {\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((item: { propName: string }) => item.propName === key);\n if (prop) {\n if (key === 'props')\n parseInputValue(component, value);\n // if(key === 'locale' && !value)\n // value = getLocaleFromClassName(this._componentName);\n component.setInput(key, value);\n }\n });\n }\n}\n","import {\n Component,\n ComponentMirror,\n ComponentRef,\n EnvironmentInjector,\n EventEmitter,\n inject,\n Injector,\n Input,\n OnDestroy,\n OnInit,\n Output,\n reflectComponentType,\n TemplateRef,\n Type,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport { NgxRenderingEngine } from '../../engine/NgxRenderingEngine';\nimport { BaseCustomEvent, KeyValue, RendererCustomEvent } from '../../engine';\nimport { ForAngularModule, getLogger } from '../../for-angular.module';\nimport { Logger } from '@decaf-ts/logging';\nimport { Model } from '@decaf-ts/decorator-validation';\nimport { generateRandomValue } from '../../helpers';\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~RendererCustomEvent~ 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: [ForAngularModule],\n standalone: true,\n host: {'[attr.id]': 'rendererId'},\n})\nexport class ComponentRendererComponent\n implements OnInit, OnDestroy {\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 ComponentRendererComponent\n */\n @ViewChild('componentViewContainer', { static: true, read: ViewContainerRef })\n vcr!: ViewContainerRef;\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 /**\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 ComponentRendererComponent\n */\n @Input()\n globals: Record<string, unknown> = {};\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 ComponentRendererComponent\n */\n injector: EnvironmentInjector = inject(EnvironmentInjector);\n\n /**\n * @description Reference to the dynamically created component.\n * @summary This property holds a reference to the ComponentRef of the dynamically created\n * component. It's used to interact with the component instance, subscribe to its events,\n * and properly destroy it when the renderer is destroyed.\n *\n * @type {ComponentRef<unknown>}\n * @memberOf ComponentRendererComponent\n */\n component!: ComponentRef<unknown>;\n\n /**\n * @description Event emitter for events from the rendered component.\n * @summary This output property emits events that originate from the dynamically rendered\n * component. It allows the parent component to listen for and respond to events from the\n * dynamic component, creating a communication channel between the parent and the dynamically\n * rendered child.\n *\n * @type {EventEmitter<RendererCustomEvent>}\n * @memberOf ComponentRendererComponent\n */\n @Output()\n listenEvent: EventEmitter<RendererCustomEvent> =\n new EventEmitter<RendererCustomEvent>();\n\n /**\n * @description Logger instance for the component.\n * @summary This property holds a Logger instance specific to this component.\n * It's used to log information, warnings, and errors related to the component's\n * operations, particularly useful for debugging and monitoring the dynamic\n * component rendering process.\n *\n * @type {Logger}\n * @memberOf ComponentRendererComponent\n */\n logger!: Logger;\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 */\n @Input()\n model!: Model | undefined;\n\n @Input()\n parent: undefined | KeyValue = undefined;\n\n\n @ViewChild('inner', { read: TemplateRef, static: true })\n inner?: TemplateRef<unknown>;\n\n uid: string = generateRandomValue(12);\n\n /**\n * @description Creates an instance of ComponentRendererComponent.\n * @summary Initializes a new ComponentRendererComponent. This component doesn't require\n * any dependencies to be injected in its constructor as it uses the inject function to\n * obtain the EnvironmentInjector.\n *\n * @memberOf ComponentRendererComponent\n */\n constructor() {\n this.logger = getLogger(this);\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 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 ComponentRendererComponent\n */\n async ngOnDestroy(): Promise<void> {\n if (this.component) {\n this.unsubscribeEvents();\n NgxRenderingEngine.destroy();\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 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 this.vcr.clear();\n this.component = NgxRenderingEngine.createComponent(\n component,\n props,\n metadata as ComponentMirror<unknown>,\n this.vcr,\n this.injector as Injector,\n [],\n );\n this.subscribeEvents();\n }\n\n createParentComponent() {\n const { component, inputs } = this.parent as KeyValue;\n const metadata = reflectComponentType(component) as ComponentMirror<unknown>;\n const template = this.vcr.createEmbeddedView(this.inner as TemplateRef<unknown>, this.injector).rootNodes;\n this.component = NgxRenderingEngine.createComponent(\n component,\n inputs,\n metadata,\n this.vcr,\n this.injector,\n template,\n );\n this.subscribeEvents();\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 ComponentRendererComponent\n */\n private subscribeEvents(): void {\n if (this.component) {\n const instance = this.component?.instance as KeyValue;\n const componentKeys = Object.keys(instance);\n for (const key of componentKeys) {\n const value = instance[key];\n if (value instanceof EventEmitter)\n (instance as KeyValue)[key].subscribe(\n (event: Partial<BaseCustomEvent>) => {\n this.listenEvent.emit({\n name: key,\n ...event,\n } as RendererCustomEvent);\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 ComponentRendererComponent\n */\n private unsubscribeEvents(): void {\n if (this.component) {\n const instance = this.component?.instance as KeyValue;\n const componentKeys = Object.keys(instance);\n for (const key of componentKeys) {\n const value = instance[key];\n if (value instanceof EventEmitter) instance[key].unsubscribe();\n }\n }\n }\n}\n","<!-- Keep to avoid id conflicts -->\n<div [id]=\"uid\"></div>\n\n<ng-template #componentViewContainer></ng-template>\n<ng-template #inner>\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</ng-template>\n\n\n\n","import { CrudOperationKeys, FieldProperties, RenderingError } from '@decaf-ts/ui-decorators';\nimport { KeyValue, PossibleInputTypes } from './types';\nimport { CrudOperations, InternalError, OperationKeys } from '@decaf-ts/db-decorators';\nimport { ControlValueAccessor, FormControl, FormGroup } from '@angular/forms';\nimport { ElementRef, inject } from '@angular/core';\nimport { NgxFormService } from './NgxFormService';\nimport { sf } from '@decaf-ts/decorator-validation';\nimport { TranslateService } from '@ngx-translate/core';\nimport { EventConstants } from './constants';\n\n/**\n * @class NgxCrudFormField\n * @implements {FieldProperties}\n * @implements {ControlValueAccessor}\n * @summary Abstract class representing a CRUD form field for Angular applications\n * @description This class provides the base implementation for CRUD form fields in Angular,\n * implementing both CrudFormField and ControlValueAccessor interfaces.\n */\nexport abstract class NgxCrudFormField implements ControlValueAccessor, FieldProperties {\n /**\n * @summary Reference to the component's element\n * @description ElementRef representing the component's native element\n */\n component!: ElementRef;\n\n /**\n * @summary Current CRUD operation\n * @description Represents the current CRUD operation being performed\n */\n operation!: CrudOperations;\n\n /**\n * @summary Form group for the field\n * @description Angular FormGroup instance for the field\n */\n formGroup!: FormGroup | undefined;\n\n formControl!: FormControl;\n\n name!: string;\n\n path!: string;\n\n childOf?: string;\n\n type!: PossibleInputTypes;\n\n disabled?: boolean;\n\n uid?: string;\n\n // Validation\n\n format?: string;\n hidden?: boolean | CrudOperationKeys[];\n max?: number | Date;\n maxlength?: number;\n min?: number | Date;\n minlength?: number;\n pattern?: string | undefined;\n readonly?: boolean;\n required?: boolean;\n step?: number;\n equals?: string;\n different?: string;\n lessThan?: string;\n lessThanOrEqual?: string;\n greaterThan?: string;\n greaterThanOrEqual?: string;\n\n value!: string | number | Date;\n\n multiple!: boolean;\n\n private translateService = inject(TranslateService);\n\n private validationErrorEventDispateched: boolean = false;\n\n /**\n * @summary Parent HTML element\n * @description Reference to the parent HTML element of the field\n */\n protected parent?: HTMLElement;\n\n // protected constructor() {}\n\n /**\n * @summary String formatting function\n * @description Provides access to the sf function for error message formatting\n * @prop {function(string, ...string): string} sf - String formatting function\n */\n sf = sf;\n\n /**\n * @summary Change callback function\n * @description Function called when the field value changes\n * @property {function(): unknown} onChange - onChange event handler\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: () => unknown = () => {};\n\n /**\n * @summary Touch callback function\n * @description Function called when the field is touched\n * @property {function(): unknown} onTouch - onTouch event handler\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onTouch: () => unknown = () => {};\n\n /**\n * @summary Write value to the field\n * @description Sets the value of the field\n * @param {string} obj - The value to be set\n */\n writeValue(obj: string): void {\n this.value = obj;\n }\n\n /**\n * @summary Register change callback\n * @description Registers a function to be called when the field value changes\n * @param {function(): unknown} fn - The function to be called on change\n */\n registerOnChange(fn: () => unknown): void {\n this.onChange = fn;\n }\n\n /**\n * @summary Register touch callback\n * @description Registers a function to be called when the field is touched\n * @param {function(): unknown} fn - The function to be called on touch\n */\n registerOnTouched(fn: () => unknown): void {\n this.onTouch = fn;\n }\n\n /**\n * @summary Set disabled state\n * @description Sets the disabled state of the field\n * @param {boolean} isDisabled - Whether the field should be disabled\n */\n setDisabledState?(isDisabled: boolean): void {\n this.disabled = isDisabled;\n }\n\n /**\n * @summary After view initialization logic\n * @description Performs necessary setup after the view has been initialized\n * @returns {HTMLElement} The parent element of the field\n */\n afterViewInit(): HTMLElement {\n let parent: HTMLElement;\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 * @summary Cleanup on component destruction\n * @description Unregisters the field when the component is destroyed\n */\n onDestroy(): void {\n if(this.formGroup)\n NgxFormService.unregister(this.formGroup);\n }\n\n /**\n * @summary Get field errors\n * @description Retrieves all errors associated with the field\n * @returns {string|void} An array of error objects\n */\n getErrors(parent: HTMLElement): string | void {\n const formControl = this.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.validationErrorEventDispateched) {\n const validationErrorEvent = new CustomEvent(EventConstants.VALIDATION_ERROR, {\n detail: {fieldName: this.name, hasErrors: true},\n bubbles: true\n });\n accordionComponent.dispatchEvent(validationErrorEvent);\n this.validationErrorEventDispateched = true;\n }\n }\n for(const error of errors)\n return `* ${this.sf(this.translateService.instant(`errors.${error?.['message']}`), (this as KeyValue)[error?.['key']] ?? \"\")}`;\n }\n }\n}\n","import { apply, metadata } from '@decaf-ts/reflection';\nimport { NgxRenderingEngine } from './NgxRenderingEngine';\nimport { AngularEngineKeys } from './constants';\nimport { Constructor } from '@decaf-ts/decorator-validation';\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(NgxRenderingEngine.key(AngularEngineKeys.DYNAMIC), true)\n );\n}\n","import {\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 } from '@angular/forms';\nimport { AutocompleteTypes, SelectInterface } from '@ionic/core';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport { NgxCrudFormField } from '../../engine/NgxCrudFormField';\nimport { Dynamic } from '../../engine/decorators';\nimport { FieldUpdateMode, PossibleInputTypes, RadioOption, SelectOption, StringOrBoolean } from '../../engine/types';\nimport { ForAngularModule } from '../../for-angular.module';\nimport {\n IonCheckbox,\n IonIcon,\n IonInput,\n IonItem,\n IonLabel,\n IonRadio,\n IonRadioGroup,\n IonSelect,\n IonSelectOption,\n IonText,\n IonTextarea,\n} from '@ionic/angular/standalone';\nimport { HTML5InputTypes } from '@decaf-ts/ui-decorators';\nimport { addIcons } from 'ionicons';\nimport { chevronDownOutline, chevronUpOutline } from 'ionicons/icons';\nimport { generateRandomValue } from '../../helpers';\nimport { NgxFormService } from '../../engine/NgxFormService';\nimport { EventConstants } 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 NgxCrudFormField 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 ForAngularModule,\n IonInput,\n IonItem,\n IonCheckbox,\n IonRadioGroup,\n IonRadio,\n IonSelect,\n IonSelectOption,\n IonLabel,\n IonText,\n IonTextarea,\n IonIcon\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'},\n})\nexport class CrudFieldComponent extends NgxCrudFormField 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 /**\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 = '';\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;\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;\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 Number of columns for textarea inputs.\n * @summary For textarea inputs, this sets the visible width of the text area in average character widths.\n * This is used alongside rows to define the dimensions of the textarea.\n *\n * @type {number}\n * @memberOf CrudFieldComponent\n */\n @Input()\n cols?: number;\n\n /**\n * @description Number of rows for textarea inputs.\n * @summary For textarea inputs, this sets the visible height of the text area in lines of text.\n * This is used alongside cols to define the dimensions of the textarea.\n *\n * @type {number}\n * @memberOf CrudFieldComponent\n */\n @Input()\n rows?: number;\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 {SelectOption[] | RadioOption[]}\n * @memberOf CrudFieldComponent\n */\n @Input()\n options!: SelectOption[] | RadioOption[];\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 /**\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\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 *\n * @type {number}\n * @default 0\n * @memberOf CrudFieldComponent\n */\n @Input()\n activeFormGroup: number = 0;\n\n /**\n * @description FormArray containing multiple form groups for this field.\n * @summary When this field is part of a multi-entry structure, this FormArray\n * contains all the form groups. This enables management of multiple instances\n * of the same field structure within a single form.\n *\n * @type {FormArray}\n * @memberOf CrudFieldComponent\n */\n formGroupArray!: FormArray;\n\n /**\n * @description Primary key field name for uniqueness validation.\n * @summary Specifies the field name that serves as the primary key for uniqueness\n * validation within form arrays. This is used to prevent duplicate entries\n * and ensure data integrity in multi-entry forms.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input()\n pk!: string;\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 *\n * @returns {FormGroup} The currently active FormGroup for this field\n * @memberOf CrudFieldComponent\n */\n get getActiveFormGroup(): FormGroup {\n const formGroup = this.formGroup as FormGroup;\n return this.multiple\n ? ((formGroup.parent as FormArray)?.at(this.activeFormGroup) as FormGroup)\n : formGroup;\n\n }\n\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 ngOnInit(): void {\n if ([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation)) {\n this.formGroup = undefined;\n } else {\n addIcons({chevronDownOutline, chevronUpOutline})\n\n if(this.multiple) {\n this.formGroup = this.getActiveFormGroup as FormGroup;\n this.formGroupArray = this.formGroup.parent as FormArray;\n }\n\n if (this.type === HTML5InputTypes.RADIO && !this.value)\n this.formGroup?.get(this.name)?.setValue(this.options[0].value); // TODO: migrate to RenderingEngine\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 {void}\n * @memberOf CrudFieldComponent\n */\n ngAfterViewInit() {\n if ([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation))\n super.afterViewInit();\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 ngOnDestroy(): void {\n if ([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation))\n this.onDestroy();\n }\n\n /**\n * @description Handles fieldset group creation events from parent fieldsets.\n * @summary Processes events triggered when a new group needs to be added to a fieldset.\n * Validates the current form group, checks for uniqueness if applicable, and either\n * creates a new group or provides validation feedback. Updates the active form group\n * and resets the field for new input after successful creation.\n *\n * @param {CustomEvent} event - The fieldset create group event containing group details\n * @returns {void}\n * @memberOf CrudFieldComponent\n */\n @HostListener('window:fieldsetAddGroupEvent', ['$event'])\n handleFieldsetCreateGroupEvent(event: CustomEvent) {\n event.stopImmediatePropagation();\n const { parent, component, index, operation } = event.detail;\n const formGroup = this.formGroup as FormGroup;\n const parentFormGroup = this.formGroup?.parent as FormArray;\n const isValid = NgxFormService.validateFields(formGroup as FormGroup);\n const indexToCheck = operation === OperationKeys.CREATE ?\n index === 0 ? index : parentFormGroup.length - 1 : index - 1;\n\n const isUnique = NgxFormService.isUniqueOnGroup(formGroup, indexToCheck, operation || OperationKeys.CREATE);\n event = new CustomEvent(EventConstants.FIELDSET_ADD_GROUP, {\n detail: {isValid: isValid && isUnique, value: formGroup.value, formGroup: parentFormGroup, formService: NgxFormService},\n });\n component.dispatchEvent(event);\n if(isValid && isUnique) {\n const newIndex = parentFormGroup.length;\n\n if(operation === OperationKeys.CREATE) {\n NgxFormService.addGroupToParent(parentFormGroup?.parent as FormGroup, parent, newIndex);\n this.activeFormGroup = newIndex;\n } else {\n this.activeFormGroup = newIndex - 1;\n }\n this.formGroup = this.getActiveFormGroup;\n // NgxFormService.reset(this.formGroup as FormGroup);\n this.formControl = (this.formGroup as FormGroup).get(this.name) as FormControl;\n // NgxFormService.reset(this.formControl);\n // this.component.nativeElement.setFocus();\n } else {\n if(isUnique)\n this.component.nativeElement.setFocus();\n }\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 {index} = event.detail;\n this.activeFormGroup = index;\n this.formGroup = this.getActiveFormGroup;\n this.formControl = this.formGroup.get(this.name) as FormControl;\n }\n\n\n /**\n * @description Handles fieldset group removal events from parent fieldsets.\n * @summary Processes events triggered when a group needs to be removed from a fieldset.\n * Removes the specified group from the form array, updates the active form group index,\n * and refreshes the form references. Dispatches a confirmation event back to the component.\n *\n * @param {CustomEvent} event - The fieldset remove group event containing removal details\n * @returns {void}\n * @memberOf CrudFieldComponent\n */\n @HostListener('window:fieldsetRemoveGroupEvent', ['$event'])\n handleFieldsetRemoveGroupEvent(event: CustomEvent): void {\n const { component, index } = event.detail;\n const formArray = this.formGroup?.parent as FormArray;\n formArray.removeAt(index);\n this.activeFormGroup = formArray.length === 1 ? 0 : formArray.length - 1;\n this.formGroup = this.getActiveFormGroup;\n this.formControl = this.formGroup.get(this.name) as FormControl;\n this.formGroupArray = formArray\n event = new CustomEvent(EventConstants.FIELDSET_REMOVE_GROUP, {\n detail: {value: true},\n });\n component.dispatchEvent(event);\n }\n}\n","@if(operation === 'read' || operation === 'delete') {\n <ng-container #component>\n <div [class]=\"'dcf-input-item ' + operation\">\n <ion-item>\n <ion-label>\n {{ label | translate }}<br />\n @if(value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n <br />\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n <ng-container [formGroup]=\"getActiveFormGroup\">\n <div #container [class]=\"'dcf-input-item ' + (operation || 'create')\" (createGroupEvent)=\"multiple ? handleFieldsetCreateGroupEvent($event) : ''\">\n @if(type === 'textarea') {\n <ion-textarea\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [required]=\"required !== undefined ? required : null\"\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]=\"translatable ? (placeholder | translate) : placeholder\"\n [formControlName]=\"name\"\n [label]=\"translatable ? (label | translate) : label\"\n #component>\n </ion-textarea>\n }\n @else if(type === 'checkbox') {\n <ion-item>\n <ion-checkbox\n #checkboxElement\n\n [mode]=\"mode\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span [innerHTML]=\"label | translate\"></span>\n </ion-checkbox>\n </ion-item>\n }\n @else if(type === 'radio') {\n <ion-radio-group [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track option) {\n <ion-item>\n <ion-radio\n [errorText]=\"getErrors(container)\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ translatable ? (option?.text | translate) : option?.text }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if(type === 'select') {\n <ion-select\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"translatable ? (label | translate) : label\"\n [value]=\"value\"\n [fill]=\"fill\"\n [placeholder]=\"translatable ? (placeholder | translate) : placeholder\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [interface]=\"interface\" #component>\n @for(option of options; track option.value) {\n <ion-select-option [value]=\"option.value\">\n {{ translatable ? (option.text | translate) : options.text }}\n </ion-select-option>\n }\n </ion-select>\n }\n @else {\n <ion-input\n [type]=\"type\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [required]=\"required !== undefined ? required : false\"\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]=\"translatable ? (placeholder | translate) : placeholder\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [label]=\"translatable ? (label | translate) : label\" #component />\n }\n </div>\n </ng-container>\n}\n\n","import { 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 { FieldProperties } from '@decaf-ts/ui-decorators';\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: FormGroup | 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 IComponentInput\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 IComponentInput extends FieldProperties {\n updateMode?: FieldUpdateMode;\n formGroup?: FormGroup;\n formControl?: FormControl;\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 {IComponentInput} 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: IComponentInput;\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 instance?: Type<unknown>;\n formGroup?: FormGroup;\n formControl?: FormControl;\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 BaseCustomEvent 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 BaseCustomEvent)\n * @property {HTMLElement} [target] - The target element (inherited from BaseCustomEvent)\n * @property {string} [name] - The name of the event (inherited from BaseCustomEvent)\n * @property {string} component - The component that triggered the event (inherited from BaseCustomEvent)\n * @memberOf module:engine\n */\nexport interface ListItemCustomEvent extends BaseCustomEvent {\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 BaseCustomEvent\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 BaseCustomEvent {\n name: string;\n component: string;\n data?: unknown;\n target?: HTMLElement;\n}\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","import {\n Input,\n Component,\n Inject,\n ViewChild,\n ElementRef,\n OnChanges,\n SimpleChanges,\n Output,\n EventEmitter,\n} from '@angular/core';\nimport { KeyValue, RendererCustomEvent, StringOrBoolean } from './types';\nimport {\n generateRandomValue,\n getInjectablesRegistry,\n getLocaleFromClassName,\n getOnWindow,\n isDevelopmentMode,\n stringToBoolean\n} from '../helpers/utils';\nimport { Model } from '@decaf-ts/decorator-validation';\nimport {\n CrudOperations,\n InternalError,\n OperationKeys\n} from '@decaf-ts/db-decorators';\nimport { BaseComponentProps } from './constants';\nimport { NgxRenderingEngine } from './NgxRenderingEngine';\nimport { Logger } from '@decaf-ts/logging';\nimport { getLogger } from '../for-angular.module';\nimport { DecafRepository } from '../components/list/constants';\nimport { Repository } from '@decaf-ts/core';\nimport { RamAdapter } from '@decaf-ts/core/ram';\nimport { addIcons } from 'ionicons';\n\n/**\n * @description Base component class that provides common functionality for all Decaf components.\n * @summary The NgxBaseComponent serves as the foundation for all Decaf UI components, providing\n * shared functionality for localization, element references, and styling. This abstract class\n * implements common properties and methods that are used across the component library, ensuring\n * consistent behavior and reducing code duplication. Components that extend this class inherit\n * its capabilities for handling translations, accessing DOM elements, and applying custom styling.\n *\n * @template M - The model type that this component works with\n * @param {string} instance - The component instance token used for identification\n * @param {string} locale - The locale to be used for translations\n * @param {StringOrBoolean} translatable - Whether the component should be translated\n * @param {string} className - Additional CSS classes to apply to the component\n * @param {\"ios\" | \"md\" | undefined} mode - Component platform style\n *\n * @component NgxBaseComponent\n * @example\n * ```typescript\n * @Component({\n * selector: 'app-my-component',\n * templateUrl: './my-component.component.html',\n * styleUrls: ['./my-component.component.scss']\n * })\n * export class MyComponent extends NgxBaseComponent {\n * constructor(@Inject('instanceToken') instance: string) {\n * super(instance);\n * }\n *\n * ngOnInit() {\n * this.initialize();\n * // Component-specific initialization\n * }\n * }\n * ```\n * @mermaid\n * sequenceDiagram\n * participant App as Application\n * participant Comp as Component\n * participant Base as NgxBaseComponent\n * participant Engine as NgxRenderingEngine\n *\n * App->>Comp: Create component\n * Comp->>Base: super(instance)\n * Base->>Base: Set componentName & componentLocale\n *\n * App->>Comp: Set @Input properties\n * Comp->>Base: ngOnChanges(changes)\n *\n * alt model changed\n * Base->>Base: getModel(model)\n * Base->>Engine: getDecorators(model, {})\n * Engine-->>Base: Return decorator metadata\n * Base->>Base: Configure mapper and item\n * Base->>Base: getLocale(translatable)\n * else locale/translatable changed\n * Base->>Base: getLocale(translatable)\n * end\n *\n * App->>Comp: ngOnInit()\n * Comp->>Base: initialize()\n * Base->>Base: Set initialized flag\n */\n@Component({\n standalone: true,\n template: '<div><div>',\n host: {'[attr.id]': 'uid'},\n})\nexport abstract class NgxBaseComponent implements OnChanges {\n /**\n * @description Reference to the component's 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 *\n * @type {ElementRef}\n * @memberOf NgxBaseComponent\n */\n @ViewChild('component', { read: ElementRef, static: true })\n component!: ElementRef;\n\n /**\n * @description The name of the component.\n * @summary Stores the name of the component, which is typically derived from the class name.\n * This property is used internally for various purposes such as logging, deriving the default\n * locale, and potentially for component identification in debugging or error reporting.\n *\n * The `componentName` is set during the component's initialization process and should not\n * be modified externally. It's marked as protected to allow access in derived classes while\n * preventing direct access from outside the component hierarchy.\n *\n * @type {string}\n * @protected\n * @memberOf NgxBaseComponent\n *\n * @example\n * // Inside a derived component class\n * console.log(this.componentName); // Outputs: \"MyCustomComponent\"\n */\n componentName!: string;\n\n /**\n * @description Unique identifier for the renderer.\n * @summary A unique identifier used to reference the component's renderer instance.\n * This can be used for targeting specific renderer instances when multiple components\n * are present on the same page.\n *\n * @type {string}\n * @memberOf NgxBaseComponent\n */\n @Input()\n rendererId!: string;\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 NgxBaseComponent\n */\n @Input()\n model!: Model | undefined;\n\n /**\n * @description The repository for interacting with the data model.\n * @summary Provides a connection to the data layer for retrieving and manipulating data.\n * This is an instance of the `DecafRepository` class from the `@decaf-ts/core` package,\n * which is initialized in the `repository` getter method.\n *\n * The repository is used to perform CRUD (Create, Read, Update, Delete) operations on the\n * data model, such as fetching data, creating new items, updating existing items, and deleting\n * items. It also provides methods for querying and filtering data based on specific criteria.\n *\n * @type {DecafRepository<Model>}\n * @private\n * @memberOf NgxBaseComponent\n */\n protected _repository?: DecafRepository<Model>;\n\n /**\n * @description Dynamic properties configuration object.\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 *\n * @type {Record<string, unknown>}\n * @default {}\n * @memberOf NgxBaseComponent\n */\n @Input()\n props: Record<string, unknown> = {};\n\n /**\n * @description Configuration for list item rendering\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 *\n * @type {Record<string, unknown>}\n * @default {tag: \"\"}\n * @memberOf NgxBaseComponent\n */\n @Input()\n item: Record<string, unknown> = { tag: '' };\n\n /**\n * @description Primary key field name for the 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 *\n * @type {string}\n * @default 'id'\n * @memberOf NgxBaseComponent\n */\n @Input()\n pk!: string;\n\n /**\n * @description Base route for navigation related to this component.\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.\n *\n * @type {string}\n * @memberOf NgxBaseComponent\n */\n @Input()\n route!: string;\n\n /**\n * @description Available CRUD operations for this component.\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.\n *\n * @default [OperationKeys.READ]\n * @memberOf NgxBaseComponent\n */\n @Input()\n operations: CrudOperations[] = [OperationKeys.READ];\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 * @memberOf NgxBaseComponent\n */\n @Input()\n uid!: string | number;\n\n /**\n * @description Field mapping configuration.\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 *\n * @type {Record<string, string>}\n * @memberOf NgxBaseComponent\n */\n @Input()\n mapper: Record<string, string> = {};\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 NgxBaseComponent\n */\n @Input()\n locale!: string;\n\n /**\n * @description Determines if the component should be translated.\n * @summary Controls whether the component's text content should be processed for translation.\n * When true, the component will attempt to translate text using the specified locale.\n * When false, text is displayed as-is without translation. This property accepts either\n * a boolean value or a string that can be converted to a boolean (e.g., 'true', 'false', '1', '0').\n *\n * @type {StringOrBoolean}\n * @default false\n * @memberOf NgxBaseComponent\n */\n @Input()\n translatable: StringOrBoolean = true;\n\n /**\n * @description Additional CSS class names to apply to the component.\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 *\n * @type {string}\n * @default \"\"\n * @memberOf NgxBaseComponent\n */\n @Input()\n className: string = '';\n\n /**\n * @description Component platform style.\n * @summary Controls the visual appearance of the component based on platform design guidelines.\n * The 'ios' mode follows iOS design patterns, while 'md' (Material Design) follows Android/Google\n * design patterns. This property affects various visual aspects such as animations, form elements,\n * and icons. Setting this property allows components to maintain platform-specific styling\n * for a more native look and feel.\n *\n * @type {(\"ios\" | \"md\" | undefined)}\n * @default \"md\"\n * @memberOf NgxBaseComponent\n */\n @Input()\n mode: 'ios' | 'md' | undefined = 'md';\n\n /**\n * @description The locale derived from the component's class name.\n * @summary Stores the automatically derived locale based on the component's class name.\n * This is determined during component initialization and serves as a fallback when no\n * explicit locale is provided via the locale input property. The derivation is handled\n * by the getLocaleFromClassName utility function, which extracts a locale identifier\n * from the component's class name.\n *\n * @type {string}\n * @memberOf NgxBaseComponent\n */\n componentLocale!: string;\n\n /**\n * @description Controls whether child components should be rendered\n * @summary Determines if child components should be rendered by the component.\n * This can be set to a boolean value or a string that can be converted to a boolean.\n * When true, child components defined in the model will be rendered. When false,\n * child components will be skipped. This provides control over the rendering depth.\n *\n * @type {string | StringOrBoolean}\n * @default true\n * @memberOf NgxBaseComponent\n */\n @Input()\n renderChild: string | StringOrBoolean = true;\n\n /**\n * @description Flag indicating if the component has been initialized\n * @summary Tracks whether the component has completed its initialization process.\n * This flag is used to prevent duplicate initialization and to determine if\n * certain operations that require initialization can be performed.\n *\n * @type {boolean}\n * @default false\n */\n initialized: boolean = false;\n\n /**\n * @description Event emitter for custom renderer events.\n * @summary Emits custom events that occur within child components or the layout itself.\n * This allows parent components to listen for and respond to user interactions or\n * state changes within the grid layout. Events are passed up the component hierarchy\n * to enable coordinated behavior across the application.\n *\n * @type {EventEmitter<RendererCustomEvent>}\n * @memberOf NgxBaseComponent\n */\n @Output()\n listenEvent: EventEmitter<RendererCustomEvent> = new EventEmitter<RendererCustomEvent>();\n\n /**\n * @description Reference to the rendering engine instance\n * @summary Provides access to the NgxRenderingEngine singleton instance,\n * which handles the rendering of components based on model definitions.\n * This engine is used to extract decorator metadata and render child components.\n *\n * @type {NgxRenderingEngine}\n */\n renderingEngine: NgxRenderingEngine =\n NgxRenderingEngine.get() as unknown as NgxRenderingEngine;\n\n /**\n * @description Logger instance for the component.\n * @summary Provides logging capabilities for the component, allowing for consistent\n * and structured logging of information, warnings, and errors. This logger is initialized\n * in the ngOnInit method using the getLogger function from the ForAngularModule.\n *\n * The logger is used throughout the component to record important events, debug information,\n * and potential issues. It helps in monitoring the component's behavior, tracking the flow\n * of operations, and facilitating easier debugging and maintenance.\n *\n * @type {Logger}\n * @private\n * @memberOf NgxBaseComponent\n */\n logger!: Logger;\n\n /**\n * @description Creates an instance of NgxBaseComponent.\n * @summary Initializes a new instance of the base component with the provided instance token.\n * This constructor sets up the fundamental properties required by all Decaf components,\n * including the component name, locale settings, and logging capabilities. The instance\n * token is used for component identification and locale derivation.\n *\n * The constructor performs the following initialization steps:\n * 1. Sets the componentName from the provided instance token\n * 2. Derives the componentLocale from the class name using utility functions\n * 3. Initializes the logger instance for the component\n *\n * @param {string} instance - The component instance token used for identification\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular\n * participant C as Component\n * participant B as NgxBaseComponent\n * participant U as Utils\n * participant L as Logger\n *\n * A->>C: new Component(instance)\n * C->>B: super(instance)\n * B->>B: Set componentName = instance\n * B->>U: getLocaleFromClassName(instance)\n * U-->>B: Return derived locale\n * B->>B: Set componentLocale\n * B->>L: getLogger(this)\n * L-->>B: Return logger instance\n * B->>B: Set logger\n *\n * @memberOf NgxBaseComponent\n */\n // eslint-disable-next-line @angular-eslint/prefer-inject\n protected constructor(@Inject('instanceToken') protected instance: string, @Inject('iconsToken') icons: KeyValue = {}) {\n if(Object.keys(icons).length)\n addIcons(icons);\n this.componentName = instance;\n this.componentLocale = getLocaleFromClassName(instance);\n this.logger = getLogger(this);\n this.getLocale(this.translatable);\n this.uid = generateRandomValue(12);\n }\n\n /**\n * @description Getter for the repository instance.\n * @summary Provides a connection to the data layer for retrieving and manipulating data.\n * This method initializes the `_repository` property if it is not already set, ensuring\n * that a single instance of the repository is used throughout the component.\n *\n * The repository is used to perform CRUD operations on the data model, such as fetching data,\n * creating new items, updating existing items, and deleting items. It also provides methods\n * for querying and filtering data based on specific criteria.\n *\n * @returns {DecafRepository<Model>} The initialized repository instance.\n * @private\n * @memberOf NgxBaseComponent\n */\n protected get repository(): DecafRepository<Model> {\n try {\n if (!this._repository) {\n const modelName = (this.model as Model).constructor.name\n const constructor = Model.get(modelName);\n if (!constructor)\n throw new InternalError(\n 'Cannot find model. was it registered with @model?',\n );\n let dbAdapterFlavour = getOnWindow('dbAdapterFlavour');\n if(!dbAdapterFlavour && isDevelopmentMode()) {\n const adapter = new RamAdapter();\n dbAdapterFlavour = adapter.flavour;\n }\n this._repository = Repository.forModel(constructor, dbAdapterFlavour as string);\n this.model = new constructor() as Model;\n if(this.model && !this.pk)\n this.pk = (this._repository as unknown as DecafRepository<Model>).pk || 'id';\n }\n } catch (error: unknown) {\n throw new InternalError(\n (error as Error)?.message || error as string\n );\n }\n return this._repository;\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 *\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 *\n * @param {KeyValue} instance - The component instance object to process\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant B as NgxBaseComponent\n * participant P as Props Object\n *\n * C->>B: parseProps(instance)\n * B->>B: Get Object.keys(instance)\n * loop For each key in instance\n * B->>P: Check if key exists in this.props\n * alt Key exists in props\n * B->>B: Set this[key] = this.props[key]\n * else Key not in props\n * Note over B: Skip this key\n * end\n * end\n *\n * @protected\n * @memberOf NgxBaseComponent\n */\n protected parseProps(instance: KeyValue): void {\n Object.keys(instance).forEach((key) => {\n if(Object.keys(this.props).includes(key))\n (this as KeyValue)[key] = this.props[key];\n })\n }\n\n /**\n * @description Handles changes to component inputs\n * @summary This Angular lifecycle hook is called when input properties change.\n * It responds to changes in the model, locale, or translatable properties by\n * updating the component's internal state accordingly. When the model changes,\n * it calls getModel to process the new model and getLocale to update the locale.\n * When locale or translatable properties change, it calls getLocale to update\n * the translation settings.\n *\n * @param {SimpleChanges} changes - Object containing changed properties\n * @return {void}\n */\n ngOnChanges(changes: SimpleChanges): void {\n if (changes[BaseComponentProps.MODEL]) {\n const { currentValue } = changes[BaseComponentProps.MODEL];\n if (currentValue) this.getModel(currentValue);\n this.getLocale(this.translatable);\n }\n if (\n changes[BaseComponentProps.INITIALIZED] ||\n changes[BaseComponentProps.LOCALE] ||\n changes[BaseComponentProps.TRANSLATABLE]\n )\n this.getLocale(this.translatable);\n }\n\n /**\n * @description Gets the appropriate locale string based on the translatable flag and available locales.\n * @summary Determines which locale string to use for translation based on the translatable flag\n * and available locale settings. This method first converts the translatable parameter to a boolean\n * using the stringToBoolean utility function. If translatable is false, it returns an empty string,\n * indicating no translation should be performed. If translatable is true, it checks for an explicitly\n * provided locale via the locale property. If no explicit locale is available, it falls back to the\n * componentLocale derived from the component's class name.\n *\n * @param {StringOrBoolean} translatable - Whether the component should be translated\n * @return {string} The locale string to use for translation, or empty string if not translatable\n *\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant N as NgxBaseComponent\n * participant S as StringUtils\n *\n * C->>N: getLocale(translatable)\n * N->>S: stringToBoolean(translatable)\n * S-->>N: Return boolean value\n * N->>N: Store in this.translatable\n * alt translatable is false\n * N-->>C: Return empty string\n * else translatable is true\n * alt this.locale is defined\n * N-->>C: Return this.locale\n * else this.locale is not defined\n * N-->>C: Return this.componentLocale\n * end\n * end\n */\n getLocale(translatable: StringOrBoolean): string {\n this.translatable = stringToBoolean(translatable);\n if (!this.translatable)\n return '';\n if (!this.locale)\n this.locale = this.componentLocale;\n return this.locale;\n }\n\n /**\n * @description Gets the route for the component\n * @summary Retrieves the route path for the component, generating one based on the model\n * if no route is explicitly set. This method checks if a route is already defined, and if not,\n * it creates a default route based on the model's constructor name. The generated route follows\n * the pattern '/model/{ModelName}'. This is useful for automatic routing in CRUD operations.\n *\n * @return {string} The route path for the component, or empty string if no route is available\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 sets the component's model\n * @summary Processes the provided model parameter, which can be either a Model instance\n * or a string identifier. If a string is provided, it attempts to resolve the actual model\n * from the injectables registry. After resolving the model, it calls setModelDefinitions\n * to configure the component based on the model's metadata.\n *\n * @param {string | Model} model - The model instance or identifier string\n * @return {void}\n */\n getModel(model: string | Model): void {\n if (!(model instanceof Model))\n this.model = getInjectablesRegistry().get(model) as Model;\n this.setModelDefinitions(this.model as Model);\n }\n\n /**\n * @description Configures component properties based on model metadata\n * @summary Extracts and applies configuration from the model's decorators to set up\n * the component. This method uses the rendering engine to retrieve decorator metadata\n * from the model, then configures the component's mapper and item properties accordingly.\n * It ensures the route is properly set and merges various properties from the model's\n * metadata into the component's configuration.\n *\n * @param {Model} model - The model to extract configuration from\n * @return {void}\n */\n setModelDefinitions(model: Model): void {\n if (model instanceof Model) {\n this.getRoute();\n this.model = model;\n const field = this.renderingEngine.getDecorators(this.model as Model, {});\n const{ props, item, children } = field;\n this.props = Object.assign(props || {}, {children: children || []});\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 };\n }\n }\n\n /**\n * @description Initializes the component\n * @summary Performs one-time initialization of the component. This method checks if\n * the component has already been initialized to prevent duplicate initialization.\n * When called for the first time, it sets the initialized flag to true and logs\n * an initialization message with the component name. This method is typically called\n * during the component's lifecycle setup.\n */\n initialize(): void {\n this.initialized = true;\n }\n\n /**\n * @description Handles custom events from child components.\n * @summary Receives events from child renderer components and forwards them to parent\n * components through the listenEvent output. This creates an event propagation chain\n * that allows events to bubble up through the component hierarchy, enabling coordinated\n * responses to user interactions across the layout structure.\n *\n * @param {RendererCustomEvent} event - The custom event from a child component\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant C as Child Component\n * participant L as NgxBaseComponent\n * participant P as Parent Component\n *\n * C->>L: Emit RendererCustomEvent\n * L->>L: handleEvent(event)\n * L->>P: listenEvent.emit(event)\n * Note over P: Handle event in parent\n *\n * @memberOf NgxBaseComponent\n */\n handleEvent(event: RendererCustomEvent): void {\n this.listenEvent.emit(event);\n }\n\n /**\n * @description Tracks items in ngFor loops for optimal change detection.\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 *\n * @param {number} index - The index of the item in the list\n * @param {KeyValue | string | number} item - The item data to track\n * @returns {string | number} A unique identifier for the item\n * @memberOf NgxBaseComponent\n */\n trackItemFn(index: number, item: KeyValue | string | number): string | number {\n return `${index}-${item}`;\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 './NgxBaseComponent';\nexport * from './NgxCrudFormField';\nexport * from './NgxFormService';\n","import { CrudFormOptions } from './types';\n\nexport const CssClasses = {\n BUTTONS_CONTAINER: 'buttons-container',\n};\n\nexport const DefaultFormReactiveOptions: CrudFormOptions = {\n buttons: {\n submit: {\n text: 'Submit',\n },\n clear: {\n text: 'Clear',\n },\n },\n};\n","import {\n Component,\n ElementRef,\n EventEmitter,\n inject,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ViewChild,\n} from '@angular/core';\nimport { Location } from '@angular/common';\nimport { FormGroup } from '@angular/forms';\nimport { IFormElement } from '../../engine/interfaces';\nimport { NgxFormService } from '../../engine/NgxFormService';\nimport { CrudFormEvent, Dynamic, EventConstants, FieldUpdateMode, HandlerLike, HTMLFormTarget, RenderedModel } from '../../engine';\nimport { CrudFormOptions } from './types';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport { DefaultFormReactiveOptions } from './constants';\nimport { ForAngularModule, getLogger } from '../../for-angular.module';\nimport { IonIcon } from '@ionic/angular/standalone';\nimport { Model } from '@decaf-ts/decorator-validation';\nimport { Logger } from '@decaf-ts/logging';\nimport { generateRandomValue } from '../../helpers';\n\n\n/**\n * @component CrudFormComponent\n * @example <ngx-decaf-crud-form\n * action=\"create\"\n * operation=\"create\"\n * formGroup=\"formGroup\"\n * rendererId=\"rendererId\"\n * submitEvent=\"submitEvent\"\n * target=\"_self\"\n * method=\"event\">\n * </ngx-decaf-crud-form>\n *\n * @param {string} action - The action to be performed (create, read, update, delete)\n * @param {CrudOperations} operation - The CRUD operation being performed (create, read, update, delete)\n * @param {FormGroup} formGroup - The form group\n * @param {string} rendererId - The renderer id\n * @param {SubmitEvent} submitEvent - The submit event\n * @param {string} target - The target\n * @param {string} method - The method\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: [ForAngularModule, IonIcon],\n host: {'[attr.id]': 'uid'},\n})\nexport class CrudFormComponent implements OnInit, IFormElement, OnDestroy, RenderedModel {\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 CrudFormComponent\n */\n @Input()\n model!: Model | undefined;\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 * @memberOf CrudFormComponent\n */\n @Input()\n updateOn: FieldUpdateMode = 'change';\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 * @memberOf CrudFormComponent\n */\n @ViewChild('reactiveForm', { static: false, read: ElementRef })\n component!: ElementRef;\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 * @memberOf CrudFormComponent\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 * @memberOf CrudFormComponent\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 {CrudFormOptions}\n * @memberOf CrudFormComponent\n */\n @Input()\n options!: CrudFormOptions;\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 * @memberOf CrudFormComponent\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 * @memberOf CrudFormComponent\n */\n @Input({ required: true })\n operation!: CrudOperations;\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 * @memberOf CrudFormComponent\n */\n @Input()\n handlers!: HandlerLike;\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 * @memberOf CrudFormComponent\n */\n @Input()\n formGroup!: FormGroup | undefined;\n\n /**\n * @description Path to the parent FormGroup, if nested.\n * @summary Full dot-delimited path of the parent FormGroup. Set only when is part of a nested structure.\n *\n * @type {string}\n * @memberOf CrudFormComponent\n */\n @Input()\n childOf?: string;\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 * @memberOf CrudFormComponent\n */\n @Input()\n rendererId!: string;\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 * @memberOf CrudFormComponent\n */\n @Input()\n uid: string = generateRandomValue(12);\n\n\n /**\n * @description Event emitter for form submission events.\n * @summary Emits CrudFormEvent 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<CrudFormEvent>}\n * @memberOf CrudFormComponent\n */\n @Output()\n submitEvent: EventEmitter<CrudFormEvent> = new EventEmitter<CrudFormEvent>();\n\n /**\n * @description Logger instance for the component.\n * @summary Provides logging capabilities for the component, allowing for consistent\n * and structured logging of information, warnings, and errors. This logger is initialized\n * in the ngOnInit method using the getLogger function from the ForAngularModule.\n *\n * The logger is used throughout the component to record important events, debug information,\n * and potential issues. It helps in monitoring the component's behavior, tracking the flow\n * of operations, and facilitating easier debugging and maintenance.\n *\n * @type {Logger}\n * @private\n * @memberOf CrudFormComponent\n */\n private logger!: Logger;\n\n /**\n * @description Angular Location service.\n * @summary Injected service that provides access to the browser's URL and history.\n * This service is used for interacting with the browser's history API, allowing\n * for back navigation and URL manipulation outside of Angular's router.\n *\n * @private\n * @type {Location}\n * @memberOf CrudFormComponent\n */\n private location: Location = inject(Location);\n\n // ngAfterViewInit() {\n // if (![OperationKeys.READ, OperationKeys.DELETE].includes(this.operation))\n // NgxFormService.formAfterViewInit(this, this.rendererId);\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 async ngOnInit() {\n if (!this.logger)\n this.logger = getLogger(this);\n if (this.operation === OperationKeys.READ || this.operation === OperationKeys.DELETE)\n this.formGroup = undefined;\n this.options = Object.assign(\n {},\n DefaultFormReactiveOptions,\n this.options || {},\n );\n\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 * @memberOf CrudFormComponent\n */\n ngOnDestroy() {\n if (this.formGroup)\n NgxFormService.unregister(this.formGroup);\n }\n\n /**\n * @description Handles form submission with validation and event emission.\n * @summary Processes form submission by first preventing default browser behavior,\n * then validating all form fields using NgxFormService. If validation passes,\n * extracts form data and emits a submitEvent with the data, component information,\n * and any associated handlers. Returns false if validation fails.\n *\n * @param {SubmitEvent} event - The browser's native form submit event\n * @returns {Promise<boolean | void>} Returns false if validation fails, void if successful\n * @memberOf CrudFormComponent\n */\n async submit(event: SubmitEvent): Promise<boolean | void> {\n event.preventDefault();\n event.stopImmediatePropagation();\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: 'CrudFormComponent',\n name: this.action || EventConstants.SUBMIT,\n handlers: this.handlers,\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 * @memberOf CrudFormComponent\n */\n handleReset(): void {\n if(![OperationKeys.DELETE, OperationKeys.READ].includes(this.operation))\n return NgxFormService.reset(this.formGroup as FormGroup);\n this.location.back();\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.uid,\n component: 'CrudFormComponent',\n name: EventConstants.SUBMIT,\n });\n }\n\n /**\n * @description Reference to CRUD operation constants for template usage.\n * @summary Exposes the OperationKeys enum to the component template, enabling\n * conditional rendering and behavior based on operation types. This protected\n * readonly property ensures that template logic can access operation constants\n * while maintaining encapsulation and preventing accidental modification.\n *\n * @type {CrudOperations}\n * @protected\n * @readonly\n * @memberOf CrudFormComponent\n */\n protected readonly OperationKeys = OperationKeys;\n}\n","@if(operation !== 'read' && operation !== 'delete') {\n <form #reactiveForm [id]=\"rendererId\" [formGroup]=\"formGroup\" (submit)=\"submit($event)\" novalidate [target]=\"target\">\n <ng-content #formContent></ng-content>\n <div class=\"dcf-buttons-container dcf-grid dcf-grid-collapse dcf-flex dcf-flex-left\">\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 {{ action ? action : options.buttons.submit.text}}\n </ion-button>\n </div>\n <div>\n @if(options.buttons.clear) {\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 {{ ['create', 'update'].includes(operation) ? 'Back' : options.buttons.clear?.text}}\n </ion-button>\n }\n </div>\n </div>\n </form>\n} @else {\n <div [class]=\"'dcf-buttons-container dcf-grid dcf-grid-collapse dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n\n @if(operation === 'delete' && uid) {\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 <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 {{ ['delete', 'read', 'update'].includes(operation) ? 'Back' : options.buttons.clear?.text}}\n </ion-button>\n </div>\n\n }\n </div>\n}\n\n","import { Component, inject, Input, OnInit } from '@angular/core';\nimport { Color, PredefinedColors } from '@ionic/core';\nimport {\n IonCard,\n IonCardContent,\n IonIcon,\n IonTitle,\n NavController\n}\nfrom '@ionic/angular/standalone';\nimport * as allIcons from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { Dynamic, StringOrBoolean } from '../../engine';\nimport { stringToBoolean } from '../../helpers';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { TranslateService } from '@ngx-translate/core';\nimport { FunctionLike } from '../../engine/types';\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 * +PredefinedColors iconColor\n * +string|Function buttonLink\n * +string buttonText\n * +string buttonFill\n * +Color buttonColor\n * +string buttonSize\n * +string searchValue\n * -NavController navController\n * +ngOnInit()\n * +handleClick()\n * }\n * EmptyStateComponent --|> NgxBaseComponent\n * EmptyStateComponent --|> OnInit\n *\n * @extends {NgxBaseComponent}\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 ForAngularModule,\n IonCard,\n IonCardContent,\n IonTitle,\n IonIcon\n ]\n\n})\nexport class EmptyStateComponent extends NgxBaseComponent implements OnInit {\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 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 = '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 subtitle: string = \"\";\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 \"ti-info-square-rounded\"\n * @memberOf EmptyStateComponent\n */\n @Input()\n icon: string = \"ti-info-square-rounded\";\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?: 'large' | 'small' = '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 {PredefinedColors | undefined}\n * @default 'medium'\n * @memberOf EmptyStateComponent\n */\n @Input()\n iconColor?: PredefinedColors = '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 {Color}\n * @default 'primary'\n * @memberOf EmptyStateComponent\n */\n @Input()\n buttonColor: Color = '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: '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 * @description Service for handling navigation operations.\n * @summary Injected service that provides methods for navigating between routes.\n * This service is used when the buttonLink is a string URL to navigate to that location.\n *\n * @private\n * @type {NavController}\n * @memberOf EmptyStateComponent\n */\n private navController: NavController = inject(NavController);\n\n private sanitizer: DomSanitizer = inject(DomSanitizer);\n\n private translate: TranslateService = inject(TranslateService);\n\n searchSubtitle!: SafeHtml\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 addIcons(allIcons);\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 async ngOnInit(): Promise<void> {\n this.parseProps(this);\n this.translatable = stringToBoolean(this.translatable);\n this.showIcon = stringToBoolean(this.showIcon);\n this.locale = this.getLocale(this.translatable);\n\n // if(this.translatable) {\n // this.title = generateLocaleFromString(this.locale, this.title);\n // this.subtitle = generateLocaleFromString(this.locale, this.subtitle);\n // this.buttonText = generateLocaleFromString(this.locale, this.buttonText);\n // }\n\n this.titleColor = `dcf-title color-${this.titleColor}`;\n this.subtitleColor = `dcf-subtitle color-${this.titleColor}`;\n\n if(this.searchValue && this.translatable)\n this.searchSubtitle = await this.getSearchSubtitle(this.subtitle as string);\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 NavController\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>}\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> {\n const fn = this.buttonLink;\n if(!fn)\n return false;\n if(fn instanceof Function)\n return fn();\n return this.navController.navigateForward(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 ('value0') 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, {'value0': 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.instant(content, {'value0': this.searchValue});\n return this.sanitizer.bypassSecurityTrustHtml(result);\n }\n}\n","\n<ion-card [id]=\"uid\" [ngClass]=\"className\">\n <ion-card-content>\n @if(icon && showIcon) {\n <div class=\"dcf-icon-container\">\n <ion-icon\n name=\"alert-circle-outline\"\n size=\"large\"\n color=\"danger\"\n />\n </div>\n }\n @if(title) {\n <h5 [class]=\"titleColor\" [innerHTML]=\"title\"></h5>\n }\n @if(subtitle) {\n @if(!searchValue) {\n <p [class]=\"subtitleColor\" [innerHTML]=\"subtitle\"></p>\n } @else {\n <p [class]=\"subtitleColor\" [innerHTML]=\"searchSubtitle\"></p>\n }\n }\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 </ion-card-content>\n</ion-card>\n","import { Directive, ElementRef, inject, OnInit, Injector } from '@angular/core';\n\n\n@Directive({\n selector: '[decafCollapsable]',\n standalone: true\n})\nexport class CollapsableDirective implements OnInit{\n\n private element: ElementRef<HTMLElement> = inject(ElementRef);\n private injector = inject(Injector);\n // constructor() {}\n\n ngOnInit() {\n const element = this.element?.nativeElement;\n if(element) {\n const requiredFields = element.querySelectorAll('[required]') as NodeListOf<Element>;\n if(requiredFields.length) {\n const accordion = element?.closest('ion-accordion-group') as HTMLElement;\n accordion.setAttribute('value', 'open');\n }\n }\n }\n\n // private element: ElementRef<HTMLElement> = inject(ElementRef);\n // private renderer = inject(Renderer2);\n\n // ngOnInit() {\n // const element = this.element?.nativeElement;\n // if(element) {\n // const requiredFields = element.querySelectorAll('[required]') as NodeListOf<Element>;\n\n // // Find the parent fieldset component and set required attribute if there are required fields\n // const fieldsetElement = element.closest('ngx-decaf-fieldset');\n // if (fieldsetElement && requiredFields.length > 0) {\n // // Set a data attribute that the fieldset component can read\n // this.renderer.setAttribute(fieldsetElement, 'data-has-required-fields', 'true');\n\n // // Dispatch a custom event to notify the fieldset component\n // const event = new CustomEvent('requiredFieldsDetected', {\n // detail: { hasRequiredFields: true, count: requiredFields.length },\n // bubbles: true\n // });\n // fieldsetElement.dispatchEvent(event);\n\n // const accordion = element?.closest('ion-accordion-group') as HTMLElement;\n // if (accordion) {\n // accordion.setAttribute('value', 'open');\n // }\n // }\n // }\n // }\n}\n","\nimport { AfterViewInit, ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, inject, Input, ViewChild, Renderer2, OnInit } from '@angular/core';\nimport { Dynamic, EventConstants, HandlerLike, HTMLFormTarget, KeyValue } from '../../engine';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { CollapsableDirective } from '../../directives/collapsable.directive';\nimport { IonAccordion, IonAccordionGroup, IonButton, IonItem, IonLabel, IonList, ItemReorderEventDetail, IonReorderGroup, IonReorder } from '@ionic/angular/standalone';\nimport { cleanSpaces, generateRandomValue, itemMapper, windowEventEmitter } from '../../helpers';\nimport { FormArray, FormControl, FormGroup } from '@angular/forms';\nimport { NgxBaseComponent } from '../../engine';\nimport { alertCircleOutline, createOutline } from 'ionicons/icons';\nimport { TranslateService } from '@ngx-translate/core';\nimport { IFieldSetItem, IFieldSetValidationEvent } from '../../engine/interfaces';\n\n\n\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 ForAngularModule\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: [CUSTOM_ELEMENTS_SCHEMA],\n imports: [ForAngularModule, IonAccordionGroup, IonAccordion, IonList, IonItem, IonLabel, IonReorder, IonButton, IonReorderGroup, CollapsableDirective],\n host: {'[attr.id]': 'overriode '},\n})\nexport class FieldsetComponent extends NgxBaseComponent implements OnInit, AfterViewInit {\n\n\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 /**\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 name: string = 'Child';\n\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 childOf: string = 'Child';\n\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 override uid: string = generateRandomValue(12);\n\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 The current CRUD operation context.\n * @summary Determines the component's initial behavior and state based on the current operation.\n * This input is crucial for auto-state management: READ and DELETE operations automatically\n * open the fieldset to show content, while CREATE and UPDATE operations keep it closed\n * initially. This provides an intuitive user experience aligned with operation semantics.\n *\n * @type {OperationKeys}\n * @default OperationKeys.READ\n * @memberOf FieldsetComponent\n */\n /**\n * @description The CRUD operation type for the current fieldset context.\n * @summary Determines the component's initial behavior and state based on the current operation.\n * This input is crucial for auto-state management: READ and DELETE operations automatically\n * open the fieldset to show content, while CREATE and UPDATE operations keep it closed\n * initially. This provides an intuitive user experience aligned with operation semantics.\n *\n * @type {OperationKeys}\n * @default OperationKeys.READ\n * @memberOf FieldsetComponent\n */\n @Input()\n operation: OperationKeys = OperationKeys.READ;\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 * @memberOf FieldsetComponent\n */\n @Input()\n formGroup!: FormArray;\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 Form target attribute for nested form submissions.\n * @summary Specifies where to display the response after submitting forms contained within\n * the fieldset. This attribute mirrors the HTML form target behavior, allowing control over\n * whether form submissions open in the same window, new window, or specific frame. Useful\n * for complex form workflows and multi-step processes.\n *\n * @type {HTMLFormTarget}\n * @default '_self'\n * @memberOf FieldsetComponent\n */\n @Input()\n target: HTMLFormTarget = '_self';\n\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 = false;\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 Event handler functions for custom fieldset actions.\n * @summary A record of event handler functions keyed by event names that can be triggered\n * within the fieldset. These handlers provide extensibility for custom business logic\n * and can be invoked for various fieldset operations and user interactions.\n *\n * @type {HandlerLike}\n * @memberOf FieldsetComponent\n */\n @Input()\n handlers!: HandlerLike;\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 /**\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 Reference to CRUD operation constants for template usage.\n * @summary Exposes the OperationKeys enum to the component template, enabling conditional\n * rendering and behavior based on operation types. This protected readonly property ensures\n * that template logic can access operation constants while maintaining encapsulation and\n * preventing accidental modification of the enum values.\n *\n * @type {CrudOperations}\n * @default OperationKeys.CREATE\n * @memberOf FieldsetComponent\n */\n protected readonly OperationKeys: CrudOperations = OperationKeys.CREATE;\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 * @private\n * @type {ChangeDetectorRef}\n * @memberOf FieldsetComponent\n */\n private 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 * @private\n * @type {Renderer2}\n * @memberOf FieldsetComponent\n */\n private 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 * @private\n * @type {TranslateService}\n * @memberOf FieldsetComponent\n */\n private translateService: TranslateService = inject(TranslateService);\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 Component constructor that initializes the fieldset with icons and component name.\n * @summary Calls the parent NgxBaseComponent 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', {alertCircleOutline, 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 ngOnInit(): void {\n if(this.model)\n this._repository = this.repository;\n this.buttonLabel = this.translateService.instant(this.locale + '.add');\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 {void}\n * @memberOf FieldsetComponent\n */\n ngAfterViewInit(): void {\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(this.accordionComponent)\n this.renderer.setAttribute(accordionElement, 'value', 'open');\n } else {\n const inputs = this.component?.nativeElement.querySelectorAll('[required]');\n this.isRequired = inputs.length > 0;\n if(this.isRequired) {\n this.accordionComponent.value = 'open';\n this.handleAccordionToggle();\n }\n }\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 handleRemoveComponent(event: Event): void {\n event.stopImmediatePropagation();\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 /**\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(event?: CustomEvent<IFieldSetValidationEvent>): Promise<void> {\n if(event && event instanceof CustomEvent) {\n event.stopImmediatePropagation();\n const {formGroup, value, isValid} = event.detail;\n this.formGroup = formGroup as FormArray;\n if(!this.mapper)\n this.mapper = this.getMapper(value as KeyValue);\n if(isValid ){\n this.isUniqueError = undefined;\n this.buttonLabel = this.translateService.instant(this.locale + '.add');\n this.setValue();\n } else {\n this.isUniqueError = (value as KeyValue)?.[this.pk] || undefined;\n }\n } else {\n windowEventEmitter(EventConstants.FIELDSET_ADD_GROUP, {\n component: this.component.nativeElement,\n index: this.value?.length,\n parent: this.childOf,\n operation: !this.updatingItem ? OperationKeys.CREATE : OperationKeys.UPDATE\n });\n }\n }\n\n\n /**\n * @description Handles item update operations with form state management.\n * @summary Locates an item in the form array for editing and prepares the component\n * for update mode. Updates the button label to reflect the edit state and stores\n * the item being updated. Triggers a window event to notify parent components.\n *\n * @param {string | number} value - The identifier value of the item to update\n * @param {number} index - The array index position of the item\n * @returns {void}\n * @memberOf FieldsetComponent\n */\n handleUpdateItem(value: string | number, index: number): void {\n const item = this.formGroup.controls.find(control => `${control.get(this.pk)?.value}`.toLowerCase() === cleanSpaces(`${value}`, true)) as FormControl;\n if(item) {\n this.buttonLabel = this.translateService.instant(this.locale + '.update');\n this.updatingItem = Object.assign({}, item.value || {});\n windowEventEmitter(EventConstants.FIELDSET_UPDATE_GROUP, {\n parent: this.childOf,\n component: this.component.nativeElement,\n index: index\n });\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 windowEventEmitter(EventConstants.FIELDSET_UPDATE_GROUP, {\n parent: this.childOf,\n component: this.component.nativeElement,\n index: this.value?.length\n });\n }\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(value: string | undefined, event?: CustomEvent): void {\n if(event && event instanceof CustomEvent) {\n event.stopImmediatePropagation();\n return this.setValue();\n }\n const formArray = this.formGroup as FormArray;\n const arrayLength = formArray.length;\n for (let index = arrayLength - 1; index >= 0; index--) {\n const group = formArray.at(index) as FormGroup;\n if (cleanSpaces(group.get(this.pk)?.value) === cleanSpaces(value as string)) {\n windowEventEmitter(EventConstants.FIELDSET_REMOVE_GROUP, {\n parent: this.childOf,\n component: this.component.nativeElement,\n index,\n formGroup: group\n });\n }\n }\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]; // sua estrutura visual\n const formArray = this.formGroup as FormArray; // FormArray reativo\n\n if (fromIndex !== toIndex) {\n // Reordenar os dados visuais\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 // Reordenar os controles do FormArray\n const controlToMove = formArray.at(fromIndex);\n formArray.removeAt(fromIndex);\n formArray.insert(toIndex, controlToMove);\n }\n // Finaliza a operação de reorder do Ionic\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)\n event.stopImmediatePropagation();\n if(!this.hasValidationErrors) {\n this.accordionComponent.value = this.isOpen ? undefined : 'open';\n this.isOpen = !!this.accordionComponent.value;\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 {void}\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\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(({value}) => value);\n this.items = this.value\n .filter(v => v[this.pk] !== undefined)\n .map((v, index) => {\n return {\n ...itemMapper(v, this.mapper),\n index: index + 1\n } as IFieldSetItem;\n });\n const inputContainers = this.component.nativeElement.querySelectorAll('.dcf-input-item');\n inputContainers.forEach((container: HTMLElement) => {\n const input = container.querySelector('input, ion-input, ion-textarea, textarea') as HTMLInputElement | null;\n if(input)\n input.value = '';\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)\n this.pk = Object.keys(value)[0];\n if(!Object.keys(this.mapper).length)\n this.mapper['title'] = this.pk;\n this.mapper['index'] = \"index\";\n for(const key in value) {\n if(Object.keys(this.mapper).length >= 2 || Object.keys(this.mapper).length === Object.keys(value).length)\n break;\n if(!this.mapper['title']) {\n this.mapper['title'] = key;\n } else {\n this.mapper['description'] = key;\n }\n }\n return this.mapper;\n }\n}\n","\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n (fieldsetRemoveGroupEvent)=\"handleRemoveItem(undefined, $event)\"\n [class]=\"'dcf-fieldset ' + operation\"\n #component>\n <ion-accordion-group [ngClass]=\"{'open': isOpen, 'hasValidationErrors': hasValidationErrors}\" (validationErrorEvent)=\"handleValidationError($event)\" #accordionComponent>\n <ion-accordion value=\"open\">\n <ion-item slot=\"header\" (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>{{ name | translate }}</legend>\n </div>\n @if(!isRequired && ['create', 'update'].includes(operation)) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleRemoveComponent($event)\">\n <ion-icon name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n </div>\n </ion-item>\n <div slot=\"content\" [attr.aria-hidden]=\"!isOpen\">\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 [ngClass]=\"{'not-unique': item.title === isUniqueError}\" lines=\"full\" [button]=\"false\" [ngClass]=\"{'updating': updatingItem?.[pk] === item.title}\">\n @if(items?.length > 1 && !updatingItem) {\n <ion-reorder slot=\"start\">\n <ion-icon name=\"swap-vertical-outline\"></ion-icon>\n </ion-reorder>\n } @else {\n <div slot=\"start\">\n <ion-icon class=\"dcf-reorder-disabled\" size=\"small\" name=\"swap-vertical-outline\" disabled></ion-icon>\n </div>\n }\n <ion-label [color]=\"item.title === isUniqueError ? '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 @if(!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleUpdateItem(item.title, $index)\">\n <ion-icon name=\"create-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n }\n\n @if(!updatingItem) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleRemoveItem(item.title)\">\n <ion-icon name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n }\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n <ng-content></ng-content>\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 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 <div class=\"dcf-margin-bottom dcf-grid dcf-grid-collapse dcf-flex\">\n @if(updatingItem) {\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ locale + '.cancel' | translate }}\n </ion-button>\n }\n <ion-button size=\"small\" fill=\"clear\" color=\"dark\" (click)=\"handleCreateItem()\">\n <ion-icon name=\"add-outline\" slot=\"start\"></ion-icon>\n {{buttonLabel}}\n </ion-button>\n\n </div>\n }\n\n </div>\n </ion-accordion>\n </ion-accordion-group>\n</fieldset>\n\n","import { Component, EventEmitter, HostListener, Input, OnInit, Output } from '@angular/core';\nimport { AutocompleteTypes, PredefinedColors} from '@ionic/core';\nimport { StringOrBoolean } from '../../engine/types';\nimport {windowEventEmitter} from '../../helpers/utils';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { stringToBoolean } from '../../helpers/utils';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport { IonSearchbar } from '@ionic/angular/standalone';\nimport * as allIcons from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\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 NgxBaseComponent 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 {NgxBaseComponent}\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: [ForAngularModule, IonSearchbar],\n})\nexport class SearchbarComponent extends NgxBaseComponent 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","import { Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport { IonChip, IonIcon, IonItem, IonLabel, IonSelect} from '@ionic/angular/standalone';\nimport { Dynamic, IFilterQuery, IFilterQueryItem } from '../../engine';\nimport { getWindowWidth } from '../../helpers/utils';\nimport { debounceTime, fromEvent, Subscription } from 'rxjs';\nimport { OrderDirection, Repository } from '@decaf-ts/core';\nimport { Model } from '@decaf-ts/decorator-validation';\nimport { SearchbarComponent } from '../searchbar/searchbar.component';\nimport { addIcons } from 'ionicons';\nimport { chevronDownOutline, chevronUpOutline } from 'ionicons/icons';\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 ForAngularModule\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-filter',\n templateUrl: './filter.component.html',\n styleUrls: ['./filter.component.scss'],\n imports: [\n ForAngularModule,\n IonLabel,\n IonItem,\n IonChip,\n IonIcon,\n IonSelect,\n IonIcon,\n SearchbarComponent\n ],\n standalone: true,\n})\nexport class FilterComponent extends NgxBaseComponent 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 * @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, 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 {void}\n * @memberOf FilterComponent\n */\n ngOnInit(): 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(Repository.indexes(this.model as Model) || {});\n if(!this.disableSort)\n this.sortBy = [... this.sortBy, ...this.indexes];\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 ngOnDestroy(): void {\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 }\n this.step++;\n this.value = '';\n if(this.options.length)\n this.handleFocus(this.options);\n this.component.nativeElement.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(): void {\n this.options = this.filteredOptions = this.filterValue = [];\n this.step = 1;\n this.lastFilter = {};\n this.value = '';\n setTimeout(() => {\n this.submit();\n }, 100);\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 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-grid\" [ngClass]=\"{'dcf-hidden': !indexes.length}\">\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 name=\"close\" (click)=\"removeFilter(filter?.['value'])\" size=\"small\"></ion-icon>\n </ion-chip>\n }\n }\n <div class=\"dcf-width-1-1\">\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 [readonly]=\"step !== 3\"\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n #component\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 {{ '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 name=\"trash-outline\" color=\"dark\" 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 name=\"search-outline\" color=\"dark\" 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 {{ '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 >\n @for(sort of sortBy; track sort) {\n aa\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 slot=\"icon-only\" [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","import {\n Component,\n EventEmitter,\n inject,\n Injector,\n Input,\n OnChanges,\n OnDestroy,\n Output,\n SimpleChanges,\n TemplateRef,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport { Model, sf } from '@decaf-ts/decorator-validation';\nimport { NgComponentOutlet } from '@angular/common';\nimport {\n AngularDynamicOutput,\n AngularEngineKeys,\n BaseComponentProps,\n BaseCustomEvent,\n NgxRenderingEngine,\n RenderedModel,\n} from '../../engine';\nimport { KeyValue, RendererCustomEvent } from '../../engine/types';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { Renderable } from '@decaf-ts/ui-decorators';\nimport { ComponentRendererComponent } from '../component-renderer/component-renderer.component';\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: [ForAngularModule, NgComponentOutlet, ComponentRendererComponent],\n selector: 'ngx-decaf-model-renderer',\n templateUrl: './model-renderer.component.html',\n styleUrl: './model-renderer.component.scss',\n host: {'[attr.id]': 'rendererId'},\n})\nexport class ModelRendererComponent<M extends Model>\n implements OnChanges, OnDestroy, RenderedModel {\n\n /**\n * @description Input model to be rendered\n * @summary Can be a Model instance or a JSON string representation of a model\n */\n @Input({ required: true })\n model!: M | string | undefined;\n\n /**\n * @description Global variables to be passed to the rendered component\n */\n @Input()\n globals: Record<string, unknown> = {};\n\n /**\n * @description Template reference for inner content\n */\n @ViewChild('inner', { read: TemplateRef, static: true })\n inner?: TemplateRef<unknown>;\n\n /**\n * @description Output of the rendered model\n */\n output?: AngularDynamicOutput;\n\n /**\n * @description Unique identifier for the renderer\n */\n @Input()\n rendererId?: string;\n\n /**\n * @description View container reference for dynamic component rendering\n */\n @ViewChild('componentOuter', { static: true, read: ViewContainerRef })\n vcr!: ViewContainerRef;\n\n /**\n * @description Event emitter for custom events from the rendered component\n */\n @Output()\n listenEvent = new EventEmitter<RendererCustomEvent>();\n\n /**\n * @description Instance of the rendered component\n */\n private instance!: KeyValue | undefined;\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 );\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?.instance;\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 ngOnChanges(changes: SimpleChanges): void {\n if (changes[BaseComponentProps.MODEL]) {\n const { currentValue } = changes[BaseComponentProps.MODEL];\n this.refresh(currentValue);\n }\n }\n\n /**\n * @description Lifecycle hook that is called when a directive, pipe, or service is destroyed\n * @return {Promise<void>}\n */\n async ngOnDestroy(): Promise<void> {\n if (this.instance) {\n this.unsubscribeEvents();\n await NgxRenderingEngine.destroy();\n }\n this.output = undefined;\n }\n\n private subscribeEvents(): void {\n const component = this?.output?.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((event: Partial<BaseCustomEvent>) => {\n this.listenEvent.emit({\n component: component.name || '',\n name: key,\n ...event,\n } as RendererCustomEvent);\n });\n }\n }\n }\n\n /**\n * @description Unsubscribes from events emitted by the rendered component\n */\n private 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 protected readonly JSON = JSON;\n}\n"," <!-- Keep to avoid id conflicts -->\n <div [id]=\"rendererId\"></div>\n\n <ng-template #componentOuter></ng-template>\n <ng-template #inner>\n <div [id]=\"rendererId || null\">\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","import { Component, Input, OnInit} from '@angular/core';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport { KeyValue } from '../../engine';\nimport { ComponentRendererComponent } from '../component-renderer/component-renderer.component';\nimport { ModelRendererComponent } from '../model-renderer/model-renderer.component';\nimport { UIMediaBreakPoints } from '@decaf-ts/ui-decorators';\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 NgxBaseComponent to inherit common functionality\n * and integrates with the model and component renderer systems.\n *\n * @class LayoutComponent\n * @extends {NgxBaseComponent}\n * @implements {OnInit}\n * @memberOf LayoutComponent\n */\n@Component({\n selector: 'ngx-decaf-layout',\n templateUrl: './layout.component.html',\n styleUrls: ['./layout.component.scss'],\n imports: [ForAngularModule, ModelRendererComponent, ComponentRendererComponent],\n standalone: true,\n\n})\nexport class LayoutComponent extends NgxBaseComponent implements OnInit {\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 * @memberOf LayoutComponent\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 * @memberOf LayoutComponent\n */\n @Input()\n rows: number | KeyValue[] | string[] = 1;\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 {UIMediaBreakPoints}\n * @default 'medium'\n * @memberOf LayoutComponent\n */\n @Input()\n breakpoint: UIMediaBreakPoints = 'medium';\n\n /**\n * @description Array of child components or data to render within the grid.\n * @summary Contains the child elements that will be distributed across the grid layout.\n * Each item in the array represents content that will be rendered using the appropriate\n * renderer component (ModelRenderer or ComponentRenderer). This allows for mixed content\n * types within a single layout structure.\n *\n * @type {KeyValue[]}\n * @default []\n * @memberOf LayoutComponent\n */\n @Input()\n children: KeyValue[] = [];\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 NgxBaseComponent 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 === \"number\")\n cols = Array.from({length: Number(cols)}, () => ``);\n return cols;\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 === \"number\")\n rows = Array.from({length: Number(rows)}, () => ({title: ''}));\n return rows.map((row, index) => {\n return {\n title: (row as KeyValue)?.['title'],\n cols: this.children.filter(child => {\n if(child['row'] === index + 1)\n return child;\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 ngOnInit(): void {\n this.initialize();\n }\n\n /**\n * @description Initializes the layout component with processed properties.\n * @summary Overrides the base component's initialize method to set up the grid layout.\n * This method processes input properties, normalizes the breakpoint value, converts\n * rows and columns to their array representations, and marks the component as initialized.\n * The initialization ensures all properties are in the correct format for rendering.\n *\n * @mermaid\n * sequenceDiagram\n * participant L as LayoutComponent\n * participant B as NgxBaseComponent\n *\n * L->>B: parseProps(this)\n * Note over L: Process component properties\n * L->>L: Normalize breakpoint to lowercase\n * L->>L: Convert rows to array format\n * L->>L: Convert cols to array format\n * L->>L: Set initialized = true\n *\n * @override\n * @memberOf LayoutComponent\n */\n override initialize() {\n this.parseProps(this);\n this.breakpoint = this.breakpoint.slice(0, 2).toLowerCase() as UIMediaBreakPoints;\n this.cols = this._cols;\n this.rows = this._rows;\n this.initialized = true;\n }\n}\n","\n@if(initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n <div [id]=\"uid\" class=\"dcf-grid dcf-grid-collapse dcf-grid-match\">\n @if(row) {\n <div class=\"dcf-width-1-1 dcf-grid-title\">\n <ion-card class=\"dcf-grid-title\">\n {{row.title | translate}}\n </ion-card>\n </div>\n }\n @for (child of row.cols; track trackItemFn($index, child.col); let colIndex = $index) {\n <div [class]=\"(child.col === cols.length ? 'dcf-width-1-1' : 'dcf-width-'+child.col+'-'+cols.length+'@'+breakpoint)\">\n <div [class]=\"'dcf-grid-child '+child.col \">\n @if(child.tag === 'ngx-decaf-crud-form') {\n <ion-card [class]=\"'dcf-height-1-1 ' + className\">\n <ion-card-content>\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ion-card-content>\n </ion-card>\n } @else {\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{props: child.props}\"\n />\n }\n </div>\n </div>\n }\n </div>\n }\n}\n","import { Component, EventEmitter, HostListener, inject, Input, OnInit, Output, ViewChild } from '@angular/core';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport { StringOrBoolean } from '../../engine/types';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { removeFocusTrap, stringToBoolean } from '../../helpers/utils';\nimport { getWindowWidth, windowEventEmitter } from '../../helpers/utils';\nimport { Dynamic, EventConstants, ListItemCustomEvent } from '../../engine';\nimport { NavController } from '@ionic/angular';\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';\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 NgxBaseComponent. 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 NgxBaseComponent\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 ForAngularModule,\n IonList,\n IonListHeader,\n IonItem,\n IonItemSliding,\n IonItemOptions,\n IonItemOption,\n IonIcon,\n IonLabel,\n IonButton,\n IonContent,\n IonPopover\n ]\n\n})\nexport class ListItemComponent extends NgxBaseComponent implements OnInit {\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' = 'inset';\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 * @description Angular NavController service for handling navigation.\n * @summary Injected service that provides methods for programmatic navigation\n * within the Ionic application. Used for navigating to different routes when\n * list item actions are performed or when the item itself is clicked.\n *\n * @private\n * @type {NavController}\n * @memberOf ListItemComponent\n */\n private navController: NavController = inject(NavController);\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 }\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\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 /**\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 NavController\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: EventConstants.CLICK, component: this.componentName } as ListItemCustomEvent;\n windowEventEmitter(`ListItem${EventConstants.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 > 768px\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 > 768)\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 NavController 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 NavController\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.navController.navigateForward(`/${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 #component>\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 \">\n @if(icon && lines !== 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-button shape=\"round\" fill=\"clear\">\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" color=\"dark\" size=\"default\"></ion-icon>\n </ion-button>\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-button shape=\"round\" fill=\"clear\">\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" color=\"dark\" size=\"default\"></ion-icon>\n </ion-button>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n <ion-label class=\"dcf-item-title\" [innerHTML]=\"uid + ' - ' + title\" ></ion-label>\n <div *ngIf =\"description\" class=\"dcf-description\" [innerHTML]=\"description\"></div>\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 <span *ngIf=\"info\" [innerHTML]=\"info\"></span>\n <div *ngIf=\"subinfo\" class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\" ></div>\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 <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n <ion-button class=\"dcf-hidden@m\" shape=\"round\" fill=\"clear\" color=\"primary\" (click)=\"presentActionsMenu($event)\">\n <ion-icon slot=\"icon-only\" aria-hidden=\"true\" name=\"ellipsis-vertical-outline\"></ion-icon>\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\"></ion-icon>\n } @else {\n <ion-icon color=\"danger\" aria-hidden=\"true\" name=\"trash\"></ion-icon>\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(operations?.length && uid) {\n <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n @if(operations?.includes('update')) {\n <ion-button fill=\"clear\" size=\"small\" color=\"primary\" (click)=\"handleAction('update', component)\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\"></ion-icon>\n </ion-button>\n }\n @if(operations?.includes('delete')) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleAction('delete', component)\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\"></ion-icon>\n </ion-button>\n }\n </div>\n } -->\n @if(windowWidth > 768) {\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=\"update\" (click)=\"handleAction('update', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\"></ion-icon>\n </ion-item-option>\n }\n @if(operations?.includes('delete')) {\n <ion-item-option class=\"delete\" (click)=\"handleAction('delete', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\"></ion-icon>\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n","import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { IonIcon } from '@ionic/angular/standalone';\nimport { addIcons } from 'ionicons';\nimport { chevronBackOutline, chevronForwardOutline } from 'ionicons/icons';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport { EventConstants, KeyValue, StringOrBoolean } from '../../engine';\nimport { PaginationCustomEvent } from './constants';\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 PaginationCustomEvent\n *\n * U->>P: Click next button\n * P->>P: next()\n * P->>P: handleClick('next')\n * P->>E: Emit clickEvent with PaginationCustomEvent\n *\n * U->>P: Click previous button\n * P->>P: previous()\n * P->>P: handleClick('previous')\n * P->>E: Emit clickEvent with PaginationCustomEvent\n *\n * @example\n * <ngx-decaf-pagination\n * [pages]=\"10\"\n * [current]=\"3\"\n * (clickEvent)=\"handlePageChange($event)\">\n * </ngx-decaf-pagination>\n *\n * @extends {NgxBaseComponent}\n * @implements {OnInit}\n */\n@Component({\n selector: 'ngx-decaf-pagination',\n templateUrl: './pagination.component.html',\n styleUrls: ['./pagination.component.scss'],\n imports: [\n ForAngularModule,\n IonIcon\n ],\n standalone: true,\n\n})\nexport class PaginationComponent extends NgxBaseComponent implements OnInit {\n\n /**\n * @description Controls whether the component uses translation services.\n * @summary When set to true, the component will attempt to use translation services\n * for any text content. This allows for internationalization of the pagination component.\n *\n * @type {StringOrBoolean}\n * @default true\n * @memberOf PaginationComponent\n */\n override translatable: StringOrBoolean = true;\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<PaginationCustomEvent>}\n * @memberOf PaginationComponent\n */\n @Output()\n clickEvent: EventEmitter<PaginationCustomEvent> = new EventEmitter<PaginationCustomEvent>();\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: EventConstants.CLICK,\n data: {\n direction,\n page: this.current\n },\n component: this.componentName\n } as PaginationCustomEvent);\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 = '') {\n if (pages.some(item => item['index'] === index)) return;\n pages.push({ index, text: index != null ? index.toString().padStart(2, '0') : text });\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, '...');\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\">\n <div class=\"dcf-width-1-1\">\n <div class=\"dcf-pagination-resume\" [innerHTML]=\"locale + '.resume' | translate: {value0: current, value1: last}\"></div>\n <div #paginationComponent class=\"dcf-pagination aeon-pagination dcf-flex-center\">\n <div\n aria-label=\"previous\"\n tabindex=\"0\"\n (click)=\"previous()\"\n (keydown.enter)=\"previous()\" [ngClass]=\"{'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\" (click)=\"navigate(page['index'])\"\n (keydown.enter)=\"navigate(page['index'])\"\n [ngClass]=\"{'dcf-active': current === page['index'], 'dcf-disabled': page['index'] === ndivl}\">\n <span class=\"page-item\">{{ page['text'] }}</span>\n </div>\n }\n <div\n tabindex=\"0\" (click)=\"next()\"\n (keydown.enter)=\"next()\"\n [ngClass]=\"{'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","import { Adapter, Repository } from \"@decaf-ts/core\";\nimport { Context, RepositoryFlags } from \"@decaf-ts/db-decorators\";\nimport { Constructor, Model } from \"@decaf-ts/decorator-validation\";\n\nexport enum ListComponentsTypes {\n INFINITE = 'infinite',\n PAGINATED = 'paginated'\n}\n\nexport interface IListEmptyResult {\n title: string;\n subtitle: string;\n showButton: boolean;\n buttonText: string;\n link: string;\n icon: string;\n}\n\nexport interface RawQuery<M extends Model> {\n select: undefined | (keyof M)[];\n from: Constructor<M>;\n where: (el: M) => boolean;\n sort?: (el: M, el2: M) => number;\n limit?: number;\n skip?: number;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type DecafRepositoryAdapter = Adapter<Map<string, Map<string | number, any>>, RawQuery<any>, RepositoryFlags & {UUIID?: string}, Context<RepositoryFlags & {UUIID?: string}>>\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type DecafRepository<M extends Model> = Repository<M, RawQuery<any>, DecafRepositoryAdapter, RepositoryFlags, Context<RepositoryFlags>>;\n","import { Component, OnInit, EventEmitter, Output, Input, HostListener, OnDestroy } from '@angular/core';\nimport { InfiniteScrollCustomEvent, RefresherCustomEvent, SpinnerTypes } from '@ionic/angular';\nimport {\n IonInfiniteScroll,\n IonInfiniteScrollContent,\n IonItem,\n IonLabel,\n IonList,\n IonRefresher,\n IonRefresherContent,\n IonSkeletonText,\n IonText,\n IonThumbnail,\n IonLoading\n} from '@ionic/angular/standalone';\nimport { debounceTime, Subject } from 'rxjs';\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 {\n BaseCustomEvent,\n Dynamic,\n EventConstants,\n ComponentsTagNames,\n RendererCustomEvent,\n StringOrBoolean,\n KeyValue,\n ListItemCustomEvent\n} from '../../engine';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport {\n stringToBoolean,\n formatDate,\n isValidDate\n} from '../../helpers';\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 { PaginationCustomEvent } from '../pagination/constants';\nimport { IListEmptyResult, ListComponentsTypes, DecafRepository } from './constants';\nimport { FunctionLike, IFilterQuery, IFilterQueryItem } from '../../engine';\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 {NgxBaseComponent}\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 ForAngularModule,\n IonRefresher,\n IonLoading,\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 ListItemComponent,\n FilterComponent,\n ComponentRendererComponent\n ]\n})\nexport class ListComponent extends NgxBaseComponent 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 whether the component uses translation services.\n * @summary When set to true, the component will attempt to use translation services\n * for any text content. This allows for internationalization of the list component.\n *\n * @type {StringOrBoolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n override translatable: StringOrBoolean = true;\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 {StringOrBoolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n showSearchbar: StringOrBoolean = 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 {StringOrBoolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n loadMoreData: StringOrBoolean = 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 {StringOrBoolean}\n * @default false\n * @memberOf ListComponent\n */\n @Input()\n inset: StringOrBoolean = 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 {StringOrBoolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n showRefresher: StringOrBoolean = true;\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 {StringOrBoolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n enableFilter: StringOrBoolean = 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 {StringOrBoolean}\n * @default false\n * @memberOf ListComponent\n */\n @Input()\n disableSort: StringOrBoolean = false;\n\n\n /**\n * @description Icon to display when the list is empty.\n * @summary Specifies the icon shown in the empty state when no data is available.\n * This can be any icon name supported by the application's icon system.\n *\n * @type {string | undefined}\n * @default 'ti-database-exclamation'\n * @memberOf ListComponent\n */\n @Input()\n emptyIcon?: string = 'ti-database-exclamation';\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<IListEmptyResult>}\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<IListEmptyResult> = {\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\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 * @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<BaseCustomEvent>}\n * @memberOf ListComponent\n */\n @Output()\n refreshEvent: EventEmitter<BaseCustomEvent> = new EventEmitter<BaseCustomEvent>();\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|RendererCustomEvent> = new EventEmitter<ListItemCustomEvent|RendererCustomEvent>();\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 | RendererCustomEvent>}\n * @memberOf ListComponent\n */\n private clickItemSubject: Subject<CustomEvent | ListItemCustomEvent | RendererCustomEvent> = new Subject<CustomEvent | ListItemCustomEvent | RendererCustomEvent>();\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 = { refresh: async (... args: unknown[]): Promise<void> => this.observeRepository(...args)}\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.clickItemSubject.pipe(debounceTime(100)).subscribe(event => this.clickEventEmit(event as ListItemCustomEvent | RendererCustomEvent));\n this.observerSubjet.pipe(debounceTime(100)).subscribe(args => this.handleObserveEvent(args[0], args[1], args[2]));\n this.enableFilter = stringToBoolean(this.enableFilter);\n this.limit = Number(this.limit);\n this.start = Number(this.start);\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 if(typeof this.item?.['tag'] === 'boolean' && this.item?.['tag'] === true)\n this.item['tag'] = ComponentsTagNames.LIST_ITEM as string;\n\n await this.refresh();\n\n if(this.operations.includes(OperationKeys.CREATE) && this.route)\n this.empty.link = `${this.route}/${OperationKeys.CREATE}`;\n\n this.initialize();\n\n if(this.model instanceof Model && this._repository)\n this._repository.observe(this.observer);\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 ngOnDestroy(): void {\n if(this._repository)\n this._repository.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 | RendererCustomEvent} event - The click event\n * @returns {void}\n *\n * @memberOf ListComponent\n */\n @HostListener('window:ListItemClickEvent', ['$event'])\n handleClick(event: ListItemCustomEvent | RendererCustomEvent): 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 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 await this.refresh(true);\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 }\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(data?.length || 2);\n this.refreshEvent.emit({\n name: EventConstants.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 | RendererCustomEvent} event - The click event\n * @returns {void}\n *\n * @memberOf ListComponent\n */\n private clickEventEmit(event: ListItemCustomEvent | RendererCustomEvent): 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 === EventConstants.BACK_BUTTON_NAVIGATION) {\n // const {refresh} = (force as CustomEvent).detail;\n // if(!refresh)\n // return false;\n // }\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 this.refreshEventEmit();\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 !== EventConstants.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 {PaginationCustomEvent} event - The pagination event containing page information\n * @returns {void}\n *\n * @memberOf ListComponent\n */\nhandlePaginate(event: PaginationCustomEvent): 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 return results.filter((item: KeyValue) =>\n Object.values(item).some(value =>\n value.toString().toLowerCase().includes((search as string)?.toLowerCase())\n )\n );\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 request: KeyValue[] = [];\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.logger.info('No data and source passed to infinite list');\n return [];\n }\n\n if(this.source instanceof Function)\n request = await this.source();\n\n if(!Array.isArray(request))\n request = request?.['response']?.['data'] || request?.['results'] || [];\n this.data = [... await this.parseResult(request)];\n if(this.data?.length)\n this.items = this.type === ListComponentsTypes.INFINITE ?\n (this.items || []).concat([...this.data.slice(start, limit)]) : [...request.slice(start, limit) as KeyValue[]];\n } else {\n this.data = this.parseSearchResults(this.data as [], this.searchValue as string);\n this.items = this.data;\n }\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 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 request = await this.parseResult(await repo.query(condition, (this.sortBy || this.pk) as keyof Model, this.sortDirection));\n data = [];\n }\n data = this.type === ListComponentsTypes.INFINITE ? [... (data).concat(request)] : [...request];\n } catch(error: unknown) {\n this.logger.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 result = await paginator.page(this.page);\n // TODO: Chage for result.total;\n this.getMoreData(paginator.total);\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] || 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","\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@if(showSearchbar) {\n @if(model && enableFilter) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n } @else {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n }\n}\n\n@if(data?.length) {\n <ion-list [id]=\"uid\" [inset]=\"inset\" [lines]=\"lines\" #component>\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 [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 <ion-item *ngFor=\"let skl of skeletonData\">\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 } @else {\n @if(!searchValue?.length) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\"\n [buttonText]=\"empty.showButton ? (locale + '.'+ empty.button | translate) : ''\"\n [buttonLink]=\"empty.showButton ? empty.route : ''\"\n />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n ngClass=\"empty-search\"\n [translatable]=\"true\"\n title=\"search.title\"\n subtitle=\"search.subtitle\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n}\n\n","import { NgModule, CUSTOM_ELEMENTS_SCHEMA } 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 { ForAngularModule } from '../for-angular.module';\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 { CollapsableDirective } from '../directives/collapsable.directive';\nimport { LayoutComponent } from './layout/layout.component';\nimport { FilterComponent } from './filter/filter.component';\n\nconst Directives = [CollapsableDirective];\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];\n\n@NgModule({\n imports: [Components, Directives],\n declarations: [],\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n exports: [Components, Directives, ForAngularModule],\n})\nexport class ForAngularComponentsModule {}\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';\n\n// Constants exports\nexport * from './crud-form/constants';\nexport * from './list/constants';\nexport * from './pagination/constants';\n\n// Module export\nexport * from './for-angular-components.module';\n","import '@decaf-ts/ui-decorators';\nexport * from './components';\nexport * from './engine';\nexport * from './directives';\nexport * from './helpers';\nexport * from './for-angular.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","i1","i2","i3","i4","NavController","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.module.ts","../../../src/lib/helpers/utils.ts","../../../src/lib/helpers/index.ts","../../../src/lib/engine/NgxFormService.ts","../../../src/lib/engine/NgxRenderingEngine.ts","../../../src/lib/components/component-renderer/component-renderer.component.ts","../../../src/lib/components/component-renderer/component-renderer.component.html","../../../src/lib/engine/NgxCrudFormField.ts","../../../src/lib/engine/decorators.ts","../../../src/lib/i18n/Loader.ts","../../../src/lib/components/crud-field/crud-field.component.ts","../../../src/lib/components/crud-field/crud-field.component.html","../../../src/lib/engine/interfaces.ts","../../../src/lib/engine/DynamicModule.ts","../../../src/lib/engine/NgxBaseComponent.ts","../../../src/lib/engine/index.ts","../../../src/lib/components/crud-form/constants.ts","../../../src/lib/components/crud-form/crud-form.component.ts","../../../src/lib/components/crud-form/crud-form.component.html","../../../src/lib/components/empty-state/empty-state.component.ts","../../../src/lib/components/empty-state/empty-state.component.html","../../../src/lib/directives/collapsable.directive.ts","../../../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/model-renderer/model-renderer.component.ts","../../../src/lib/components/model-renderer/model-renderer.component.html","../../../src/lib/components/layout/layout.component.ts","../../../src/lib/components/layout/layout.component.html","../../../src/lib/components/list-item/list-item.component.ts","../../../src/lib/components/list-item/list-item.component.html","../../../src/lib/components/pagination/pagination.component.ts","../../../src/lib/components/pagination/pagination.component.html","../../../src/lib/components/list/constants.ts","../../../src/lib/components/list/list.component.ts","../../../src/lib/components/list/list.component.html","../../../src/lib/components/for-angular-components.module.ts","../../../src/lib/components/index.ts","../../../src/lib/public-apis.ts","../../../src/lib/decaf-ts-for-angular.ts"],"sourcesContent":["import { UIKeys } from '@decaf-ts/ui-decorators';\nimport { VALIDATION_PARENT_KEY } from '@decaf-ts/decorator-validation';\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.\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 * @const AngularEngineKeys\n * @memberOf module:engine\n */\nexport const AngularEngineKeys = {\n REFLECT: `${UIKeys.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 FORM_GROUP_COMPONENT_PROPS: 'componentProps'\n};\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 * @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:engine\n */\nexport const FormConstants = {\n VALID: 'VALID',\n INVALID: 'INVALID',\n};\n\n/**\n * @description Event name constants\n * @summary Enum containing constants for event names used throughout the application.\n * These are used to standardize event naming and handling.\n * @enum {string}\n * @readonly\n * @property {string} BACK_BUTTON_NAVIGATION - Event fired when back button navigation ends\n * @property {string} REFRESH_EVENT - Event fired when a refresh action occurs\n * @property {string} CLICK_EVENT - Event fired when a click action occurs\n * @property {string} SUBMIT_EVENT - Event fired when a form submission occurs\n * @memberOf module:engine\n */\nexport const EventConstants = {\n BACK_BUTTON_NAVIGATION: 'backButtonNavigationEndEvent',\n REFRESH: 'RefreshEvent',\n CLICK: 'ClickEvent',\n SUBMIT: 'SubmitEvent',\n VALIDATION_ERROR: 'validationErrorEvent',\n FIELDSET_ADD_GROUP: 'fieldsetAddGroupEvent',\n FIELDSET_UPDATE_GROUP: 'fieldsetUpdateGroupEvent',\n FIELDSET_REMOVE_GROUP: 'fieldsetRemoveGroupEvent',\n // FIELDSET_GROUP_VALIDATION: 'fieldsetGroupValidationEvent'\n}\n\n/**\n * @description Logger level constants\n * @summary Enum defining the logging levels used in the application's logging system.\n * Lower values represent more verbose logging, while higher values represent more critical logs.\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:engine\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 Enum defining the possible navigation directions in the application.\n * Used for controlling navigation flow and animation directions.\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:engine\n */\nexport enum RouteDirections {\n BACK = 'back',\n FORWARD = 'forward',\n ROOT = 'root',\n}\n\n\n/**\n * @description Component tag name constants\n * @summary Enum defining the tag names for custom components used in the application.\n * These tag names are used for component registration and rendering.\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 * @memberOf module:engine\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}\n\n/**\n * @description Base component property name constants\n * @summary Enum defining the standard property names used by base components in the application.\n * These property names are used for consistent property access across components.\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} 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 * @memberOf module:engine\n */\nexport enum BaseComponentProps {\n MODEL = 'model',\n LOCALE = 'locale',\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}\n\n\n","import { AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn } from '@angular/forms';\nimport {\n ComparisonValidationKeys,\n DEFAULT_PATTERNS,\n PathProxy,\n PathProxyEngine,\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 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 { name, type } = fieldProps;\n const { validatorKey, props } = resolveValidatorKeyProps(key, fieldProps[key as keyof FieldProperties], type);\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(type, type === HTML5InputTypes.CHECKBOX ? name : 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 if(!props['types'] && !props['customTypes'])\n props['types'] = props['type'];\n errs = validator.hasErrors(value, props, proxy);\n } catch (e: unknown) {\n errs = `${key} validator failed to validate: ${e}`;\n console.warn(errs);\n }\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","import { NgModule, CUSTOM_ELEMENTS_SCHEMA, ModuleWithProviders, NO_ERRORS_SCHEMA} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport {\n IonApp,\n IonRouterOutlet,\n IonSplitPane,\n IonImg,\n IonContent,\n IonText,\n IonButton,\n IonRouterLink,\n IonTitle\n} from '@ionic/angular/standalone';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { TranslateModule, TranslatePipe } from '@ngx-translate/core';\nimport { Logger, Logging } from '@decaf-ts/logging';\nimport { FunctionLike } from './engine';\n\nconst ComponentsAndModules = [\n IonApp,\n IonRouterOutlet,\n IonSplitPane,\n IonImg,\n IonText,\n IonTitle,\n IonButton,\n IonRouterLink,\n IonContent,\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n TranslateModule,\n TranslatePipe,\n];\n\nconst log = Logging.for(\"for-angular\");\nexport function getLogger(instance: string | FunctionLike | unknown): Logger {\n return log.for(instance as string | FunctionLike);\n}\n\n/**\n * @description Main Angular module for the Decaf framework\n * @summary The ForAngularModule 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 *\n * @class ForAngularModule\n * @example\n * ```typescript\n * // In your app module:\n * @NgModule({\n * imports: [\n * ForAngularModule.forRoot(),\n * // other imports\n * ],\n * // ...\n * })\n * export class AppModule {}\n * ```\n */\n@NgModule({\n imports: ComponentsAndModules,\n declarations: [],\n exports: ComponentsAndModules,\n schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],\n})\nexport class ForAngularModule {\n /**\n * @description Creates a module with providers for root module import\n * @summary This static method provides the proper way to import the ForAngularModule in the application's\n * root module. It returns a ModuleWithProviders object that includes the ForAngularModule itself.\n * Using forRoot() ensures that the module and its providers are properly initialized and only\n * instantiated once in the application.\n *\n * @return {ModuleWithProviders<ForAngularModule>} The module with its providers\n */\n static forRoot(): ModuleWithProviders<ForAngularModule> {\n return {\n ngModule: ForAngularModule,\n };\n }\n}\n","import { 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.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()?.[key as keyof Document];\n return doc instanceof Document ?\n doc : 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 * Converts a string representation of a boolean or a boolean value to a boolean type.\n *\n * @export\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 */\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 * Checks if a value is a valid Date object\n *\n * @param {(string | Date | number)} date - The value to check. Can be a Date object, a timestamp number, or a date string\n * @return {boolean} Returns true if the value is a valid Date object (not NaN), otherwise false\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 * Formats a date into a localized string representation\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 * @return {(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 */\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 * Attempts to parse a date string, Date object, or number into a valid Date object\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 * @return {(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 */\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 * Maps an item object using a provided mapper object and optional additional properties.\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 */\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 * Maps an array of data objects using a provided mapper object.\n *\n * @template T - The type of the resulting mapped items.\n * @param {any[]} 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 *\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 */\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 * @module helpers\n * @description Utility helpers for Angular Decaf applications\n * @summary The helpers 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 './utils';\n","import { escapeHtml, FieldProperties, HTML5CheckTypes, HTML5InputTypes, parseToNumber } from '@decaf-ts/ui-decorators';\nimport { FieldUpdateMode, FormParentGroup, KeyValue } from './types';\nimport { IComponentConfig, IComponentInput } from './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 './ValidatorFactory';\nimport { cleanSpaces } from '../helpers';\nimport { OperationKeys } from '@decaf-ts/db-decorators';\nimport { AngularEngineKeys, 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 *\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 *\n * @type {WeakMap<AbstractControl, FieldProperties>}\n * @private\n * @static\n * @memberOf NgxFormService\n */\n private static controls = 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 *\n * @type {Map<string, FormGroup>}\n * @private\n * @static\n * @memberOf NgxFormService\n */\n private static formRegistry = new Map<string, FormGroup>();\n /**\n * @description Adds a form to the registry.\n * @summary Registers a FormGroup with a unique identifier. Throws an error if the identifier is already in use.\n * @param {string} formId - The unique identifier for the form.\n * @param {FormGroup} formGroup - The FormGroup to be registered.\n * @throws {Error} If a FormGroup with the given id is already registered.\n */\n static addRegistry(formId: string, formGroup: FormGroup): 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 Removes a form from the registry.\n * @summary Deletes a FormGroup from the registry using its unique identifier.\n * @param {string} formId - The unique identifier of the form to be removed.\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 * @param {FormGroup} formGroup - The root FormGroup.\n * @param {string} path - The path to the control.\n * @return {FormParentGroup} A tuple containing the parent FormGroup and the control name.\n */\n private static resolveParentGroup(formGroup: FormGroup, path: string, componentProps: IComponentInput, parentProps: KeyValue): FormParentGroup {\n const isMultiple = parentProps?.['multiple'] || parentProps?.['type'] === 'Array' || false;\n const parts = path.split('.');\n const controlName = parts.pop() as string;\n const {childOf} = componentProps\n let currentGroup = formGroup;\n\n function setArrayComponentProps(formGroupArray: FormArray) {\n const props = (formGroupArray as KeyValue)[AngularEngineKeys.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) ? new FormArray([new FormGroup({})]) : new FormGroup({});\n (partFormGroup as KeyValue)[AngularEngineKeys.FORM_GROUP_COMPONENT_PROPS] = {\n childOf: childOf || '',\n isMultiple: isMultiple,\n name: part,\n pk: componentProps?.['pk'] || parentProps?.['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\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\n currentGroup.addControl(part, partFormGroup);\n }\n }\n if(childOf && currentGroup instanceof FormArray)\n setArrayComponentProps(currentGroup);\n\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 *\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 *\n * @static\n * @memberOf NgxFormService\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)?.[AngularEngineKeys.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.\n *\n * @param {FormGroup} formGroup - The root form group containing the parent FormArray\n * @param {string} parentName - The name of the parent FormArray to add the group to\n * @param {number} [index=1] - The index position where the new group should be added\n * @return {FormGroup} The newly created and added FormGroup\n *\n * @static\n * @memberOf NgxFormService\n */\n static addGroupToParent(formGroup: FormGroup, parentName: string, index: number = 1): FormGroup {\n const componentProps = this.getComponentPropsFromGroupArray(formGroup, ModelKeys.MODEL, parentName);\n Object.entries(componentProps as KeyValue).forEach(([, value]) => {\n return this.addFormControl(formGroup, value, {multiple: true}, index);\n });\n\n return this.getGroupFromParent(formGroup, parentName, index);\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 *\n * @param {FormGroup} 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 *\n * @static\n * @memberOf NgxFormService\n */\n static getGroupFromParent(formGroup: FormGroup, 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, parentName, index);\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 *\n * @param {FormGroup} formGroup - The FormGroup to check for uniqueness\n * @param {number} index - The index of the current group within the FormArray\n * @param {OperationKeys} [operation=OperationKeys.CREATE] - The type of operation being performed\n * @return {boolean} True if the value is unique, false otherwise\n *\n * @static\n * @memberOf NgxFormService\n */\n static isUniqueOnGroup(formGroup: FormGroup, index: number, operation: OperationKeys = OperationKeys.CREATE): boolean {\n const formGroupArray = formGroup.parent as FormArray;\n const pk = this.getComponentPropsFromGroupArray(formGroupArray, BaseComponentProps.PK as string) as string;\n const controlName = Object.keys(formGroup.controls)[0];\n\n // only check for unique if is the pk control\n if(controlName !== pk)\n return true;\n const controlValue = cleanSpaces(`${formGroup.get(pk)?.value}`, true);\n if(operation === OperationKeys.CREATE)\n return !formGroupArray.controls.some((group, i) => i !== index && cleanSpaces(`${group.get(pk)?.value}`, true) === controlValue);\n\n return !formGroupArray.controls.some((group, i) =>\n i !== index && controlValue === cleanSpaces(`${group.get(pk)?.value}`, true)\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 *\n * @param {FormArray | FormGroup} formGroup - The FormGroup or FormArray to enable all controls for\n * @return {void}\n *\n * @static\n * @memberOf NgxFormService\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.\n *\n * @param {FormGroup} formGroup - The form group to add the control to\n * @param {IComponentInput} componentProps - The component properties defining the control configuration\n * @param {KeyValue} [parentProps={}] - Properties from the parent component for context\n * @param {number} [index=0] - The index for multiple controls in FormArrays\n * @return {void}\n *\n * @private\n * @static\n * @memberOf NgxFormService\n */\n private static addFormControl(formGroup: FormGroup, componentProps: IComponentInput, parentProps: KeyValue = {}, index: number = 0): void {\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, 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 parentGroup.addControl(controlName, control);\n }\n\n componentProps['formGroup'] = parentGroup;\n componentProps['formControl'] = parentGroup.get(controlName) as FormControl;\n componentProps['multiple'] = isMultiple\n\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 * @param {string} formId - The unique identifier of the form.\n * @param {string} [path] - The path to the control within the form.\n * @return {AbstractControl} The requested AbstractControl.\n * @throws {Error} If the form is not found in the registry or the control is not found in the form.\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 * @description Creates a form from component configurations.\n * @summary Generates a FormGroup based on an array of component configurations and optionally registers it.\n * @param {string} id - The unique identifier for the form.\n * @param {IComponentConfig[]} components - An array of component configurations.\n * @param {boolean} [registry=false] - Whether to register the created form.\n * @return {FormGroup} The created FormGroup.\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 * @param {string} id - The unique identifier of the form.\n * @param {FieldProperties} componentProperties - The properties of the component to create the control from.\n * @return {AbstractControl} The form or created control.\n */\n static addControlFromProps(id: string, componentProperties: FieldProperties, parentProps?: FieldProperties): AbstractControl {\n const form = this.formRegistry.get(id) ?? new FormGroup({});\n if (!this.formRegistry.has(id))\n this.addRegistry(id, form);\n\n if (componentProperties.path)\n this.addFormControl(form, componentProperties, parentProps);\n\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 * @param {FormGroup} formGroup - The FormGroup to extract data from.\n * @return {Record<string, unknown>} An object containing the form data.\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 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\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 }\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 * @param {AbstractControl} control - The control or form group to validate.\n * @param {string} [path] - The path to the control within the form.\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 */\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 return 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 * @param {FieldProperties} props - The component properties.\n * @return {ValidatorFn[]} An array of validator functions.\n */\n private static validatorsFromProps(props: FieldProperties): 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, k);\n });\n }\n\n /**\n * @description Creates a FormControl from component properties.\n * @summary Generates a FormControl with validators based on the provided component properties.\n * @param {FieldProperties} props - The component properties.\n * @param {FieldUpdateMode} [updateMode='change'] - The update mode for the control.\n * @return {FormControl} The created FormControl.\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 && props.type !== HTML5InputTypes.CHECKBOX\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.\n * @summary Gets the FieldProperties associated with a FormControl from the internal WeakMap.\n * @param {FormControl} control - The FormControl to get properties for.\n * @return {FieldProperties} The properties associated with the control.\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.\n * @summary Traverses up the DOM tree to find the nearest parent element with the specified tag.\n * @param {HTMLElement} el - The starting element.\n * @param {string} tag - The tag name to search for.\n * @return {HTMLElement} The found parent element.\n * @throws {Error} If no parent with the specified tag is found.\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.\n * @summary Associates a control with its properties in the internal WeakMap.\n * @param {AbstractControl} control - The control to register.\n * @param {FieldProperties} props - The properties to associate with the control.\n */\n static register(control: AbstractControl, props: FieldProperties) {\n this.controls.set(control, props);\n }\n\n /**\n * @description Unregisters a control.\n * @summary Removes a control and its associated properties from the internal WeakMap.\n * @param {AbstractControl} control - The control to unregister.\n * @return {boolean} True if the control was successfully unregistered, false otherwise.\n */\n static unregister(control: AbstractControl): boolean {\n return this.controls.delete(control);\n }\n\n /**\n * @description Resets a form group.\n * @summary Recursively resets all controls in a form group, clearing values, errors, and marking them as pristine and untouched.\n * @param {FormGroup} formGroup - The form group to reset.\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 { FieldDefinition, RenderingEngine } from '@decaf-ts/ui-decorators';\nimport { AngularFieldDefinition, KeyValue } from './types';\nimport { AngularDynamicOutput } from './interfaces';\nimport { AngularEngineKeys } from './constants';\nimport { Constructor, Model} from '@decaf-ts/decorator-validation';\nimport { InternalError } from '@decaf-ts/db-decorators';\nimport {\n ComponentMirror,\n ComponentRef,\n EnvironmentInjector,\n Injector,\n reflectComponentType,\n TemplateRef,\n Type,\n ViewContainerRef,\n} from '@angular/core';\nimport { NgxFormService } from './NgxFormService';\n\n/**\n * @description Angular implementation of the RenderingEngine with enhanced features\n * @summary This class extends the base RenderingEngine to provide Angular-specific rendering capabilities\n * with additional features compared to NgxRenderingEngine. It handles the conversion of field definitions\n * to Angular components, manages component registration, and provides utilities for component creation\n * and input handling. This implementation uses Angular's newer component APIs.\n *\n * @template AngularFieldDefinition - Type for Angular-specific field definitions\n * @template AngularDynamicOutput - Type for Angular-specific component output\n *\n * @class NgxRenderingEngine\n * @example\n * ```typescript\n * const engine = NgxRenderingEngine.get();\n * engine.initialize();\n * const output = engine.render(myModel, {}, viewContainerRef, injector, templateRef);\n * ```\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 */\nexport class NgxRenderingEngine extends RenderingEngine<AngularFieldDefinition, AngularDynamicOutput> {\n\n /**\n * @description Registry of components available for 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 *\n * @private\n * @static\n * @type {Record<string, { constructor: Constructor<unknown> }>}\n */\n private static _components: Record<string, { constructor: Constructor<unknown> }>;\n\n /**\n * @description Currently active model being rendered\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 *\n * @private\n * @type {Model}\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 *\n * @private\n * @static\n * @type {string | undefined}\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 *\n * @private\n * @static\n * @type {Type<unknown> | undefined}\n */\n private static _instance: Type<unknown> | 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 *\n * @constructor\n */\n constructor() {\n super('angular');\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, and child component rendering.\n * The method validates input properties against the component's metadata and processes\n * child components recursively.\n *\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 * @return {AngularDynamicOutput} The Angular component output with component reference and inputs\n *\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 */\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 ): AngularDynamicOutput {\n const cmp = (fieldDef as KeyValue)?.['component'] || 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(`Metadata for component ${fieldDef.tag} not found.`);\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(({ propName }) => propName === input);\n if (!isMapped) delete inputs[input];\n return !isMapped;\n });\n\n if (unmappedKeys.length > 0)\n console.warn(`Unmapped input properties for component ${fieldDef.tag}: ${unmappedKeys.join(', ')}`);\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 // const hiddenOn = inputs?.hidden || [];\n const result: AngularDynamicOutput = {\n component,\n inputs,\n injector,\n };\n\n if (fieldDef.rendererId)\n (result.inputs as Record<string, unknown>)['rendererId'] = fieldDef.rendererId;\n\n // process children\n if (fieldDef.children?.length) {\n result.children = fieldDef.children.map((child) => {\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 // create a child form and add its controls as properties of child.props\n NgxFormService.addControlFromProps(registryFormId, child.props, inputs);\n return this.fromFieldDefinition(child, vcr, injector, tpl, registryFormId);\n });\n }\n\n // generating DOM\n vcr.clear();\n const template = vcr.createEmbeddedView(tpl, injector).rootNodes;\n const componentInstance = NgxRenderingEngine.createComponent(\n component,\n { ...inputs, model: this._model },\n componentMetadata,\n vcr,\n injector,\n template,\n );\n\n result.instance = NgxRenderingEngine._instance = componentInstance.instance as Type<unknown>;\n\n return result;\n }\n\n\n /**\n * @description Creates an Angular component instance\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 *\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 */\n static createComponent(component: Type<unknown>, inputs: KeyValue = {}, metadata: ComponentMirror<unknown>, vcr: ViewContainerRef, injector: Injector, template: Node[] = []): ComponentRef<unknown> {\n const componentInstance = vcr.createComponent(component as Type<unknown>, {\n environmentInjector: injector as EnvironmentInjector,\n projectableNodes: [template],\n });\n this.setInputs(componentInstance, inputs, metadata);\n return componentInstance;\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 *\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 */\n getDecorators(model: Model, globalProps: Record<string, unknown>): FieldDefinition<AngularFieldDefinition> {\n return this.toFieldDefinition(model, globalProps);\n }\n\n /**\n * @description Destroys the current engine instance\n * @summary This static method clears the current instance reference, effectively\n * destroying the singleton instance of the rendering engine. This can be used\n * to reset the engine state or to prepare for a new instance creation.\n *\n * @return {Promise<void>} A promise that resolves when the instance is destroyed\n */\n static async destroy(): Promise<void> {\n NgxRenderingEngine._instance = undefined;\n }\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 *\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 *\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 */\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 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 KeyValue;\n if(!NgxRenderingEngine._operation)\n NgxRenderingEngine._operation = props?.['operation'] || undefined;\n result = this.fromFieldDefinition(fieldDef, vcr, injector, tpl, formId);\n\n (result!.instance! as KeyValue)['formGroup'] = NgxFormService.getControlFromForm(formId);\n NgxFormService.removeRegistry(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 *\n * @return {Promise<void>} A promise that resolves when initialization is complete\n */\n override async initialize(): Promise<void> {\n if (this.initialized)\n return;\n // ValidatableByType[]\n 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 *\n * @param {string} name - The name to register the component under\n * @param {Constructor<unknown>} constructor - The component constructor\n * @return {void}\n */\n static registerComponent(name: string, constructor: Constructor<unknown>): 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 *\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 */\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 Generates a key for reflection metadata\n * @summary This static method generates a key for reflection metadata by prefixing the input key\n * with the Angular engine's reflection prefix. This is used for storing and retrieving\n * metadata in a namespaced way to avoid conflicts with other metadata.\n *\n * @param {string} key - The base key to prefix\n * @return {string} The prefixed key for reflection metadata\n */\n static override key(key: string): string {\n return `${AngularEngineKeys.REFLECT}${key}`;\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 *\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 *\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 */\n static setInputs(component: ComponentRef<unknown>, inputs: KeyValue, metadata: ComponentMirror<unknown>): void {\n function parseInputValue(component: ComponentRef<unknown>, input: KeyValue) {\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((item: { propName: string }) => item.propName === key);\n if (prop) {\n if (key === 'props')\n parseInputValue(component, value);\n // if(key === 'locale' && !value)\n // value = getLocaleFromClassName(this._componentName);\n component.setInput(key, value);\n }\n });\n }\n}\n","import {\n Component,\n ComponentMirror,\n ComponentRef,\n EnvironmentInjector,\n EventEmitter,\n inject,\n Injector,\n Input,\n OnDestroy,\n OnInit,\n Output,\n reflectComponentType,\n TemplateRef,\n Type,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport { NgxRenderingEngine } from '../../engine/NgxRenderingEngine';\nimport { BaseCustomEvent, KeyValue, RendererCustomEvent } from '../../engine';\nimport { ForAngularModule, getLogger } from '../../for-angular.module';\nimport { Logger } from '@decaf-ts/logging';\nimport { Model } from '@decaf-ts/decorator-validation';\nimport { generateRandomValue } from '../../helpers';\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~RendererCustomEvent~ 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: [ForAngularModule],\n standalone: true,\n host: {'[attr.id]': 'rendererId'},\n})\nexport class ComponentRendererComponent\n implements OnInit, OnDestroy {\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 ComponentRendererComponent\n */\n @ViewChild('componentViewContainer', { static: true, read: ViewContainerRef })\n vcr!: ViewContainerRef;\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 /**\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 ComponentRendererComponent\n */\n @Input()\n globals: Record<string, unknown> = {};\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 ComponentRendererComponent\n */\n injector: EnvironmentInjector = inject(EnvironmentInjector);\n\n /**\n * @description Reference to the dynamically created component.\n * @summary This property holds a reference to the ComponentRef of the dynamically created\n * component. It's used to interact with the component instance, subscribe to its events,\n * and properly destroy it when the renderer is destroyed.\n *\n * @type {ComponentRef<unknown>}\n * @memberOf ComponentRendererComponent\n */\n component!: ComponentRef<unknown>;\n\n /**\n * @description Event emitter for events from the rendered component.\n * @summary This output property emits events that originate from the dynamically rendered\n * component. It allows the parent component to listen for and respond to events from the\n * dynamic component, creating a communication channel between the parent and the dynamically\n * rendered child.\n *\n * @type {EventEmitter<RendererCustomEvent>}\n * @memberOf ComponentRendererComponent\n */\n @Output()\n listenEvent: EventEmitter<RendererCustomEvent> =\n new EventEmitter<RendererCustomEvent>();\n\n /**\n * @description Logger instance for the component.\n * @summary This property holds a Logger instance specific to this component.\n * It's used to log information, warnings, and errors related to the component's\n * operations, particularly useful for debugging and monitoring the dynamic\n * component rendering process.\n *\n * @type {Logger}\n * @memberOf ComponentRendererComponent\n */\n logger!: Logger;\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 */\n @Input()\n model!: Model | undefined;\n\n @Input()\n parent: undefined | KeyValue = undefined;\n\n\n @ViewChild('inner', { read: TemplateRef, static: true })\n inner?: TemplateRef<unknown>;\n\n uid: string = generateRandomValue(12);\n\n /**\n * @description Creates an instance of ComponentRendererComponent.\n * @summary Initializes a new ComponentRendererComponent. This component doesn't require\n * any dependencies to be injected in its constructor as it uses the inject function to\n * obtain the EnvironmentInjector.\n *\n * @memberOf ComponentRendererComponent\n */\n constructor() {\n this.logger = getLogger(this);\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 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 ComponentRendererComponent\n */\n async ngOnDestroy(): Promise<void> {\n if (this.component) {\n this.unsubscribeEvents();\n NgxRenderingEngine.destroy();\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 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 this.vcr.clear();\n this.component = NgxRenderingEngine.createComponent(\n component,\n props,\n metadata as ComponentMirror<unknown>,\n this.vcr,\n this.injector as Injector,\n [],\n );\n this.subscribeEvents();\n }\n\n createParentComponent() {\n const { component, inputs } = this.parent as KeyValue;\n const metadata = reflectComponentType(component) as ComponentMirror<unknown>;\n const template = this.vcr.createEmbeddedView(this.inner as TemplateRef<unknown>, this.injector).rootNodes;\n this.component = NgxRenderingEngine.createComponent(\n component,\n inputs,\n metadata,\n this.vcr,\n this.injector,\n template,\n );\n this.subscribeEvents();\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 ComponentRendererComponent\n */\n private subscribeEvents(): void {\n if (this.component) {\n const instance = this.component?.instance as KeyValue;\n const componentKeys = Object.keys(instance);\n for (const key of componentKeys) {\n const value = instance[key];\n if (value instanceof EventEmitter)\n (instance as KeyValue)[key].subscribe(\n (event: Partial<BaseCustomEvent>) => {\n this.listenEvent.emit({\n name: key,\n ...event,\n } as RendererCustomEvent);\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 ComponentRendererComponent\n */\n private unsubscribeEvents(): void {\n if (this.component) {\n const instance = this.component?.instance as KeyValue;\n const componentKeys = Object.keys(instance);\n for (const key of componentKeys) {\n const value = instance[key];\n if (value instanceof EventEmitter) instance[key].unsubscribe();\n }\n }\n }\n}\n","<!-- Keep to avoid id conflicts -->\n<div [id]=\"uid\"></div>\n\n<ng-template #componentViewContainer></ng-template>\n<ng-template #inner>\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</ng-template>\n\n\n\n","import { CrudOperationKeys, FieldProperties, RenderingError } from '@decaf-ts/ui-decorators';\nimport { KeyValue, PossibleInputTypes } from './types';\nimport { CrudOperations, InternalError, OperationKeys } from '@decaf-ts/db-decorators';\nimport { ControlValueAccessor, FormControl, FormGroup } from '@angular/forms';\nimport { ElementRef, inject } from '@angular/core';\nimport { NgxFormService } from './NgxFormService';\nimport { sf } from '@decaf-ts/decorator-validation';\nimport { TranslateService } from '@ngx-translate/core';\nimport { EventConstants } from './constants';\n\n/**\n * @class NgxCrudFormField\n * @implements {FieldProperties}\n * @implements {ControlValueAccessor}\n * @summary Abstract class representing a CRUD form field for Angular applications\n * @description This class provides the base implementation for CRUD form fields in Angular,\n * implementing both CrudFormField and ControlValueAccessor interfaces.\n */\nexport abstract class NgxCrudFormField implements ControlValueAccessor, FieldProperties {\n /**\n * @summary Reference to the component's element\n * @description ElementRef representing the component's native element\n */\n component!: ElementRef;\n\n /**\n * @summary Current CRUD operation\n * @description Represents the current CRUD operation being performed\n */\n operation!: CrudOperations;\n\n /**\n * @summary Form group for the field\n * @description Angular FormGroup instance for the field\n */\n formGroup!: FormGroup | undefined;\n\n formControl!: FormControl;\n\n name!: string;\n\n path!: string;\n\n childOf?: string;\n\n type!: PossibleInputTypes;\n\n disabled?: boolean;\n\n uid?: string;\n\n // Validation\n\n format?: string;\n hidden?: boolean | CrudOperationKeys[];\n max?: number | Date;\n maxlength?: number;\n min?: number | Date;\n minlength?: number;\n pattern?: string | undefined;\n readonly?: boolean;\n required?: boolean;\n step?: number;\n equals?: string;\n different?: string;\n lessThan?: string;\n lessThanOrEqual?: string;\n greaterThan?: string;\n greaterThanOrEqual?: string;\n\n value!: string | number | Date;\n\n multiple!: boolean;\n\n protected translateService = inject(TranslateService);\n\n private validationErrorEventDispateched: boolean = false;\n\n /**\n * @summary Parent HTML element\n * @description Reference to the parent HTML element of the field\n */\n protected parent?: HTMLElement;\n\n // protected constructor() {}\n\n /**\n * @summary String formatting function\n * @description Provides access to the sf function for error message formatting\n * @prop {function(string, ...string): string} sf - String formatting function\n */\n sf = sf;\n\n /**\n * @summary Change callback function\n * @description Function called when the field value changes\n * @property {function(): unknown} onChange - onChange event handler\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: () => unknown = () => {};\n\n /**\n * @summary Touch callback function\n * @description Function called when the field is touched\n * @property {function(): unknown} onTouch - onTouch event handler\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onTouch: () => unknown = () => {};\n\n /**\n * @summary Write value to the field\n * @description Sets the value of the field\n * @param {string} obj - The value to be set\n */\n writeValue(obj: string): void {\n this.value = obj;\n }\n\n /**\n * @summary Register change callback\n * @description Registers a function to be called when the field value changes\n * @param {function(): unknown} fn - The function to be called on change\n */\n registerOnChange(fn: () => unknown): void {\n this.onChange = fn;\n }\n\n /**\n * @summary Register touch callback\n * @description Registers a function to be called when the field is touched\n * @param {function(): unknown} fn - The function to be called on touch\n */\n registerOnTouched(fn: () => unknown): void {\n this.onTouch = fn;\n }\n\n /**\n * @summary Set disabled state\n * @description Sets the disabled state of the field\n * @param {boolean} isDisabled - Whether the field should be disabled\n */\n setDisabledState?(isDisabled: boolean): void {\n this.disabled = isDisabled;\n }\n\n /**\n * @summary After view initialization logic\n * @description Performs necessary setup after the view has been initialized\n * @returns {HTMLElement} The parent element of the field\n */\n afterViewInit(): HTMLElement {\n let parent: HTMLElement;\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 * @summary Cleanup on component destruction\n * @description Unregisters the field when the component is destroyed\n */\n onDestroy(): void {\n if(this.formGroup)\n NgxFormService.unregister(this.formGroup);\n }\n\n /**\n * @summary Get field errors\n * @description Retrieves all errors associated with the field\n * @returns {string|void} An array of error objects\n */\n getErrors(parent: HTMLElement): string | void {\n const formControl = this.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.validationErrorEventDispateched) {\n const validationErrorEvent = new CustomEvent(EventConstants.VALIDATION_ERROR, {\n detail: {fieldName: this.name, hasErrors: true},\n bubbles: true\n });\n accordionComponent.dispatchEvent(validationErrorEvent);\n this.validationErrorEventDispateched = true;\n }\n }\n for(const error of errors)\n return `* ${this.sf(this.translateService.instant(`errors.${error?.['message']}`), (this as KeyValue)[error?.['key']] ?? \"\")}`;\n }\n }\n}\n","import { apply, metadata } from '@decaf-ts/reflection';\nimport { NgxRenderingEngine } from './NgxRenderingEngine';\nimport { AngularEngineKeys } from './constants';\nimport { Constructor } from '@decaf-ts/decorator-validation';\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(NgxRenderingEngine.key(AngularEngineKeys.DYNAMIC), true)\n );\n}\n","import { HttpClient } from '@angular/common/http';\nimport { TranslateLoader, TranslationObject } from '@ngx-translate/core';\nimport { TranslateHttpLoader } from '@ngx-translate/http-loader';\nimport { forkJoin, Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport {I18nResourceConfig} from '../engine/interfaces';\nimport { inject, InjectionToken } from '@angular/core';\nimport { FunctionLike } from '../engine';\nimport { cleanSpaces, getLocaleFromClassName } from '../helpers';\nexport class I18nLoader {\n static loadFromHttp(http: HttpClient): TranslateLoader {\n function getSuffix() {\n const today = new Date();\n return `.json?version=${today.getFullYear()}${today.getMonth()}${today.getDay()}` as string;\n }\n\n return new (class extends TranslateHttpLoader {\n override getTranslation(lang: string): Observable<TranslationObject> {\n const res = super.getTranslation(lang);\n return res;\n }\n })(http, './assets/i18n/', getSuffix());\n }\n}\n\n\nexport function getLocaleContext(clazz: FunctionLike | object | string, suffix?: string): string {\n return getLocaleFromClassName(clazz, suffix);\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\nexport const I18N_CONFIG_TOKEN = new InjectionToken<{resources: I18nResourceConfig[]; versionedSuffix: false}>('I18N_CONFIG_TOKEN');\n\nexport function I18nLoaderFactory(http: HttpClient): TranslateLoader {\n const {resources, versionedSuffix} = inject(I18N_CONFIG_TOKEN, { optional: true }) ?? getI18nLoaderFactoryProviderConfig().useValue;\n return new MultiI18nLoader(http, resources, versionedSuffix);\n}\n\nexport function getI18nLoaderFactoryProviderConfig(resources: I18nResourceConfig | I18nResourceConfig[] = [], versionedSuffix: boolean = false) {\n if(!Array.isArray(resources))\n resources = [resources];\n return {\n provide: I18N_CONFIG_TOKEN,\n useValue: { resources: [\n { prefix: './assets/i18n/', suffix: '.json' },\n ...resources\n ], versionedSuffix}\n }\n}\n\nexport class MultiI18nLoader implements I18nLoader {\n constructor(private http: HttpClient, private resources: I18nResourceConfig[] = [], private versionedSuffix: boolean = false) {}\n\n private getSuffix(suffix: string): string {\n if(!this.versionedSuffix)\n return suffix;\n const today = new Date();\n return `${suffix}?version=${today.getFullYear()}${today.getMonth()}${today.getDay()}` as string;\n }\n\n getTranslation(lang: string): Observable<TranslationObject> {\n const requests = this.resources.map(config =>\n this.http.get(`${config.prefix}${lang}${this.getSuffix(config.suffix)}`)\n );\n\n return forkJoin(requests).pipe(\n map(responseArray => {\n return responseArray.reduce((acc, current) => {\n return { ...acc, ...current };\n }, {});\n })\n );\n }\n}\n","import {\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 } from '@angular/forms';\nimport { AutocompleteTypes, SelectInterface } from '@ionic/core';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport { NgxCrudFormField } from '../../engine/NgxCrudFormField';\nimport { Dynamic } from '../../engine/decorators';\nimport { CrudFieldOption, FieldUpdateMode, PossibleInputTypes, StringOrBoolean } from '../../engine/types';\nimport { ForAngularModule } from '../../for-angular.module';\nimport {\n IonCheckbox,\n IonIcon,\n IonInput,\n IonItem,\n IonLabel,\n IonRadio,\n IonRadioGroup,\n IonSelect,\n IonSelectOption,\n IonText,\n IonTextarea,\n} from '@ionic/angular/standalone';\nimport { HTML5InputTypes } from '@decaf-ts/ui-decorators';\nimport { addIcons } from 'ionicons';\nimport { chevronDownOutline, chevronUpOutline } from 'ionicons/icons';\nimport { generateRandomValue } from '../../helpers';\nimport { NgxFormService } from '../../engine/NgxFormService';\nimport { EventConstants } from '../../engine/constants';\nimport { getLocaleContextByKey } from '../../i18n/Loader';\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 NgxCrudFormField 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 ForAngularModule,\n IonInput,\n IonItem,\n IonCheckbox,\n IonRadioGroup,\n IonRadio,\n IonSelect,\n IonSelectOption,\n IonLabel,\n IonText,\n IonTextarea,\n IonIcon\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'},\n})\nexport class CrudFieldComponent extends NgxCrudFormField 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 /**\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 = '';\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;\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;\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 Number of columns for textarea inputs.\n * @summary For textarea inputs, this sets the visible width of the text area in average character widths.\n * This is used alongside rows to define the dimensions of the textarea.\n *\n * @type {number}\n * @memberOf CrudFieldComponent\n */\n @Input()\n cols?: number;\n\n /**\n * @description Number of rows for textarea inputs.\n * @summary For textarea inputs, this sets the visible height of the text area in lines of text.\n * This is used alongside cols to define the dimensions of the textarea.\n *\n * @type {number}\n * @memberOf CrudFieldComponent\n */\n @Input()\n rows?: number;\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!: CrudFieldOption[];\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 /**\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\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 *\n * @type {number}\n * @default 0\n * @memberOf CrudFieldComponent\n */\n @Input()\n activeFormGroup: number = 0;\n\n /**\n * @description FormArray containing multiple form groups for this field.\n * @summary When this field is part of a multi-entry structure, this FormArray\n * contains all the form groups. This enables management of multiple instances\n * of the same field structure within a single form.\n *\n * @type {FormArray}\n * @memberOf CrudFieldComponent\n */\n formGroupArray!: FormArray;\n\n /**\n * @description Primary key field name for uniqueness validation.\n * @summary Specifies the field name that serves as the primary key for uniqueness\n * validation within form arrays. This is used to prevent duplicate entries\n * and ensure data integrity in multi-entry forms.\n *\n * @type {string}\n * @memberOf CrudFieldComponent\n */\n @Input()\n pk!: string;\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 *\n * @returns {FormGroup} The currently active FormGroup for this field\n * @memberOf CrudFieldComponent\n */\n get getActiveFormGroup(): FormGroup {\n const formGroup = this.formGroup as FormGroup;\n return this.multiple\n ? ((formGroup.parent as FormArray)?.at(this.activeFormGroup) as FormGroup)\n : formGroup;\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 get parsedOptions(): CrudFieldOption[] {\n return this.options.map((option) => {\n return {\n ...option,\n text: !option.text.includes('options') ?\n getLocaleContextByKey(`${this.label.toLowerCase().replace('label', 'options')}`, option.text) : option.text\n };\n });\n }\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 ngOnInit(): void {\n if(this.options?.length)\n this.options = this.parsedOptions;\n if ([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation)) {\n this.formGroup = undefined;\n } else {\n addIcons({chevronDownOutline, chevronUpOutline})\n if(this.multiple) {\n this.formGroup = this.getActiveFormGroup as FormGroup;\n this.formGroupArray = this.formGroup.parent as FormArray;\n }\n if (this.type === HTML5InputTypes.RADIO && !this.value)\n this.formGroup?.get(this.name)?.setValue(this.options[0].value); // TODO: migrate to RenderingEngine\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 {void}\n * @memberOf CrudFieldComponent\n */\n ngAfterViewInit(): void {\n if ([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation))\n super.afterViewInit();\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 ngOnDestroy(): void {\n if ([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation))\n this.onDestroy();\n }\n\n /**\n * @description Handles fieldset group creation events from parent fieldsets.\n * @summary Processes events triggered when a new group needs to be added to a fieldset.\n * Validates the current form group, checks for uniqueness if applicable, and either\n * creates a new group or provides validation feedback. Updates the active form group\n * and resets the field for new input after successful creation.\n *\n * @param {CustomEvent} event - The fieldset create group event containing group details\n * @returns {void}\n * @memberOf CrudFieldComponent\n */\n @HostListener('window:fieldsetAddGroupEvent', ['$event'])\n handleFieldsetCreateGroupEvent(event: CustomEvent): void {\n event.stopImmediatePropagation();\n const { parent, component, index, operation } = event.detail;\n const formGroup = this.formGroup as FormGroup;\n const parentFormGroup = this.formGroup?.parent as FormArray;\n const isValid = NgxFormService.validateFields(formGroup as FormGroup);\n const indexToCheck = operation === OperationKeys.CREATE ?\n index === 0 ? index : parentFormGroup.length - 1 : index - 1;\n\n const isUnique = NgxFormService.isUniqueOnGroup(formGroup, indexToCheck, operation || OperationKeys.CREATE);\n event = new CustomEvent(EventConstants.FIELDSET_ADD_GROUP, {\n detail: {isValid: isValid && isUnique, value: formGroup.value, formGroup: parentFormGroup, formService: NgxFormService},\n });\n component.dispatchEvent(event);\n\n if(isValid && isUnique) {\n const newIndex = parentFormGroup.length;\n\n if(operation === OperationKeys.CREATE) {\n NgxFormService.addGroupToParent(parentFormGroup?.parent as FormGroup, parent, newIndex);\n this.activeFormGroup = newIndex;\n } else {\n this.activeFormGroup = newIndex - 1;\n }\n this.formGroup = this.getActiveFormGroup;\n // NgxFormService.reset(this.formGroup as FormGroup);\n this.formControl = (this.formGroup as FormGroup).get(this.name) as FormControl;\n // NgxFormService.reset(this.formControl);\n // this.component.nativeElement.setFocus();\n } else {\n if(isUnique)\n this.component.nativeElement.setFocus();\n }\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 {index} = event.detail;\n this.activeFormGroup = index;\n this.formGroup = this.getActiveFormGroup;\n this.formControl = this.formGroup.get(this.name) as FormControl;\n }\n\n\n /**\n * @description Handles fieldset group removal events from parent fieldsets.\n * @summary Processes events triggered when a group needs to be removed from a fieldset.\n * Removes the specified group from the form array, updates the active form group index,\n * and refreshes the form references. Dispatches a confirmation event back to the component.\n *\n * @param {CustomEvent} event - The fieldset remove group event containing removal details\n * @returns {void}\n * @memberOf CrudFieldComponent\n */\n @HostListener('window:fieldsetRemoveGroupEvent', ['$event'])\n handleFieldsetRemoveGroupEvent(event: CustomEvent): void {\n const { component, index } = event.detail;\n const formArray = this.formGroup?.parent as FormArray;\n formArray.removeAt(index);\n this.activeFormGroup = formArray.length === 1 ? 0 : formArray.length - 1;\n this.formGroup = this.getActiveFormGroup;\n this.formControl = this.formGroup.get(this.name) as FormControl;\n this.formGroupArray = formArray\n event = new CustomEvent(EventConstants.FIELDSET_REMOVE_GROUP, {\n detail: {value: true},\n });\n component.dispatchEvent(event);\n }\n}\n","@if(operation === 'read' || operation === 'delete') {\n <ng-container #component>\n <div [class]=\"'dcf-input-item ' + operation\">\n <ion-item>\n <ion-label>\n {{ label | translate }}<br />\n @if(value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n <br />\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n <ng-container [formGroup]=\"getActiveFormGroup\">\n <div #container [class]=\"'dcf-input-item ' + (operation || 'create')\" (createGroupEvent)=\"multiple ? handleFieldsetCreateGroupEvent($event) : ''\">\n @if(type === 'textarea') {\n <ion-textarea\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [required]=\"required !== undefined ? required : null\"\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]=\"translatable ? (placeholder | translate) : placeholder\"\n [formControlName]=\"name\"\n [label]=\"translatable ? (label | translate) : label\"\n #component>\n </ion-textarea>\n }\n @else if(type === 'checkbox') {\n <ion-item>\n <ion-checkbox\n #checkboxElement\n\n [mode]=\"mode\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span [innerHTML]=\"label | translate\"></span>\n </ion-checkbox>\n </ion-item>\n }\n @else if(type === 'radio') {\n <ion-radio-group [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track option) {\n <ion-item>\n <ion-radio\n [errorText]=\"getErrors(container)\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ translatable ? (option?.text | translate) : option?.text }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if(type === 'select') {\n <ion-select\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"translatable ? (label | translate) : label\"\n [value]=\"value\"\n [fill]=\"fill\"\n [placeholder]=\"translatable ? (placeholder | translate) : placeholder\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [interface]=\"interface\" #component>\n @for(option of options; track option.value) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n </ion-select>\n }\n @else {\n <ion-input\n [type]=\"type\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [required]=\"required !== undefined ? required : false\"\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]=\"translatable ? (placeholder | translate) : placeholder\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [label]=\"translatable ? (label | translate) : label\" #component />\n }\n </div>\n </ng-container>\n}\n\n","import { 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 { FieldProperties } from '@decaf-ts/ui-decorators';\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: FormGroup | 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 IComponentInput\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 IComponentInput extends FieldProperties {\n updateMode?: FieldUpdateMode;\n formGroup?: FormGroup;\n formControl?: FormControl;\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 {IComponentInput} 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: IComponentInput;\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 instance?: Type<unknown>;\n formGroup?: FormGroup;\n formControl?: FormControl;\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 BaseCustomEvent 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 BaseCustomEvent)\n * @property {HTMLElement} [target] - The target element (inherited from BaseCustomEvent)\n * @property {string} [name] - The name of the event (inherited from BaseCustomEvent)\n * @property {string} component - The component that triggered the event (inherited from BaseCustomEvent)\n * @memberOf module:engine\n */\nexport interface ListItemCustomEvent extends BaseCustomEvent {\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 BaseCustomEvent\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 BaseCustomEvent {\n name: string;\n component: string;\n data?: unknown;\n target?: HTMLElement;\n}\n\n\n/**\n * Configuration for internationalization (i18n) resource file paths.\n *\n * @property prefix - The prefix to be used for the resource file path.\n * @property suffix - The suffix to be appended to the resource file path.\n */\nexport interface I18nResourceConfig { prefix: string, suffix: string }\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","import {\n Input,\n Component,\n Inject,\n ViewChild,\n ElementRef,\n OnChanges,\n SimpleChanges,\n Output,\n EventEmitter,\n} from '@angular/core';\nimport { KeyValue, RendererCustomEvent, StringOrBoolean } from './types';\nimport {\n generateRandomValue,\n getInjectablesRegistry,\n getOnWindow,\n isDevelopmentMode,\n stringToBoolean\n} from '../helpers/utils';\nimport { getLocaleContext } from '../i18n/Loader';\nimport { Model } from '@decaf-ts/decorator-validation';\nimport {\n CrudOperations,\n InternalError,\n OperationKeys\n} from '@decaf-ts/db-decorators';\nimport { BaseComponentProps } from './constants';\nimport { NgxRenderingEngine } from './NgxRenderingEngine';\nimport { Logger } from '@decaf-ts/logging';\nimport { getLogger } from '../for-angular.module';\nimport { DecafRepository } from '../components/list/constants';\nimport { Repository } from '@decaf-ts/core';\nimport { RamAdapter } from '@decaf-ts/core/ram';\n\n/**\n * @description Base component class that provides common functionality for all Decaf components.\n * @summary The NgxBaseComponent serves as the foundation for all Decaf UI components, providing\n * shared functionality for localization, element references, and styling. This abstract class\n * implements common properties and methods that are used across the component library, ensuring\n * consistent behavior and reducing code duplication. Components that extend this class inherit\n * its capabilities for handling translations, accessing DOM elements, and applying custom styling.\n *\n * @template M - The model type that this component works with\n * @param {string} instance - The component instance token used for identification\n * @param {string} locale - The locale to be used for translations\n * @param {StringOrBoolean} translatable - Whether the component should be translated\n * @param {string} className - Additional CSS classes to apply to the component\n * @param {\"ios\" | \"md\" | undefined} mode - Component platform style\n *\n * @component NgxBaseComponent\n * @example\n * ```typescript\n * @Component({\n * selector: 'app-my-component',\n * templateUrl: './my-component.component.html',\n * styleUrls: ['./my-component.component.scss']\n * })\n * export class MyComponent extends NgxBaseComponent {\n * constructor(@Inject('instanceToken') instance: string) {\n * super(instance);\n * }\n *\n * ngOnInit() {\n * this.initialize();\n * // Component-specific initialization\n * }\n * }\n * ```\n * @mermaid\n * sequenceDiagram\n * participant App as Application\n * participant Comp as Component\n * participant Base as NgxBaseComponent\n * participant Engine as NgxRenderingEngine\n *\n * App->>Comp: Create component\n * Comp->>Base: super(instance)\n * Base->>Base: Set componentName & componentLocale\n *\n * App->>Comp: Set @Input properties\n * Comp->>Base: ngOnChanges(changes)\n *\n * alt model changed\n * Base->>Base: getModel(model)\n * Base->>Engine: getDecorators(model, {})\n * Engine-->>Base: Return decorator metadata\n * Base->>Base: Configure mapper and item\n * Base->>Base: getLocale(translatable)\n * else locale/translatable changed\n * Base->>Base: getLocale(translatable)\n * end\n *\n * App->>Comp: ngOnInit()\n * Comp->>Base: initialize()\n * Base->>Base: Set initialized flag\n */\n@Component({\n standalone: true,\n template: '<div><div>',\n host: {'[attr.id]': 'uid'},\n})\nexport abstract class NgxBaseComponent implements OnChanges {\n /**\n * @description Reference to the component's 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 *\n * @type {ElementRef}\n * @memberOf NgxBaseComponent\n */\n @ViewChild('component', { read: ElementRef, static: true })\n component!: ElementRef;\n\n /**\n * @description The name of the component.\n * @summary Stores the name of the component, which is typically derived from the class name.\n * This property is used internally for various purposes such as logging, deriving the default\n * locale, and potentially for component identification in debugging or error reporting.\n *\n * The `componentName` is set during the component's initialization process and should not\n * be modified externally. It's marked as protected to allow access in derived classes while\n * preventing direct access from outside the component hierarchy.\n *\n * @type {string}\n * @protected\n * @memberOf NgxBaseComponent\n *\n * @example\n * // Inside a derived component class\n * console.log(this.componentName); // Outputs: \"MyCustomComponent\"\n */\n componentName!: string;\n\n /**\n * @description Unique identifier for the renderer.\n * @summary A unique identifier used to reference the component's renderer instance.\n * This can be used for targeting specific renderer instances when multiple components\n * are present on the same page.\n *\n * @type {string}\n * @memberOf NgxBaseComponent\n */\n @Input()\n rendererId!: string;\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 NgxBaseComponent\n */\n @Input()\n model!: Model | undefined;\n\n /**\n * @description The repository for interacting with the data model.\n * @summary Provides a connection to the data layer for retrieving and manipulating data.\n * This is an instance of the `DecafRepository` class from the `@decaf-ts/core` package,\n * which is initialized in the `repository` getter method.\n *\n * The repository is used to perform CRUD (Create, Read, Update, Delete) operations on the\n * data model, such as fetching data, creating new items, updating existing items, and deleting\n * items. It also provides methods for querying and filtering data based on specific criteria.\n *\n * @type {DecafRepository<Model>}\n * @private\n * @memberOf NgxBaseComponent\n */\n protected _repository?: DecafRepository<Model>;\n\n /**\n * @description Dynamic properties configuration object.\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 *\n * @type {Record<string, unknown>}\n * @default {}\n * @memberOf NgxBaseComponent\n */\n @Input()\n props: Record<string, unknown> = {};\n\n /**\n * @description Configuration for list item rendering\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 *\n * @type {Record<string, unknown>}\n * @default {tag: \"\"}\n * @memberOf NgxBaseComponent\n */\n @Input()\n item: Record<string, unknown> = { tag: '' };\n\n /**\n * @description Primary key field name for the 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 *\n * @type {string}\n * @default 'id'\n * @memberOf NgxBaseComponent\n */\n @Input()\n pk!: string;\n\n /**\n * @description Base route for navigation related to this component.\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.\n *\n * @type {string}\n * @memberOf NgxBaseComponent\n */\n @Input()\n route!: string;\n\n /**\n * @description Available CRUD operations for this component.\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.\n *\n * @default [OperationKeys.READ]\n * @memberOf NgxBaseComponent\n */\n @Input()\n operations: CrudOperations[] = [OperationKeys.READ];\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 * @memberOf NgxBaseComponent\n */\n @Input()\n uid!: string | number;\n\n /**\n * @description Field mapping configuration.\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 *\n * @type {Record<string, string>}\n * @memberOf NgxBaseComponent\n */\n @Input()\n mapper: Record<string, string> = {};\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 NgxBaseComponent\n */\n @Input()\n locale!: string;\n\n /**\n * @description Determines if the component should be translated.\n * @summary Controls whether the component's text content should be processed for translation.\n * When true, the component will attempt to translate text using the specified locale.\n * When false, text is displayed as-is without translation. This property accepts either\n * a boolean value or a string that can be converted to a boolean (e.g., 'true', 'false', '1', '0').\n *\n * @type {StringOrBoolean}\n * @default false\n * @memberOf NgxBaseComponent\n */\n @Input()\n translatable: StringOrBoolean = true;\n\n /**\n * @description Additional CSS class names to apply to the component.\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 *\n * @type {string}\n * @default \"\"\n * @memberOf NgxBaseComponent\n */\n @Input()\n className: string = '';\n\n /**\n * @description Component platform style.\n * @summary Controls the visual appearance of the component based on platform design guidelines.\n * The 'ios' mode follows iOS design patterns, while 'md' (Material Design) follows Android/Google\n * design patterns. This property affects various visual aspects such as animations, form elements,\n * and icons. Setting this property allows components to maintain platform-specific styling\n * for a more native look and feel.\n *\n * @type {(\"ios\" | \"md\" | undefined)}\n * @default \"md\"\n * @memberOf NgxBaseComponent\n */\n @Input()\n mode: 'ios' | 'md' | undefined = 'md';\n\n /**\n * @description The locale derived from the component's class name.\n * @summary Stores the automatically derived locale based on the component's class name.\n * This is determined during component initialization and serves as a fallback when no\n * explicit locale is provided via the locale input property. The derivation is handled\n * by the getLocaleContext utility function, which extracts a locale identifier\n * from the component's class name.\n *\n * @type {string}\n * @memberOf NgxBaseComponent\n */\n componentLocale!: string;\n\n /**\n * @description Controls whether child components should be rendered\n * @summary Determines if child components should be rendered by the component.\n * This can be set to a boolean value or a string that can be converted to a boolean.\n * When true, child components defined in the model will be rendered. When false,\n * child components will be skipped. This provides control over the rendering depth.\n *\n * @type {string | StringOrBoolean}\n * @default true\n * @memberOf NgxBaseComponent\n */\n @Input()\n renderChild: string | StringOrBoolean = true;\n\n /**\n * @description Flag indicating if the component has been initialized\n * @summary Tracks whether the component has completed its initialization process.\n * This flag is used to prevent duplicate initialization and to determine if\n * certain operations that require initialization can be performed.\n *\n * @type {boolean}\n * @default false\n */\n initialized: boolean = false;\n\n /**\n * @description Event emitter for custom renderer events.\n * @summary Emits custom events that occur within child components or the layout itself.\n * This allows parent components to listen for and respond to user interactions or\n * state changes within the grid layout. Events are passed up the component hierarchy\n * to enable coordinated behavior across the application.\n *\n * @type {EventEmitter<RendererCustomEvent>}\n * @memberOf NgxBaseComponent\n */\n @Output()\n listenEvent: EventEmitter<RendererCustomEvent> = new EventEmitter<RendererCustomEvent>();\n\n /**\n * @description Reference to the rendering engine instance\n * @summary Provides access to the NgxRenderingEngine singleton instance,\n * which handles the rendering of components based on model definitions.\n * This engine is used to extract decorator metadata and render child components.\n *\n * @type {NgxRenderingEngine}\n */\n renderingEngine: NgxRenderingEngine =\n NgxRenderingEngine.get() as unknown as NgxRenderingEngine;\n\n /**\n * @description Logger instance for the component.\n * @summary Provides logging capabilities for the component, allowing for consistent\n * and structured logging of information, warnings, and errors. This logger is initialized\n * in the ngOnInit method using the getLogger function from the ForAngularModule.\n *\n * The logger is used throughout the component to record important events, debug information,\n * and potential issues. It helps in monitoring the component's behavior, tracking the flow\n * of operations, and facilitating easier debugging and maintenance.\n *\n * @type {Logger}\n * @private\n * @memberOf NgxBaseComponent\n */\n logger!: Logger;\n\n /**\n * @description Creates an instance of NgxBaseComponent.\n * @summary Initializes a new instance of the base component with the provided instance token.\n * This constructor sets up the fundamental properties required by all Decaf components,\n * including the component name, locale settings, and logging capabilities. The instance\n * token is used for component identification and locale derivation.\n *\n * The constructor performs the following initialization steps:\n * 1. Sets the componentName from the provided instance token\n * 2. Derives the componentLocale from the class name using utility functions\n * 3. Initializes the logger instance for the component\n *\n * @param {string} instance - The component instance token used for identification\n *\n * @mermaid\n * sequenceDiagram\n * participant A as Angular\n * participant C as Component\n * participant B as NgxBaseComponent\n * participant U as Utils\n * participant L as Logger\n *\n * A->>C: new Component(instance)\n * C->>B: super(instance)\n * B->>B: Set componentName = instance\n * B->>U: getLocaleContext(instance)\n * U-->>B: Return derived locale\n * B->>B: Set componentLocale\n * B->>L: getLogger(this)\n * L-->>B: Return logger instance\n * B->>B: Set logger\n *\n * @memberOf NgxBaseComponent\n */\n // eslint-disable-next-line @angular-eslint/prefer-inject\n protected constructor(@Inject('instanceToken') protected instance: string) {\n this.componentName = instance;\n this.componentLocale = getLocaleContext(instance);\n this.logger = getLogger(this);\n this.getLocale(this.translatable);\n this.uid = generateRandomValue(12);\n }\n\n /**\n * @description Getter for the repository instance.\n * @summary Provides a connection to the data layer for retrieving and manipulating data.\n * This method initializes the `_repository` property if it is not already set, ensuring\n * that a single instance of the repository is used throughout the component.\n *\n * The repository is used to perform CRUD operations on the data model, such as fetching data,\n * creating new items, updating existing items, and deleting items. It also provides methods\n * for querying and filtering data based on specific criteria.\n *\n * @returns {DecafRepository<Model>} The initialized repository instance.\n * @private\n * @memberOf NgxBaseComponent\n */\n protected get repository(): DecafRepository<Model> {\n try {\n if (!this._repository) {\n const modelName = (this.model as Model).constructor.name\n const constructor = Model.get(modelName);\n if (!constructor)\n throw new InternalError(\n 'Cannot find model. was it registered with @model?',\n );\n let dbAdapterFlavour = getOnWindow('dbAdapterFlavour');\n if(!dbAdapterFlavour && isDevelopmentMode()) {\n const adapter = new RamAdapter();\n dbAdapterFlavour = adapter.flavour;\n }\n this._repository = Repository.forModel(constructor, dbAdapterFlavour as string);\n this.model = new constructor() as Model;\n if(this.model && !this.pk)\n this.pk = (this._repository as unknown as DecafRepository<Model>).pk || 'id';\n }\n } catch (error: unknown) {\n throw new InternalError(\n (error as Error)?.message || error as string\n );\n }\n return this._repository;\n }\n\n /**\n * @description Handles changes to component inputs\n * @summary This Angular lifecycle hook is called when input properties change.\n * It responds to changes in the model, locale, or translatable properties by\n * updating the component's internal state accordingly. When the model changes,\n * it calls getModel to process the new model and getLocale to update the locale.\n * When locale or translatable properties change, it calls getLocale to update\n * the translation settings.\n *\n * @param {SimpleChanges} changes - Object containing changed properties\n * @return {void}\n */\n ngOnChanges(changes: SimpleChanges): void {\n if (changes[BaseComponentProps.MODEL]) {\n const { currentValue } = changes[BaseComponentProps.MODEL];\n if (currentValue) this.getModel(currentValue);\n this.getLocale(this.translatable);\n }\n if (\n changes[BaseComponentProps.INITIALIZED] ||\n changes[BaseComponentProps.LOCALE] ||\n changes[BaseComponentProps.TRANSLATABLE]\n )\n this.getLocale(this.translatable);\n }\n\n /**\n * @description Gets the appropriate locale string based on the translatable flag and available locales.\n * @summary Determines which locale string to use for translation based on the translatable flag\n * and available locale settings. This method first converts the translatable parameter to a boolean\n * using the stringToBoolean utility function. If translatable is false, it returns an empty string,\n * indicating no translation should be performed. If translatable is true, it checks for an explicitly\n * provided locale via the locale property. If no explicit locale is available, it falls back to the\n * componentLocale derived from the component's class name.\n *\n * @param {StringOrBoolean} translatable - Whether the component should be translated\n * @return {string} The locale string to use for translation, or empty string if not translatable\n *\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant N as NgxBaseComponent\n * participant S as StringUtils\n *\n * C->>N: getLocale(translatable)\n * N->>S: stringToBoolean(translatable)\n * S-->>N: Return boolean value\n * N->>N: Store in this.translatable\n * alt translatable is false\n * N-->>C: Return empty string\n * else translatable is true\n * alt this.locale is defined\n * N-->>C: Return this.locale\n * else this.locale is not defined\n * N-->>C: Return this.componentLocale\n * end\n * end\n */\n getLocale(translatable: StringOrBoolean): string {\n this.translatable = stringToBoolean(translatable);\n if (!this.translatable)\n return '';\n if (!this.locale)\n this.locale = this.componentLocale;\n return this.locale;\n }\n\n /**\n * @description Gets the route for the component\n * @summary Retrieves the route path for the component, generating one based on the model\n * if no route is explicitly set. This method checks if a route is already defined, and if not,\n * it creates a default route based on the model's constructor name. The generated route follows\n * the pattern '/model/{ModelName}'. This is useful for automatic routing in CRUD operations.\n *\n * @return {string} The route path for the component, or empty string if no route is available\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 sets the component's model\n * @summary Processes the provided model parameter, which can be either a Model instance\n * or a string identifier. If a string is provided, it attempts to resolve the actual model\n * from the injectables registry. After resolving the model, it calls setModelDefinitions\n * to configure the component based on the model's metadata.\n *\n * @param {string | Model} model - The model instance or identifier string\n * @return {void}\n */\n getModel(model: string | Model): void {\n if (!(model instanceof Model))\n this.model = getInjectablesRegistry().get(model) as Model;\n this.setModelDefinitions(this.model as Model);\n }\n\n /**\n * @description Configures component properties based on model metadata\n * @summary Extracts and applies configuration from the model's decorators to set up\n * the component. This method uses the rendering engine to retrieve decorator metadata\n * from the model, then configures the component's mapper and item properties accordingly.\n * It ensures the route is properly set and merges various properties from the model's\n * metadata into the component's configuration.\n *\n * @param {Model} model - The model to extract configuration from\n * @return {void}\n */\n setModelDefinitions(model: Model): void {\n if (model instanceof Model) {\n this.getRoute();\n this.model = model;\n const field = this.renderingEngine.getDecorators(this.model as Model, {});\n const{ props, item, children } = field;\n this.props = Object.assign(props || {}, {children: children || []});\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 };\n }\n }\n\n /**\n * @description Initializes the component\n * @summary Performs one-time initialization of the component. This method checks if\n * the component has already been initialized to prevent duplicate initialization.\n * When called for the first time, it sets the initialized flag to true and logs\n * an initialization message with the component name. This method is typically called\n * during the component's lifecycle setup.\n */\n initialize(): void {\n this.initialized = true;\n }\n\n /**\n * @description Handles custom events from child components.\n * @summary Receives events from child renderer components and forwards them to parent\n * components through the listenEvent output. This creates an event propagation chain\n * that allows events to bubble up through the component hierarchy, enabling coordinated\n * responses to user interactions across the layout structure.\n *\n * @param {RendererCustomEvent} event - The custom event from a child component\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant C as Child Component\n * participant L as NgxBaseComponent\n * participant P as Parent Component\n *\n * C->>L: Emit RendererCustomEvent\n * L->>L: handleEvent(event)\n * L->>P: listenEvent.emit(event)\n * Note over P: Handle event in parent\n *\n * @memberOf NgxBaseComponent\n */\n handleEvent(event: RendererCustomEvent): void {\n this.listenEvent.emit(event);\n }\n\n /**\n * @description Tracks items in ngFor loops for optimal change detection.\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 *\n * @param {number} index - The index of the item in the list\n * @param {KeyValue | string | number} item - The item data to track\n * @returns {string | number} A unique identifier for the item\n * @memberOf NgxBaseComponent\n */\n trackItemFn(index: number, item: KeyValue | string | number): string | number {\n return `${index}-${item}`;\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 *\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 *\n * @param {KeyValue} instance - The component instance object to process\n * @return {void}\n *\n * @mermaid\n * sequenceDiagram\n * participant C as Component\n * participant B as NgxBaseComponent\n * participant P as Props Object\n *\n * C->>B: parseProps(instance)\n * B->>B: Get Object.keys(instance)\n * loop For each key in instance\n * B->>P: Check if key exists in this.props\n * alt Key exists in props\n * B->>B: Set this[key] = this.props[key]\n * else Key not in props\n * Note over B: Skip this key\n * end\n * end\n *\n * @protected\n * @memberOf NgxBaseComponent\n */\n protected parseProps(instance: KeyValue): void {\n Object.keys(instance).forEach((key) => {\n if(Object.keys(this.props).includes(key))\n (this as KeyValue)[key] = this.props[key];\n })\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 './NgxBaseComponent';\nexport * from './NgxCrudFormField';\nexport * from './NgxFormService';\n","import { CrudFormOptions } from './types';\n\nexport const CssClasses = {\n BUTTONS_CONTAINER: 'buttons-container',\n};\n\nexport const DefaultFormReactiveOptions: CrudFormOptions = {\n buttons: {\n submit: {\n text: 'Submit',\n },\n clear: {\n text: 'Clear',\n },\n },\n};\n","import {\n Component,\n ElementRef,\n EventEmitter,\n inject,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ViewChild,\n} from '@angular/core';\nimport { Location } from '@angular/common';\nimport { FormGroup } from '@angular/forms';\nimport { IFormElement } from '../../engine/interfaces';\nimport { NgxFormService } from '../../engine/NgxFormService';\nimport { CrudFormEvent, Dynamic, EventConstants, FieldUpdateMode, HandlerLike, HTMLFormTarget, RenderedModel } from '../../engine';\nimport { CrudFormOptions } from './types';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport { DefaultFormReactiveOptions } from './constants';\nimport { ForAngularModule, getLogger } from '../../for-angular.module';\nimport { IonIcon } from '@ionic/angular/standalone';\nimport { Model } from '@decaf-ts/decorator-validation';\nimport { Logger } from '@decaf-ts/logging';\nimport { generateRandomValue } from '../../helpers';\n\n\n/**\n * @component CrudFormComponent\n * @example <ngx-decaf-crud-form\n * action=\"create\"\n * operation=\"create\"\n * formGroup=\"formGroup\"\n * rendererId=\"rendererId\"\n * submitEvent=\"submitEvent\"\n * target=\"_self\"\n * method=\"event\">\n * </ngx-decaf-crud-form>\n *\n * @param {string} action - The action to be performed (create, read, update, delete)\n * @param {CrudOperations} operation - The CRUD operation being performed (create, read, update, delete)\n * @param {FormGroup} formGroup - The form group\n * @param {string} rendererId - The renderer id\n * @param {SubmitEvent} submitEvent - The submit event\n * @param {string} target - The target\n * @param {string} method - The method\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: [ForAngularModule, IonIcon],\n host: {'[attr.id]': 'uid'},\n})\n/**\n * @class CrudFormComponent\n * @implements OnInit, IFormElement, OnDestroy, RenderedModel\n *\n * @description\n * The `CrudFormComponent` is an Angular component designed to provide a flexible and extensible form interface for performing CRUD (Create, Read, Update, Delete) operations on a data model. It integrates with Angular's reactive forms and supports advanced configuration, validation, and event handling for a wide range of use cases.\n *\n * @summary\n * - Supports dynamic form rendering based on the provided data model and operation type.\n * - Handles form validation, submission, and reset logic with customizable behavior.\n * - Emits structured events for form actions, enabling decoupled business logic.\n * - Integrates with external services for logging, form management, and navigation.\n * - Provides extensive configuration options for form appearance and behavior.\n *\n * @inputs\n * - `model`: The repository model for data operations.\n * - `modelId`: The primary data model instance for CRUD operations.\n * - `updateOn`: Determines when form field validation is triggered (`change`, `blur`, or `submit`).\n * - `component`: Reference to the reactive form DOM element.\n * - `target`: Specifies the form submission target (e.g., `_self`, `_blank`).\n * - `method`: Defines the form submission strategy (`get`, `post`, or `event`).\n * - `options`: Configuration options for form behavior and rendering.\n * - `action`: Optional custom action identifier for submission context.\n * - `operation`: The current CRUD operation being performed (required).\n * - `handlers`: Custom event handlers for form actions.\n * - `formGroup`: Angular FormGroup for form state management.\n * - `childOf`: Path to the parent FormGroup if nested.\n * - `rendererId`: Unique identifier for the form renderer.\n * - `uid`: Unique identifier for the current record.\n * - `allowClear`: Enables or disables form clearing functionality.\n *\n * @outputs\n * - `submitEvent`: Emits `CrudFormEvent` objects on form submission.\n *\n * @protected\n * - `OperationKeys`: Reference to CRUD operation constants for template usage.\n *\n * @private\n * - `logger`: Logger instance for structured logging.\n * - `location`: Angular Location service for navigation.\n *\n * @lifecycle\n * - `ngOnInit`: Initializes the component, configures logger, merges options, and sets form state based on operation.\n * - `ngOnDestroy`: Cleans up resources and unregisters the FormGroup.\n *\n * @methods\n * - `submit(event: SubmitEvent)`: Handles form submission, validation, and event emission.\n * - `handleReset()`: Resets the form or navigates back based on the operation.\n * - `handleDelete()`: Emits a delete event for the current record.\n *\n * @usage\n * Use this component within Angular templates to provide a robust CRUD form interface. Configure inputs to match your data model and desired behavior, and handle output events to implement custom business logic.\n */\nexport class CrudFormComponent implements OnInit, IFormElement, OnDestroy, RenderedModel {\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 CrudFormComponent\n */\n @Input()\n model!: Model | undefined;\n\n\n /**\n * @description The primary data model used for CRUD operations.\n * @summary This input provides the main Model instance that the form interacts with for\n * creating, reading, updating, or deleting records. It serves as the source of schema\n * and validation rules for the form fields, and is required for most operations except\n * for certain read or delete scenarios.\n *\n * @type {Model | undefined}\n * @memberOf CrudFormComponent\n */\n @Input()\n modelId!: Model | undefined;\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 * @memberOf CrudFormComponent\n */\n @Input()\n updateOn: FieldUpdateMode = 'change';\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 * @memberOf CrudFormComponent\n */\n @ViewChild('reactiveForm', { static: false, read: ElementRef })\n component!: ElementRef;\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 * @memberOf CrudFormComponent\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 * @memberOf CrudFormComponent\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 {CrudFormOptions}\n * @memberOf CrudFormComponent\n */\n @Input()\n options!: CrudFormOptions;\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 * @memberOf CrudFormComponent\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 * @memberOf CrudFormComponent\n */\n @Input({ required: true })\n operation!: CrudOperations;\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 * @memberOf CrudFormComponent\n */\n @Input()\n handlers!: HandlerLike;\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 * @memberOf CrudFormComponent\n */\n @Input()\n formGroup!: FormGroup | undefined;\n\n /**\n * @description Path to the parent FormGroup, if nested.\n * @summary Full dot-delimited path of the parent FormGroup. Set only when is part of a nested structure.\n *\n * @type {string}\n * @memberOf CrudFormComponent\n */\n @Input()\n childOf?: string;\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 * @memberOf CrudFormComponent\n */\n @Input()\n rendererId!: string;\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 * @memberOf CrudFormComponent\n */\n @Input()\n uid: string = generateRandomValue(12);\n\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 * @memberOf CrudFormComponent\n */\n @Input()\n allowClear: boolean = true;\n\n /**\n * @description Reference to CRUD operation constants for template usage.\n * @summary Exposes the OperationKeys enum to the component template, enabling\n * conditional rendering and behavior based on operation types. This protected\n * readonly property ensures that template logic can access operation constants\n * while maintaining encapsulation and preventing accidental modification.\n *\n * @protected\n * @readonly\n * @memberOf CrudFormComponent\n */\n protected readonly OperationKeys = OperationKeys;\n\n\n /**\n * @description Event emitter for form submission events.\n * @summary Emits CrudFormEvent 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<CrudFormEvent>}\n * @memberOf CrudFormComponent\n */\n @Output()\n submitEvent: EventEmitter<CrudFormEvent> = new EventEmitter<CrudFormEvent>();\n\n /**\n * @description Logger instance for the component.\n * @summary Provides logging capabilities for the component, allowing for consistent\n * and structured logging of information, warnings, and errors. This logger is initialized\n * in the ngOnInit method using the getLogger function from the ForAngularModule.\n *\n * The logger is used throughout the component to record important events, debug information,\n * and potential issues. It helps in monitoring the component's behavior, tracking the flow\n * of operations, and facilitating easier debugging and maintenance.\n *\n * @type {Logger}\n * @private\n * @memberOf CrudFormComponent\n */\n private logger!: Logger;\n\n /**\n * @description Angular Location service.\n * @summary Injected service that provides access to the browser's URL and history.\n * This service is used for interacting with the browser's history API, allowing\n * for back navigation and URL manipulation outside of Angular's router.\n *\n * @private\n * @type {Location}\n * @memberOf CrudFormComponent\n */\n private location: Location = inject(Location);\n\n // ngAfterViewInit() {\n // if (![OperationKeys.READ, OperationKeys.DELETE].includes(this.operation))\n // NgxFormService.formAfterViewInit(this, this.rendererId);\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 async ngOnInit(): Promise<void> {\n if (!this.logger)\n this.logger = getLogger(this);\n if (this.operation === OperationKeys.READ || this.operation === OperationKeys.DELETE)\n this.formGroup = undefined;\n this.options = Object.assign(\n {},\n DefaultFormReactiveOptions,\n this.options || {},\n );\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 * @memberOf CrudFormComponent\n */\n ngOnDestroy(): void {\n if (this.formGroup)\n NgxFormService.unregister(this.formGroup);\n }\n\n /**\n * @description Handles form submission with validation and event emission.\n * @summary Processes form submission by first preventing default browser behavior,\n * then validating all form fields using NgxFormService. If validation passes,\n * extracts form data and emits a submitEvent with the data, component information,\n * and any associated handlers. Returns false if validation fails.\n *\n * @param {SubmitEvent} event - The browser's native form submit event\n * @returns {Promise<boolean | void>} Returns false if validation fails, void if successful\n * @memberOf CrudFormComponent\n */\n async submit(event: SubmitEvent): Promise<boolean | void> {\n event.preventDefault();\n event.stopImmediatePropagation();\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: 'CrudFormComponent',\n name: this.action || EventConstants.SUBMIT,\n handlers: this.handlers,\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 * @memberOf CrudFormComponent\n */\n handleReset(): void {\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 /**\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: EventConstants.SUBMIT,\n });\n }\n\n}\n","@if(operation !== 'read' && operation !== 'delete') {\n <form #reactiveForm [id]=\"rendererId\" [formGroup]=\"formGroup\" (submit)=\"submit($event)\" novalidate [target]=\"target\">\n <ng-content #formContent></ng-content>\n <div class=\"dcf-buttons-container dcf-grid dcf-grid-collapse dcf-flex dcf-flex-left\">\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 {{ 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 </form>\n} @else {\n <div [class]=\"'dcf-buttons-container dcf-grid dcf-grid-collapse dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if(operation === OperationKeys.READ && 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 </div>\n}\n\n","import { Component, inject, Input, OnInit } from '@angular/core';\nimport {\n IonCard,\n IonCardContent,\n IonIcon,\n IonTitle\n}\nfrom '@ionic/angular/standalone';\nimport * as allIcons from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { Dynamic, StringOrBoolean } from '../../engine';\nimport { stringToBoolean } from '../../helpers';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { TranslateService } from '@ngx-translate/core';\nimport { FunctionLike } from '../../engine/types';\nimport { Router } from '@angular/router';\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 --|> NgxBaseComponent\n * EmptyStateComponent --|> OnInit\n *\n * @extends {NgxBaseComponent}\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 ForAngularModule,\n IonCard,\n IonCardContent,\n IonTitle,\n IonIcon\n ]\n\n})\nexport class EmptyStateComponent extends NgxBaseComponent implements OnInit {\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 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 = '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 subtitle: string = \"\";\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 \"ti-info-square-rounded\"\n * @memberOf EmptyStateComponent\n */\n @Input()\n icon: string = \"ti-info-square-rounded\";\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?: 'large' | 'small' = '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 {PredefinedColors | undefined}\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: '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 * @description Service for handling navigation operations.\n * @summary Injected service that provides methods for navigating between routes.\n * This service is used when the buttonLink is a string URL to navigate to that location.\n *\n * @private\n * @type {Router}\n * @memberOf EmptyStateComponent\n */\n private router: Router = inject(Router);\n\n private sanitizer: DomSanitizer = inject(DomSanitizer);\n\n private translate: TranslateService = inject(TranslateService);\n\n searchSubtitle!: SafeHtml\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 addIcons(allIcons);\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 async ngOnInit(): Promise<void> {\n this.parseProps(this);\n this.translatable = stringToBoolean(this.translatable);\n this.showIcon = stringToBoolean(this.showIcon);\n this.locale = this.getLocale(this.translatable);\n\n // if(this.translatable) {\n // this.title = generateLocaleFromString(this.locale, this.title);\n // this.subtitle = generateLocaleFromString(this.locale, this.subtitle);\n // this.buttonText = generateLocaleFromString(this.locale, this.buttonText);\n // }\n\n this.titleColor = `dcf-title color-${this.titleColor}`;\n this.subtitleColor = `dcf-subtitle color-${this.titleColor}`;\n\n if(this.searchValue && this.translatable)\n this.searchSubtitle = await this.getSearchSubtitle(this.subtitle as string);\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>}\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> {\n const fn = this.buttonLink;\n if(!fn)\n return false;\n if(fn instanceof Function)\n return fn();\n 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 ('value0') 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, {'value0': 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.instant(content, {'value0': this.searchValue});\n return this.sanitizer.bypassSecurityTrustHtml(result);\n }\n}\n","\n<ion-card [id]=\"uid\" [ngClass]=\"className\">\n <ion-card-content>\n @if(icon && showIcon) {\n <div class=\"dcf-icon-container\">\n <ion-icon\n name=\"alert-circle-outline\"\n size=\"large\"\n color=\"danger\"\n />\n </div>\n }\n @if(title) {\n <h5 [class]=\"titleColor\" [innerHTML]=\"title\"></h5>\n }\n @if(subtitle) {\n @if(!searchValue) {\n <p [class]=\"subtitleColor\" [innerHTML]=\"subtitle\"></p>\n } @else {\n <p [class]=\"subtitleColor\" [innerHTML]=\"searchSubtitle\"></p>\n }\n }\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 </ion-card-content>\n</ion-card>\n","import { Directive, ElementRef, inject, OnInit, Injector } from '@angular/core';\n\n\n@Directive({\n selector: '[decafCollapsable]',\n standalone: true\n})\nexport class CollapsableDirective implements OnInit{\n\n private element: ElementRef<HTMLElement> = inject(ElementRef);\n private injector = inject(Injector);\n // constructor() {}\n\n ngOnInit() {\n const element = this.element?.nativeElement;\n if(element) {\n const requiredFields = element.querySelectorAll('[required]') as NodeListOf<Element>;\n if(requiredFields.length) {\n const accordion = element?.closest('ion-accordion-group') as HTMLElement;\n accordion.setAttribute('value', 'open');\n }\n }\n }\n\n // private element: ElementRef<HTMLElement> = inject(ElementRef);\n // private renderer = inject(Renderer2);\n\n // ngOnInit() {\n // const element = this.element?.nativeElement;\n // if(element) {\n // const requiredFields = element.querySelectorAll('[required]') as NodeListOf<Element>;\n\n // // Find the parent fieldset component and set required attribute if there are required fields\n // const fieldsetElement = element.closest('ngx-decaf-fieldset');\n // if (fieldsetElement && requiredFields.length > 0) {\n // // Set a data attribute that the fieldset component can read\n // this.renderer.setAttribute(fieldsetElement, 'data-has-required-fields', 'true');\n\n // // Dispatch a custom event to notify the fieldset component\n // const event = new CustomEvent('requiredFieldsDetected', {\n // detail: { hasRequiredFields: true, count: requiredFields.length },\n // bubbles: true\n // });\n // fieldsetElement.dispatchEvent(event);\n\n // const accordion = element?.closest('ion-accordion-group') as HTMLElement;\n // if (accordion) {\n // accordion.setAttribute('value', 'open');\n // }\n // }\n // }\n // }\n}\n","\nimport { AfterViewInit, ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, inject, Input, ViewChild, Renderer2, OnInit } from '@angular/core';\nimport { Dynamic, EventConstants, HandlerLike, HTMLFormTarget, KeyValue } from '../../engine';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { CollapsableDirective } from '../../directives/collapsable.directive';\nimport { IonAccordion, IonAccordionGroup, IonButton, IonItem, IonLabel, IonList, ItemReorderEventDetail, IonReorderGroup, IonReorder } from '@ionic/angular/standalone';\nimport { cleanSpaces, generateRandomValue, itemMapper, windowEventEmitter } from '../../helpers';\nimport { FormArray, FormControl, FormGroup } from '@angular/forms';\nimport { NgxBaseComponent } from '../../engine';\nimport { alertCircleOutline, createOutline } from 'ionicons/icons';\nimport { TranslateService } from '@ngx-translate/core';\nimport { IFieldSetItem, IFieldSetValidationEvent } from '../../engine/interfaces';\nimport { addIcons } from 'ionicons';\n\n\n\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 ForAngularModule\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: [CUSTOM_ELEMENTS_SCHEMA],\n imports: [ForAngularModule, IonAccordionGroup, IonAccordion, IonList, IonItem, IonLabel, IonReorder, IonButton, IonReorderGroup, CollapsableDirective],\n host: {'[attr.id]': 'overriode '},\n})\nexport class FieldsetComponent extends NgxBaseComponent implements OnInit, AfterViewInit {\n\n\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 /**\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 name: string = 'Child';\n\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 childOf: string = 'Child';\n\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 override uid: string = generateRandomValue(12);\n\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 The current CRUD operation context.\n * @summary Determines the component's initial behavior and state based on the current operation.\n * This input is crucial for auto-state management: READ and DELETE operations automatically\n * open the fieldset to show content, while CREATE and UPDATE operations keep it closed\n * initially. This provides an intuitive user experience aligned with operation semantics.\n *\n * @type {OperationKeys}\n * @default OperationKeys.READ\n * @memberOf FieldsetComponent\n */\n /**\n * @description The CRUD operation type for the current fieldset context.\n * @summary Determines the component's initial behavior and state based on the current operation.\n * This input is crucial for auto-state management: READ and DELETE operations automatically\n * open the fieldset to show content, while CREATE and UPDATE operations keep it closed\n * initially. This provides an intuitive user experience aligned with operation semantics.\n *\n * @type {OperationKeys}\n * @default OperationKeys.READ\n * @memberOf FieldsetComponent\n */\n @Input()\n operation: OperationKeys = OperationKeys.READ;\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 * @memberOf FieldsetComponent\n */\n @Input()\n formGroup!: FormArray;\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 Form target attribute for nested form submissions.\n * @summary Specifies where to display the response after submitting forms contained within\n * the fieldset. This attribute mirrors the HTML form target behavior, allowing control over\n * whether form submissions open in the same window, new window, or specific frame. Useful\n * for complex form workflows and multi-step processes.\n *\n * @type {HTMLFormTarget}\n * @default '_self'\n * @memberOf FieldsetComponent\n */\n @Input()\n target: HTMLFormTarget = '_self';\n\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 = false;\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 Event handler functions for custom fieldset actions.\n * @summary A record of event handler functions keyed by event names that can be triggered\n * within the fieldset. These handlers provide extensibility for custom business logic\n * and can be invoked for various fieldset operations and user interactions.\n *\n * @type {HandlerLike}\n * @memberOf FieldsetComponent\n */\n @Input()\n handlers!: HandlerLike;\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 /**\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 Reference to CRUD operation constants for template usage.\n * @summary Exposes the OperationKeys enum to the component template, enabling conditional\n * rendering and behavior based on operation types. This protected readonly property ensures\n * that template logic can access operation constants while maintaining encapsulation and\n * preventing accidental modification of the enum values.\n *\n * @type {CrudOperations}\n * @default OperationKeys.CREATE\n * @memberOf FieldsetComponent\n */\n protected readonly OperationKeys: CrudOperations = OperationKeys.CREATE;\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 * @private\n * @type {ChangeDetectorRef}\n * @memberOf FieldsetComponent\n */\n private 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 * @private\n * @type {Renderer2}\n * @memberOf FieldsetComponent\n */\n private 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 * @private\n * @type {TranslateService}\n * @memberOf FieldsetComponent\n */\n private translateService: TranslateService = inject(TranslateService);\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 /**\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 /**\n * @description Component constructor that initializes the fieldset with icons and component name.\n * @summary Calls the parent NgxBaseComponent 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, 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 ngOnInit(): void {\n if(this.model)\n this._repository = this.repository;\n this.buttonLabel = this.translateService.instant(this.locale + '.add');\n this.buttonCancelLabel = this.translateService.instant(this.locale + '.cancel');\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 {void}\n * @memberOf FieldsetComponent\n */\n ngAfterViewInit(): void {\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(this.accordionComponent)\n this.renderer.setAttribute(accordionElement, 'value', 'open');\n } else {\n const inputs = this.component?.nativeElement.querySelectorAll('[required]');\n this.isRequired = inputs.length > 0;\n if(this.isRequired) {\n this.accordionComponent.value = 'open';\n this.handleAccordionToggle();\n }\n }\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 handleRemoveComponent(event: Event): void {\n event.stopImmediatePropagation();\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 /**\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(event?: CustomEvent<IFieldSetValidationEvent>): Promise<void> {\n if(event && event instanceof CustomEvent) {\n event.stopImmediatePropagation();\n const {formGroup, value, isValid} = event.detail;\n this.formGroup = formGroup as FormArray;\n if(!this.mapper)\n this.mapper = this.getMapper(value as KeyValue);\n if(isValid ){\n this.isUniqueError = undefined;\n this.buttonLabel = this.translateService.instant(this.locale + '.add');\n this.setValue();\n } else {\n this.isUniqueError = (value as KeyValue)?.[this.pk] || undefined;\n }\n } else {\n windowEventEmitter(EventConstants.FIELDSET_ADD_GROUP, {\n component: this.component.nativeElement,\n index: this.value?.length,\n parent: this.childOf,\n operation: !this.updatingItem ? OperationKeys.CREATE : OperationKeys.UPDATE\n });\n }\n }\n\n\n /**\n * @description Handles item update operations with form state management.\n * @summary Locates an item in the form array for editing and prepares the component\n * for update mode. Updates the button label to reflect the edit state and stores\n * the item being updated. Triggers a window event to notify parent components.\n *\n * @param {string | number} value - The identifier value of the item to update\n * @param {number} index - The array index position of the item\n * @returns {void}\n * @memberOf FieldsetComponent\n */\n handleUpdateItem(value: string | number, index: number): void {\n const item = this.formGroup.controls.find(control => `${control.get(this.pk)?.value}`.toLowerCase() === cleanSpaces(`${value}`, true)) as FormControl;\n if(item) {\n this.buttonLabel = this.translateService.instant(this.locale + '.update');\n this.updatingItem = Object.assign({}, item.value || {});\n windowEventEmitter(EventConstants.FIELDSET_UPDATE_GROUP, {\n parent: this.childOf,\n component: this.component.nativeElement,\n index: index\n });\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 windowEventEmitter(EventConstants.FIELDSET_UPDATE_GROUP, {\n parent: this.childOf,\n component: this.component.nativeElement,\n index: this.value?.length\n });\n }\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(value: string | undefined, event?: CustomEvent): void {\n if(event && event instanceof CustomEvent) {\n event.stopImmediatePropagation();\n return this.setValue();\n }\n const formArray = this.formGroup as FormArray;\n const arrayLength = formArray.length;\n for (let index = arrayLength - 1; index >= 0; index--) {\n const group = formArray.at(index) as FormGroup;\n if (cleanSpaces(group.get(this.pk)?.value) === cleanSpaces(value as string)) {\n windowEventEmitter(EventConstants.FIELDSET_REMOVE_GROUP, {\n parent: this.childOf,\n component: this.component.nativeElement,\n index,\n formGroup: group\n });\n }\n }\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]; // sua estrutura visual\n const formArray = this.formGroup as FormArray; // FormArray reativo\n\n if (fromIndex !== toIndex) {\n // Reordenar os dados visuais\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 // Reordenar os controles do FormArray\n const controlToMove = formArray.at(fromIndex);\n formArray.removeAt(fromIndex);\n formArray.insert(toIndex, controlToMove);\n }\n // Finaliza a operação de reorder do Ionic\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)\n event.stopImmediatePropagation();\n if(!this.hasValidationErrors) {\n this.accordionComponent.value = this.isOpen ? undefined : 'open';\n this.isOpen = !!this.accordionComponent.value;\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 {void}\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\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(({value}) => value);\n this.items = this.value\n .filter(v => v[this.pk] !== undefined)\n .map((v, index) => {\n return {\n ...itemMapper(v, this.mapper),\n index: index + 1\n } as IFieldSetItem;\n });\n const inputContainers = this.component.nativeElement.querySelectorAll('.dcf-input-item');\n inputContainers.forEach((container: HTMLElement) => {\n const input = container.querySelector('input, ion-input, ion-textarea, textarea') as HTMLInputElement | null;\n if(input)\n input.value = '';\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)\n this.pk = Object.keys(value)[0];\n if(!Object.keys(this.mapper).length)\n this.mapper['title'] = this.pk;\n this.mapper['index'] = \"index\";\n for(const key in value) {\n if(Object.keys(this.mapper).length >= 2 || Object.keys(this.mapper).length === Object.keys(value).length)\n break;\n if(!this.mapper['title']) {\n this.mapper['title'] = key;\n } else {\n this.mapper['description'] = key;\n }\n }\n return this.mapper;\n }\n}\n","\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n (fieldsetRemoveGroupEvent)=\"handleRemoveItem(undefined, $event)\"\n [class]=\"'dcf-fieldset ' + operation\"\n #component>\n <ion-accordion-group [ngClass]=\"{'open': isOpen, 'hasValidationErrors': hasValidationErrors}\" (validationErrorEvent)=\"handleValidationError($event)\" #accordionComponent>\n <ion-accordion value=\"open\">\n <ion-item slot=\"header\" (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>{{ name | translate }}</legend>\n </div>\n @if(!isRequired && ['create', 'update'].includes(operation)) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleRemoveComponent($event)\">\n <ion-icon name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n </div>\n </ion-item>\n <div slot=\"content\" [attr.aria-hidden]=\"!isOpen\">\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 [ngClass]=\"{'not-unique': item.title === isUniqueError}\" lines=\"full\" [button]=\"false\" [ngClass]=\"{'updating': updatingItem?.[pk] === item.title}\">\n @if(items?.length > 1 && !updatingItem) {\n <ion-reorder slot=\"start\">\n <ion-icon name=\"swap-vertical-outline\"></ion-icon>\n </ion-reorder>\n } @else {\n <div slot=\"start\">\n <ion-icon class=\"dcf-reorder-disabled\" size=\"small\" name=\"swap-vertical-outline\" disabled></ion-icon>\n </div>\n }\n <ion-label [color]=\"(item.title === isUniqueError && !updatingItem.title === 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 @if(!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleUpdateItem(item.title, $index)\">\n <ion-icon name=\"create-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n }\n\n @if(!updatingItem) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleRemoveItem(item.title)\">\n <ion-icon name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n }\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n <ng-content></ng-content>\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 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 <div class=\"dcf-margin-bottom dcf-grid dcf-grid-collapse dcf-flex\">\n @if(updatingItem) {\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ buttonCancelLabel }}\n </ion-button>\n }\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" (click)=\"handleCreateItem()\">\n <ion-icon name=\"add-outline\" slot=\"start\"></ion-icon>\n {{buttonLabel}}\n </ion-button>\n\n </div>\n }\n\n </div>\n </ion-accordion>\n </ion-accordion-group>\n</fieldset>\n\n","import { Component, EventEmitter, HostListener, Input, OnInit, Output } from '@angular/core';\nimport { AutocompleteTypes, PredefinedColors} from '@ionic/core';\nimport { StringOrBoolean } from '../../engine/types';\nimport {windowEventEmitter} from '../../helpers/utils';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { stringToBoolean } from '../../helpers/utils';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport { IonSearchbar } from '@ionic/angular/standalone';\nimport * as allIcons from 'ionicons/icons';\nimport { addIcons } from 'ionicons';\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 NgxBaseComponent 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 {NgxBaseComponent}\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: [ForAngularModule, IonSearchbar],\n})\nexport class SearchbarComponent extends NgxBaseComponent 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","import { Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport { IonChip, IonIcon, IonItem, IonLabel, IonSelect} from '@ionic/angular/standalone';\nimport { Dynamic, IFilterQuery, IFilterQueryItem } from '../../engine';\nimport { getWindowWidth, isDarkMode } from '../../helpers/utils';\nimport { debounceTime, fromEvent, Subscription } from 'rxjs';\nimport { OrderDirection, Repository } from '@decaf-ts/core';\nimport { Model } from '@decaf-ts/decorator-validation';\nimport { SearchbarComponent } from '../searchbar/searchbar.component';\nimport { addIcons } from 'ionicons';\nimport { chevronDownOutline, chevronUpOutline } from 'ionicons/icons';\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 ForAngularModule\n */\n@Dynamic()\n@Component({\n selector: 'ngx-decaf-filter',\n templateUrl: './filter.component.html',\n styleUrls: ['./filter.component.scss'],\n imports: [\n ForAngularModule,\n IonLabel,\n IonItem,\n IonChip,\n IonIcon,\n IonSelect,\n IonIcon,\n SearchbarComponent\n ],\n standalone: true,\n})\nexport class FilterComponent extends NgxBaseComponent 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 * @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 Browsing mode (dark or light).\n * @summary Indicates whether the dark mode theme is currently enabled.\n * Defaults to `false`.\n *\n * @type {boolean}\n * @memberOf FilterComponent\n */\n isDarkMode: boolean = false;\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, 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 this.isDarkMode = await isDarkMode();\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 }\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 ngOnDestroy(): void {\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 }\n this.step++;\n this.value = '';\n if(this.options.length)\n this.handleFocus(this.options);\n this.component.nativeElement.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(): void {\n this.options = this.filteredOptions = this.filterValue = [];\n this.step = 1;\n this.lastFilter = {};\n this.value = '';\n setTimeout(() => {\n this.submit();\n }, 100);\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 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-grid\" [ngClass]=\"{'dcf-hidden': !indexes.length}\">\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 name=\"close\" (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\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n #component\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 name=\"trash-outline\" [color]=\"!isDarkMode ? 'dark' : 'medium'\" 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 name=\"search-outline\" [color]=\"!isDarkMode ? 'dark' : 'medium'\" 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 slot=\"icon-only\" [color]=\"!isDarkMode ? 'primary' : 'medium'\" [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","import {\n Component,\n EventEmitter,\n inject,\n Injector,\n Input,\n OnChanges,\n OnDestroy,\n Output,\n SimpleChanges,\n TemplateRef,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport { Model, sf } from '@decaf-ts/decorator-validation';\nimport { NgComponentOutlet } from '@angular/common';\nimport {\n AngularDynamicOutput,\n AngularEngineKeys,\n BaseComponentProps,\n BaseCustomEvent,\n NgxRenderingEngine,\n RenderedModel,\n} from '../../engine';\nimport { KeyValue, RendererCustomEvent } from '../../engine/types';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { Renderable } from '@decaf-ts/ui-decorators';\nimport { ComponentRendererComponent } from '../component-renderer/component-renderer.component';\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: [ForAngularModule, NgComponentOutlet, ComponentRendererComponent],\n selector: 'ngx-decaf-model-renderer',\n templateUrl: './model-renderer.component.html',\n styleUrl: './model-renderer.component.scss',\n host: {'[attr.id]': 'rendererId'},\n})\nexport class ModelRendererComponent<M extends Model>\n implements OnChanges, OnDestroy, RenderedModel {\n\n /**\n * @description Input model to be rendered\n * @summary Can be a Model instance or a JSON string representation of a model\n */\n @Input({ required: true })\n model!: M | string | undefined;\n\n /**\n * @description Global variables to be passed to the rendered component\n */\n @Input()\n globals: Record<string, unknown> = {};\n\n /**\n * @description Template reference for inner content\n */\n @ViewChild('inner', { read: TemplateRef, static: true })\n inner?: TemplateRef<unknown>;\n\n /**\n * @description Output of the rendered model\n */\n output?: AngularDynamicOutput;\n\n /**\n * @description Unique identifier for the renderer\n */\n @Input()\n rendererId?: string;\n\n /**\n * @description View container reference for dynamic component rendering\n */\n @ViewChild('componentOuter', { static: true, read: ViewContainerRef })\n vcr!: ViewContainerRef;\n\n /**\n * @description Event emitter for custom events from the rendered component\n */\n @Output()\n listenEvent = new EventEmitter<RendererCustomEvent>();\n\n /**\n * @description Instance of the rendered component\n */\n private instance!: KeyValue | undefined;\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 );\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?.instance;\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 ngOnChanges(changes: SimpleChanges): void {\n if (changes[BaseComponentProps.MODEL]) {\n const { currentValue } = changes[BaseComponentProps.MODEL];\n this.refresh(currentValue);\n }\n }\n\n /**\n * @description Lifecycle hook that is called when a directive, pipe, or service is destroyed\n * @return {Promise<void>}\n */\n async ngOnDestroy(): Promise<void> {\n if (this.instance) {\n this.unsubscribeEvents();\n await NgxRenderingEngine.destroy();\n }\n this.output = undefined;\n }\n\n private subscribeEvents(): void {\n const component = this?.output?.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((event: Partial<BaseCustomEvent>) => {\n this.listenEvent.emit({\n component: component.name || '',\n name: key,\n ...event,\n } as RendererCustomEvent);\n });\n }\n }\n }\n\n /**\n * @description Unsubscribes from events emitted by the rendered component\n */\n private 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 protected readonly JSON = JSON;\n}\n"," <!-- Keep to avoid id conflicts -->\n <div [id]=\"rendererId\"></div>\n\n <ng-template #componentOuter></ng-template>\n <ng-template #inner>\n <div [id]=\"rendererId || null\">\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","import { Component, Input, OnInit} from '@angular/core';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport { KeyValue } from '../../engine';\nimport { ComponentRendererComponent } from '../component-renderer/component-renderer.component';\nimport { ModelRendererComponent } from '../model-renderer/model-renderer.component';\nimport { UIMediaBreakPoints } from '@decaf-ts/ui-decorators';\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 NgxBaseComponent to inherit common functionality\n * and integrates with the model and component renderer systems.\n *\n * @class LayoutComponent\n * @extends {NgxBaseComponent}\n * @implements {OnInit}\n * @memberOf LayoutComponent\n */\n@Component({\n selector: 'ngx-decaf-layout',\n templateUrl: './layout.component.html',\n styleUrls: ['./layout.component.scss'],\n imports: [ForAngularModule, ModelRendererComponent, ComponentRendererComponent],\n standalone: true,\n\n})\nexport class LayoutComponent extends NgxBaseComponent implements OnInit {\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 * @memberOf LayoutComponent\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 * @memberOf LayoutComponent\n */\n @Input()\n rows: number | KeyValue[] | string[] = 1;\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 {UIMediaBreakPoints}\n * @default 'medium'\n * @memberOf LayoutComponent\n */\n @Input()\n breakpoint: UIMediaBreakPoints = 'medium';\n\n /**\n * @description Array of child components or data to render within the grid.\n * @summary Contains the child elements that will be distributed across the grid layout.\n * Each item in the array represents content that will be rendered using the appropriate\n * renderer component (ModelRenderer or ComponentRenderer). This allows for mixed content\n * types within a single layout structure.\n *\n * @type {KeyValue[]}\n * @default []\n * @memberOf LayoutComponent\n */\n @Input()\n children: KeyValue[] = [];\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 NgxBaseComponent 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 === \"number\")\n cols = Array.from({length: Number(cols)}, () => ``);\n return cols;\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 === \"number\")\n rows = Array.from({length: Number(rows)}, () => ({title: ''}));\n return rows.map((row, index) => {\n return {\n title: (row as KeyValue)?.['title'],\n cols: this.children.filter(child => {\n if(child['row'] === index + 1)\n return child;\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 ngOnInit(): void {\n this.initialize();\n }\n\n /**\n * @description Initializes the layout component with processed properties.\n * @summary Overrides the base component's initialize method to set up the grid layout.\n * This method processes input properties, normalizes the breakpoint value, converts\n * rows and columns to their array representations, and marks the component as initialized.\n * The initialization ensures all properties are in the correct format for rendering.\n *\n * @mermaid\n * sequenceDiagram\n * participant L as LayoutComponent\n * participant B as NgxBaseComponent\n *\n * L->>B: parseProps(this)\n * Note over L: Process component properties\n * L->>L: Normalize breakpoint to lowercase\n * L->>L: Convert rows to array format\n * L->>L: Convert cols to array format\n * L->>L: Set initialized = true\n *\n * @override\n * @memberOf LayoutComponent\n */\n override initialize() {\n this.parseProps(this);\n this.breakpoint = this.breakpoint.slice(0, 2).toLowerCase() as UIMediaBreakPoints;\n this.cols = this._cols;\n this.rows = this._rows;\n this.initialized = true;\n }\n}\n","\n@if(initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n <div [id]=\"uid\" class=\"dcf-grid dcf-grid-collapse dcf-grid-match\">\n @if(row) {\n <div class=\"dcf-width-1-1 dcf-grid-title\">\n <ion-card class=\"dcf-grid-title\">\n {{row.title | translate}}\n </ion-card>\n </div>\n }\n @for (child of row.cols; track trackItemFn($index, child.col); let colIndex = $index) {\n <div [class]=\"(child.col === cols.length ? 'dcf-width-1-1' : 'dcf-width-'+child.col+'-'+cols.length+'@'+breakpoint)\">\n <div [class]=\"'dcf-grid-child '+child.col \">\n @if(child.tag === 'ngx-decaf-crud-form') {\n <ion-card [class]=\"'dcf-height-1-1 ' + className\">\n <ion-card-content>\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ion-card-content>\n </ion-card>\n } @else {\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{props: child.props}\"\n />\n }\n </div>\n </div>\n }\n </div>\n }\n}\n","import { Component, EventEmitter, HostListener, inject, Input, OnInit, Output, ViewChild } from '@angular/core';\nimport { CrudOperations, OperationKeys } from '@decaf-ts/db-decorators';\nimport { StringOrBoolean } from '../../engine/types';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { removeFocusTrap, stringToBoolean } from '../../helpers/utils';\nimport { getWindowWidth, windowEventEmitter } from '../../helpers/utils';\nimport { Dynamic, EventConstants, ListItemCustomEvent } from '../../engine';\nimport { NavController } from '@ionic/angular';\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';\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 NgxBaseComponent. 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 NgxBaseComponent\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 ForAngularModule,\n IonList,\n IonListHeader,\n IonItem,\n IonItemSliding,\n IonItemOptions,\n IonItemOption,\n IonIcon,\n IonLabel,\n IonButton,\n IonContent,\n IonPopover\n ]\n\n})\nexport class ListItemComponent extends NgxBaseComponent implements OnInit {\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 * @description Angular NavController service for handling navigation.\n * @summary Injected service that provides methods for programmatic navigation\n * within the Ionic application. Used for navigating to different routes when\n * list item actions are performed or when the item itself is clicked.\n *\n * @private\n * @type {NavController}\n * @memberOf ListItemComponent\n */\n private navController: NavController = inject(NavController);\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 }\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\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 /**\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 NavController\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: EventConstants.CLICK, component: this.componentName } as ListItemCustomEvent;\n windowEventEmitter(`ListItem${EventConstants.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 > 768px\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 > 768)\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 NavController 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 NavController\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.navController.navigateForward(`/${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 #component>\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 \">\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\"></ion-icon>\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\"></ion-icon>\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n <ion-label class=\"dcf-item-title\" [innerHTML]=\"uid + ' - ' + title\" ></ion-label>\n <div *ngIf =\"description\" class=\"dcf-description\" [innerHTML]=\"description\"></div>\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 <span *ngIf=\"info\" [innerHTML]=\"info\"></span>\n <div *ngIf=\"subinfo\" class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\" ></div>\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 <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n <ion-button class=\"dcf-hidden@m\" shape=\"round\" fill=\"clear\" color=\"primary\" (click)=\"presentActionsMenu($event)\">\n <ion-icon slot=\"icon-only\" aria-hidden=\"true\" name=\"ellipsis-vertical-outline\"></ion-icon>\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\"></ion-icon>\n } @else {\n <ion-icon color=\"danger\" aria-hidden=\"true\" name=\"trash\"></ion-icon>\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(operations?.length && uid) {\n <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n @if(operations?.includes('update')) {\n <ion-button fill=\"clear\" size=\"small\" color=\"primary\" (click)=\"handleAction('update', component)\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\"></ion-icon>\n </ion-button>\n }\n @if(operations?.includes('delete')) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleAction('delete', component)\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\"></ion-icon>\n </ion-button>\n }\n </div>\n } -->\n @if(windowWidth > 768) {\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\"></ion-icon>\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\"></ion-icon>\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n","import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { IonIcon } from '@ionic/angular/standalone';\nimport { addIcons } from 'ionicons';\nimport { chevronBackOutline, chevronForwardOutline } from 'ionicons/icons';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport { EventConstants, KeyValue, StringOrBoolean } from '../../engine';\nimport { PaginationCustomEvent } from './constants';\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 PaginationCustomEvent\n *\n * U->>P: Click next button\n * P->>P: next()\n * P->>P: handleClick('next')\n * P->>E: Emit clickEvent with PaginationCustomEvent\n *\n * U->>P: Click previous button\n * P->>P: previous()\n * P->>P: handleClick('previous')\n * P->>E: Emit clickEvent with PaginationCustomEvent\n *\n * @example\n * <ngx-decaf-pagination\n * [pages]=\"10\"\n * [current]=\"3\"\n * (clickEvent)=\"handlePageChange($event)\">\n * </ngx-decaf-pagination>\n *\n * @extends {NgxBaseComponent}\n * @implements {OnInit}\n */\n@Component({\n selector: 'ngx-decaf-pagination',\n templateUrl: './pagination.component.html',\n styleUrls: ['./pagination.component.scss'],\n imports: [\n ForAngularModule,\n IonIcon\n ],\n standalone: true,\n\n})\nexport class PaginationComponent extends NgxBaseComponent implements OnInit {\n\n /**\n * @description Controls whether the component uses translation services.\n * @summary When set to true, the component will attempt to use translation services\n * for any text content. This allows for internationalization of the pagination component.\n *\n * @type {StringOrBoolean}\n * @default true\n * @memberOf PaginationComponent\n */\n override translatable: StringOrBoolean = true;\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<PaginationCustomEvent>}\n * @memberOf PaginationComponent\n */\n @Output()\n clickEvent: EventEmitter<PaginationCustomEvent> = new EventEmitter<PaginationCustomEvent>();\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: EventConstants.CLICK,\n data: {\n direction,\n page: this.current\n },\n component: this.componentName\n } as PaginationCustomEvent);\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\">\n <div class=\"dcf-width-1-1\">\n <div class=\"dcf-pagination-resume\" [innerHTML]=\"locale + '.resume' | translate: {value0: current, value1: 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()\" [ngClass]=\"{'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 [ngClass]=\"{'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 [ngClass]=\"{'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","import { Adapter, Repository } from \"@decaf-ts/core\";\nimport { Context, RepositoryFlags } from \"@decaf-ts/db-decorators\";\nimport { Constructor, Model } from \"@decaf-ts/decorator-validation\";\n\nexport enum ListComponentsTypes {\n INFINITE = 'infinite',\n PAGINATED = 'paginated'\n}\n\nexport interface IListEmptyResult {\n title: string;\n subtitle: string;\n showButton: boolean;\n buttonText: string;\n link: string;\n icon: string;\n}\n\nexport interface RawQuery<M extends Model> {\n select: undefined | (keyof M)[];\n from: Constructor<M>;\n where: (el: M) => boolean;\n sort?: (el: M, el2: M) => number;\n limit?: number;\n skip?: number;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type DecafRepositoryAdapter = Adapter<Map<string, Map<string | number, any>>, RawQuery<any>, RepositoryFlags & {UUIID?: string}, Context<RepositoryFlags & {UUIID?: string}>>\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type DecafRepository<M extends Model> = Repository<M, RawQuery<any>, DecafRepositoryAdapter, RepositoryFlags, Context<RepositoryFlags>>;\n","import { Component, OnInit, EventEmitter, Output, Input, HostListener, OnDestroy } from '@angular/core';\nimport { InfiniteScrollCustomEvent, RefresherCustomEvent, SpinnerTypes } from '@ionic/angular';\nimport {\n IonInfiniteScroll,\n IonInfiniteScrollContent,\n IonItem,\n IonLabel,\n IonList,\n IonRefresher,\n IonRefresherContent,\n IonSkeletonText,\n IonText,\n IonThumbnail,\n IonLoading\n} from '@ionic/angular/standalone';\nimport { debounceTime, Subject } from 'rxjs';\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 {\n BaseCustomEvent,\n Dynamic,\n EventConstants,\n ComponentsTagNames,\n RendererCustomEvent,\n StringOrBoolean,\n KeyValue,\n ListItemCustomEvent\n} from '../../engine';\nimport { ForAngularModule } from '../../for-angular.module';\nimport { NgxBaseComponent } from '../../engine/NgxBaseComponent';\nimport {\n stringToBoolean,\n formatDate,\n isValidDate\n} from '../../helpers';\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 { PaginationCustomEvent } from '../pagination/constants';\nimport { IListEmptyResult, ListComponentsTypes, DecafRepository } from './constants';\nimport { FunctionLike, IFilterQuery, IFilterQueryItem } from '../../engine';\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 {NgxBaseComponent}\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 ForAngularModule,\n IonRefresher,\n IonLoading,\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 ListItemComponent,\n FilterComponent,\n ComponentRendererComponent\n ]\n})\nexport class ListComponent extends NgxBaseComponent 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 whether the component uses translation services.\n * @summary When set to true, the component will attempt to use translation services\n * for any text content. This allows for internationalization of the list component.\n *\n * @type {StringOrBoolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n override translatable: StringOrBoolean = true;\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 {StringOrBoolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n showSearchbar: StringOrBoolean = 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 {StringOrBoolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n loadMoreData: StringOrBoolean = 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 {StringOrBoolean}\n * @default false\n * @memberOf ListComponent\n */\n @Input()\n inset: StringOrBoolean = 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 {StringOrBoolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n showRefresher: StringOrBoolean = true;\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 {StringOrBoolean}\n * @default true\n * @memberOf ListComponent\n */\n @Input()\n enableFilter: StringOrBoolean = 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 {StringOrBoolean}\n * @default false\n * @memberOf ListComponent\n */\n @Input()\n disableSort: StringOrBoolean = false;\n\n\n /**\n * @description Icon to display when the list is empty.\n * @summary Specifies the icon shown in the empty state when no data is available.\n * This can be any icon name supported by the application's icon system.\n *\n * @type {string | undefined}\n * @default 'ti-database-exclamation'\n * @memberOf ListComponent\n */\n @Input()\n emptyIcon?: string = 'ti-database-exclamation';\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<IListEmptyResult>}\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<IListEmptyResult> = {\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\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 * @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<BaseCustomEvent>}\n * @memberOf ListComponent\n */\n @Output()\n refreshEvent: EventEmitter<BaseCustomEvent> = new EventEmitter<BaseCustomEvent>();\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|RendererCustomEvent> = new EventEmitter<ListItemCustomEvent|RendererCustomEvent>();\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 | RendererCustomEvent>}\n * @memberOf ListComponent\n */\n private clickItemSubject: Subject<CustomEvent | ListItemCustomEvent | RendererCustomEvent> = new Subject<CustomEvent | ListItemCustomEvent | RendererCustomEvent>();\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 = { refresh: async (... args: unknown[]): Promise<void> => this.observeRepository(...args)}\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.clickItemSubject.pipe(debounceTime(100)).subscribe(event => this.clickEventEmit(event as ListItemCustomEvent | RendererCustomEvent));\n this.observerSubjet.pipe(debounceTime(100)).subscribe(args => this.handleObserveEvent(args[0], args[1], args[2]));\n this.enableFilter = stringToBoolean(this.enableFilter);\n this.limit = Number(this.limit);\n this.start = Number(this.start);\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 if(typeof this.item?.['tag'] === 'boolean' && this.item?.['tag'] === true)\n this.item['tag'] = ComponentsTagNames.LIST_ITEM as string;\n\n await this.refresh();\n\n if(this.operations.includes(OperationKeys.CREATE) && this.route)\n this.empty.link = `${this.route}/${OperationKeys.CREATE}`;\n\n this.initialize();\n\n if(this.model instanceof Model && this._repository)\n this._repository.observe(this.observer);\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 ngOnDestroy(): void {\n if(this._repository)\n this._repository.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 | RendererCustomEvent} event - The click event\n * @returns {void}\n *\n * @memberOf ListComponent\n */\n @HostListener('window:ListItemClickEvent', ['$event'])\n handleClick(event: ListItemCustomEvent | RendererCustomEvent): 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 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 await this.refresh(true);\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 }\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(data?.length || 2);\n this.refreshEvent.emit({\n name: EventConstants.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 | RendererCustomEvent} event - The click event\n * @returns {void}\n *\n * @memberOf ListComponent\n */\n private clickEventEmit(event: ListItemCustomEvent | RendererCustomEvent): 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 === EventConstants.BACK_BUTTON_NAVIGATION) {\n // const {refresh} = (force as CustomEvent).detail;\n // if(!refresh)\n // return false;\n // }\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 this.refreshEventEmit();\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 !== EventConstants.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 {PaginationCustomEvent} event - The pagination event containing page information\n * @returns {void}\n *\n * @memberOf ListComponent\n */\nhandlePaginate(event: PaginationCustomEvent): 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 return results.filter((item: KeyValue) =>\n Object.values(item).some(value =>\n value.toString().toLowerCase().includes((search as string)?.toLowerCase())\n )\n );\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 request: KeyValue[] = [];\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.logger.info('No data and source passed to infinite list');\n return [];\n }\n\n if(this.source instanceof Function)\n request = await this.source();\n\n if(!Array.isArray(request))\n request = request?.['response']?.['data'] || request?.['results'] || [];\n this.data = [... await this.parseResult(request)];\n if(this.data?.length)\n this.items = this.type === ListComponentsTypes.INFINITE ?\n (this.items || []).concat([...this.data.slice(start, limit)]) : [...request.slice(start, limit) as KeyValue[]];\n } else {\n this.data = this.parseSearchResults(this.data as [], this.searchValue as string);\n this.items = this.data;\n }\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 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 request = await this.parseResult(await repo.query(condition, (this.sortBy || this.pk) as keyof Model, this.sortDirection));\n data = [];\n }\n data = this.type === ListComponentsTypes.INFINITE ? [... (data).concat(request)] : [...request];\n } catch(error: unknown) {\n this.logger.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 result = await paginator.page(this.page);\n // TODO: Chage for result.total;\n this.getMoreData(paginator.total);\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] || 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","\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@if(showSearchbar) {\n @if(model && enableFilter) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n } @else {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n }\n}\n\n@if(data?.length) {\n <ion-list [id]=\"uid\" [inset]=\"inset\" [lines]=\"lines\" #component>\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 [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 <ion-item *ngFor=\"let skl of skeletonData\">\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 } @else {\n @if(!searchValue?.length) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\"\n [buttonText]=\"empty.showButton ? (locale + '.'+ empty.button | translate) : ''\"\n [buttonLink]=\"empty.showButton ? empty.route : ''\"\n />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n ngClass=\"empty-search\"\n [translatable]=\"true\"\n title=\"search.title\"\n subtitle=\"search.subtitle\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n}\n\n","import { NgModule, CUSTOM_ELEMENTS_SCHEMA } 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 { ForAngularModule } from '../for-angular.module';\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 { CollapsableDirective } from '../directives/collapsable.directive';\nimport { LayoutComponent } from './layout/layout.component';\nimport { FilterComponent } from './filter/filter.component';\n\nconst Directives = [CollapsableDirective];\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];\n\n@NgModule({\n imports: [Components, Directives],\n declarations: [],\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n exports: [Components, Directives, ForAngularModule],\n})\nexport class ForAngularComponentsModule {}\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';\n\n// Constants exports\nexport * from './crud-form/constants';\nexport * from './list/constants';\nexport * from './pagination/constants';\n\n// Module export\nexport * from './for-angular-components.module';\n","import '@decaf-ts/ui-decorators';\nexport * from './components';\nexport * from './engine';\nexport * from './directives';\nexport * from './helpers';\nexport * from './for-angular.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","i1","i2","i3","i4","AllIcons"],"mappings":"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"}
|