@decaf-ts/for-angular 0.0.47 → 0.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,15 +1,15 @@
1
- import { HTML5InputTypes, parseValueByType, HTML5CheckTypes, escapeHtml, parseToNumber, RenderingEngine, DecafComponent, UIKeys, RenderingError, UIMediaBreakPoints } from '@decaf-ts/ui-decorators';
1
+ import { HTML5InputTypes, parseValueByType, HTML5CheckTypes, escapeHtml, parseToNumber, RenderingEngine, DecafComponent, UIKeys, RenderingError, UIMediaBreakPoints, DecafEventHandler } from '@decaf-ts/ui-decorators';
2
2
  import * as i0 from '@angular/core';
3
3
  import { InjectionToken, NgModule, isDevMode, reflectComponentType, Injector, createEnvironmentInjector, runInInjectionContext, createComponent, inject, NgZone, Injectable, ChangeDetectorRef, Renderer2, EventEmitter, ElementRef, Input, Output, ViewChild, Inject, Directive, EnvironmentInjector, ViewContainerRef, TemplateRef, Component, HostListener, CUSTOM_ELEMENTS_SCHEMA, ViewEncapsulation } from '@angular/core';
4
4
  import * as i1$1 from '@angular/common';
5
5
  import { CommonModule, Location, NgComponentOutlet } from '@angular/common';
6
6
  import { VALIDATION_PARENT_KEY, ValidationKeys, DEFAULT_PATTERNS, Validation, Primitives, ComparisonValidationKeys, PathProxyEngine, Model, ModelKeys, isValidDate as isValidDate$1, parseDate, sf, ReservedModels } from '@decaf-ts/decorator-validation';
7
- import { OperationKeys, InternalError } from '@decaf-ts/db-decorators';
7
+ import { OperationKeys, InternalError, NotFoundError } from '@decaf-ts/db-decorators';
8
8
  import * as i1 from '@angular/forms';
9
9
  import { FormGroup, FormControl, FormsModule, ReactiveFormsModule, FormArray, AbstractControl, Validators } from '@angular/forms';
10
10
  import { InjectableRegistryImp } from '@decaf-ts/injectable-decorators';
11
11
  import { TranslateModule, TranslatePipe, TranslateParser, provideTranslateService, TranslateLoader, provideTranslateParser, TranslateService } from '@ngx-translate/core';
12
- import { Logging, LoggedClass } from '@decaf-ts/logging';
12
+ import { Logging } from '@decaf-ts/logging';
13
13
  import { Repository, OrderDirection, Condition } from '@decaf-ts/core';
14
14
  import { uses, Metadata, apply, metadata } from '@decaf-ts/decoration';
15
15
  import { faker } from '@faker-js/faker';
@@ -572,9 +572,10 @@ function getModelAndRepository(model) {
572
572
  uses(dbAdapterFlavour)(constructor);
573
573
  const repository = Repository.forModel(constructor);
574
574
  model = new constructor();
575
- if (!repository.pk)
575
+ const pk = Model.pk(repository.class);
576
+ if (!pk)
576
577
  return undefined;
577
- return { repository, model };
578
+ return { repository, model, pk };
578
579
  }
579
580
  catch (error) {
580
581
  getLogger(getModelAndRepository).warn(error?.message || error);
@@ -603,13 +604,12 @@ function getModelAndRepository(model) {
603
604
  * provideDbAdapter(PostgresAdapter, { host: 'localhost', port: 5432 })
604
605
  * ]
605
606
  */
606
- function provideDbAdapter(adapterClass, options = {}, flavour) {
607
- const adapter = new adapterClass(options);
607
+ function provideDbAdapter(clazz, options = {}, flavour) {
608
+ const adapter = new clazz(options);
608
609
  if (flavour)
609
610
  flavour = adapter.flavour;
610
- // Log and expose adapter flavour globally
611
611
  getLogger(provideDbAdapter).info(`Using ${adapter.constructor.name} ${flavour} as Db Provider`);
612
- getWindow()[DB_ADAPTER_PROVIDER] = flavour;
612
+ setOnWindow(DB_ADAPTER_PROVIDER, flavour);
613
613
  return {
614
614
  provide: DB_ADAPTER_PROVIDER_TOKEN,
615
615
  useValue: adapter,
@@ -1423,6 +1423,7 @@ class NgxFormService {
1423
1423
  partFormGroup[BaseComponentProps.FORM_GROUP_COMPONENT_PROPS] = {
1424
1424
  childOf: childOf || '',
1425
1425
  isMultiple: isMultiple,
1426
+ required: parentProps?.required ?? false,
1426
1427
  name: part,
1427
1428
  pk,
1428
1429
  [ModelKeys.MODEL]: {},
@@ -1868,8 +1869,21 @@ class NgxFormService {
1868
1869
  const control = formGroup.controls[key];
1869
1870
  const parentProps = NgxFormService.getPropsFromControl(formGroup);
1870
1871
  if (!(control instanceof FormControl)) {
1871
- if (control.disabled)
1872
+ if (control.disabled) {
1873
+ if (control instanceof FormGroup)
1874
+ data[key] = NgxFormService.getFormData(control);
1875
+ if (control instanceof FormArray) {
1876
+ const value = control.controls.map(c => {
1877
+ if (Object.values(c.value).some(p => p !== undefined))
1878
+ return c.value;
1879
+ return undefined;
1880
+ });
1881
+ data[key] = Array.isArray(value)
1882
+ ? !value.filter(Boolean).length
1883
+ ? undefined : value : value;
1884
+ }
1872
1885
  continue;
1886
+ }
1873
1887
  const value = NgxFormService.getFormData(control);
1874
1888
  const isValid = control.valid;
1875
1889
  if (parentProps.multiple) {
@@ -1970,13 +1984,27 @@ class NgxFormService {
1970
1984
  if (control instanceof FormArray) {
1971
1985
  const totalGroups = control.length;
1972
1986
  const hasValid = control.controls.some(control => control.valid);
1973
- if (totalGroups > 1 && hasValid) {
1987
+ const parentProps = control[BaseComponentProps.FORM_GROUP_COMPONENT_PROPS] || {};
1988
+ const childControl = control.at(0);
1989
+ if (totalGroups === 1) {
1990
+ const parent = childControl.parent;
1991
+ if (!parentProps.required) {
1992
+ parent.setErrors(null);
1993
+ parent.updateValueAndValidity({ emitEvent: true });
1994
+ childControl.disable();
1995
+ }
1996
+ else {
1997
+ this.validateFields(childControl);
1998
+ }
1999
+ }
2000
+ else if (totalGroups > 1 && hasValid) {
1974
2001
  for (let i = control.length - 1; i >= 0; i--) {
1975
2002
  const childControl = control.at(i);
1976
2003
  // disable no valid groups on array
1977
2004
  if (!childControl.valid) {
1978
- childControl.parent.setErrors(null);
1979
- childControl.parent.updateValueAndValidity({ emitEvent: true });
2005
+ const parent = childControl.parent;
2006
+ parent.setErrors(null);
2007
+ parent.updateValueAndValidity({ emitEvent: true });
1980
2008
  childControl.disable();
1981
2009
  }
1982
2010
  else {
@@ -2199,25 +2227,23 @@ class DecafFakerRepository {
2199
2227
  if (!this._repository)
2200
2228
  this._repository = this.repository;
2201
2229
  }
2202
- async generateData(pkValues, pk, pkType) {
2203
- const limit = pkValues
2204
- ? Object.values(pkValues || {}).length - 1
2205
- : this.limit;
2206
- if (!pk)
2207
- pk = this._repository?.pk;
2208
- if (!pkType)
2209
- pkType = Metadata.type(this.repository.class, pk).name.toLowerCase();
2230
+ async generateData(values, key, keyType) {
2231
+ const limit = values ? Object.values(values || {}).length : this.limit;
2232
+ if (!key)
2233
+ key = Model.pk(this.repository.class);
2234
+ if (!keyType)
2235
+ keyType = Metadata.type(this.repository.class, key).name.toLowerCase();
2210
2236
  const props = Object.keys(this.model).filter((k) => {
2211
- if (pkType === Primitives.STRING)
2237
+ if (keyType === Primitives.STRING)
2212
2238
  return !['updatedBy', 'createdAt', 'createdBy', 'updatedAt'].includes(k);
2213
- return ![pk, 'updatedBy', 'createdAt', 'createdBy', 'updatedAt'].includes(k);
2239
+ return ![key, 'updatedBy', 'createdAt', 'createdBy', 'updatedAt'].includes(k);
2214
2240
  });
2215
2241
  const dataProps = {};
2216
2242
  for (const prop of props) {
2217
- const type = Metadata.type(this.repository.class, prop).name.toLowerCase();
2218
- switch ((type?.name || '').toLowerCase()) {
2243
+ const type = Metadata.type(this.repository.class, prop);
2244
+ switch (type.name.toLowerCase()) {
2219
2245
  case 'string':
2220
- dataProps[prop] = () => `${faker.lorem.word()} ${pk === prop ? ' - ' + faker.number.int({ min: 1, max: 200 }) : ''}`;
2246
+ dataProps[prop] = () => `${faker.lorem.word()} ${key === prop ? ' - ' + faker.number.int({ min: 1, max: 200 }) : ''}`;
2221
2247
  break;
2222
2248
  case 'step':
2223
2249
  dataProps[prop] = () => faker.lorem.word();
@@ -2243,25 +2269,25 @@ class DecafFakerRepository {
2243
2269
  }
2244
2270
  }
2245
2271
  const data = getFakerData(limit, dataProps, typeof this.model === 'string' ? this.model : this.model?.constructor.name);
2246
- if (!pkValues)
2272
+ if (!values)
2247
2273
  return data;
2248
- const values = Object.values(pkValues);
2274
+ const _values = Object.values(values);
2249
2275
  const iterated = [];
2250
2276
  function getPkValue(item) {
2251
- if (values.length > 0) {
2252
- const randomIndex = Math.floor(Math.random() * values.length);
2253
- const selected = values.splice(randomIndex, 1)[0];
2254
- const value = pkType === Primitives.STRING
2277
+ if (_values.length > 0) {
2278
+ const randomIndex = Math.floor(Math.random() * _values.length);
2279
+ const selected = _values.splice(randomIndex, 1)[0];
2280
+ const value = keyType === Primitives.STRING
2255
2281
  ? selected
2256
- : pkType === Primitives.NUMBER
2282
+ : keyType === Primitives.NUMBER
2257
2283
  ? parseToNumber(selected)
2258
- : pkType === Array.name
2284
+ : keyType === Array.name
2259
2285
  ? [selected]
2260
2286
  : selected;
2261
- item[pk] = value;
2287
+ item[key] = value;
2262
2288
  }
2263
- if (!iterated.includes(item[pk])) {
2264
- iterated.push(item[pk]);
2289
+ if (!iterated.includes(item[key])) {
2290
+ iterated.push(item[key]);
2265
2291
  return item;
2266
2292
  }
2267
2293
  return undefined;
@@ -2270,9 +2296,9 @@ class DecafFakerRepository {
2270
2296
  return data
2271
2297
  .map((d) => getPkValue(d))
2272
2298
  .filter((item) => {
2273
- if (!item || uids.has(item[pk]) || !item[pk] || item[pk] === undefined)
2299
+ if (!item || uids.has(item[key]) || !item[key] || item[key] === undefined)
2274
2300
  return false;
2275
- uids.add(item[pk]);
2301
+ uids.add(item[key]);
2276
2302
  return true;
2277
2303
  })
2278
2304
  .filter(Boolean);
@@ -2290,6 +2316,8 @@ function getFakerData(limit = 100, data, model) {
2290
2316
  // (item as any).code = `${index}`;
2291
2317
  // item.id = index;
2292
2318
  // item.createdAt = faker.date.past({ refDate: '2025-01-01' });
2319
+ if (item['productCode'])
2320
+ item['productCode'] = `${index}`;
2293
2321
  index = index + 1;
2294
2322
  return (!model ? item : Model.build(item, model));
2295
2323
  });
@@ -2441,7 +2469,7 @@ class NgxRenderingEngine extends RenderingEngine {
2441
2469
  return !isMapped;
2442
2470
  });
2443
2471
  if (unmappedKeys.length > 0 && isDevelopmentMode())
2444
- getLogger(this.fromFieldDefinition).warn(`Unmapped input properties for component ${fieldDef.tag}: ${unmappedKeys.join(', ')}`);
2472
+ getLogger(this).warn(`Unmapped input properties for component ${fieldDef.tag}: ${unmappedKeys.join(', ')}`);
2445
2473
  const operation = NgxRenderingEngine._operation;
2446
2474
  const hiddenOn = inputs?.hidden || [];
2447
2475
  if (hiddenOn.includes(operation))
@@ -2810,6 +2838,10 @@ var operations = {
2810
2838
  "delete": {
2811
2839
  success: "Successfully deleted item with {0} {1}.",
2812
2840
  error: "Error deleting item with {0} {1}."
2841
+ },
2842
+ multiple: {
2843
+ success: "Successfully processed all operations.",
2844
+ error: "Error processing operations."
2813
2845
  }
2814
2846
  };
2815
2847
  var component = {
@@ -2819,7 +2851,8 @@ var component = {
2819
2851
  cancel: "Cancel",
2820
2852
  not_unique: "The value entered already exists. Value {0}",
2821
2853
  max_items: "You can create up to {0} items.",
2822
- max_items_reached: "Maximum of {0} items reached."
2854
+ max_items_reached: "Maximum of {0} items reached.",
2855
+ empty: "No items found."
2823
2856
  },
2824
2857
  list: {
2825
2858
  pagination: "Showing page <span class=\"text-bold\">{0} of {1}</span>",
@@ -2874,6 +2907,8 @@ var component = {
2874
2907
  },
2875
2908
  file_upload: {
2876
2909
  drag_file: "Drag and drop your image here",
2910
+ empty: "No files found.",
2911
+ preview: "Preview",
2877
2912
  buttons: {
2878
2913
  select: "Select File",
2879
2914
  preview: "Preview",
@@ -3552,9 +3587,9 @@ class NgxComponentDirective extends DecafComponent {
3552
3587
  * The operation affects form validation, field availability, and the specific repository
3553
3588
  * method called during data submission.
3554
3589
  *
3555
- * @type {OperationKeys.CREATE | OperationKeys.READ | OperationKeys.UPDATE | OperationKeys.DELETE}
3590
+ * @type {OperationKeys}
3556
3591
  * @default OperationKeys.READ
3557
- * @memberOf ModelPage
3592
+ * @memberOf module:lib/engine/NgxComponentDirective
3558
3593
  */
3559
3594
  this.operation = OperationKeys.READ;
3560
3595
  /**
@@ -3642,6 +3677,16 @@ class NgxComponentDirective extends DecafComponent {
3642
3677
  * @memberOf module:lib/engine/NgxComponentDirective
3643
3678
  */
3644
3679
  this.listenEvent = new EventEmitter();
3680
+ /**
3681
+ * @description Event emitter for custom component events.
3682
+ * @summary Emits custom events that occur within child components or the component itself.
3683
+ * This allows parent components to listen for and respond to user interactions or
3684
+ * state changes. Events are passed up the component hierarchy to enable coordinated
3685
+ * behavior across the application.
3686
+ * @type {EventEmitter<IBaseCustomEvent>}
3687
+ * @memberOf module:lib/engine/NgxComponentDirective
3688
+ */
3689
+ this.refreshEvent = new EventEmitter();
3645
3690
  /**
3646
3691
  * @description Angular Router instance for programmatic navigation.
3647
3692
  * @summary Injected Router service used for programmatic navigation between routes
@@ -3723,13 +3768,37 @@ class NgxComponentDirective extends DecafComponent {
3723
3768
  this.isModalChild = false;
3724
3769
  this.handlers = {};
3725
3770
  this.events = {};
3726
- this.componentName = componentName || "NgxComponentDirective";
3771
+ /**
3772
+ * @description Indicates whether a refresh operation is in progress.
3773
+ * @summary When true, the component is currently fetching new data. This is used
3774
+ * to control loading indicators and prevent duplicate refresh operations from
3775
+ * being triggered simultaneously.
3776
+ *
3777
+ * @type {boolean}
3778
+ * @default false
3779
+ */
3780
+ this.refreshing = false;
3781
+ /**
3782
+ * @description Represents the color scheme used for application.
3783
+ * @summary This property determines the visual appearance of the application
3784
+ * based on predefined color schemes (e.g., light or dark mode).
3785
+ * @type {WindowColorScheme}
3786
+ * @default WindowColorSchemes.light
3787
+ */
3788
+ this.colorSchema = WindowColorSchemes.light;
3789
+ this.componentName = componentName || 'NgxComponentDirective';
3727
3790
  this.localeRoot = localeRoot;
3728
3791
  if (!this.localeRoot && this.componentName)
3729
3792
  this.localeRoot = this.componentName;
3730
3793
  if (this.localeRoot)
3731
3794
  this.getLocale(this.localeRoot);
3732
3795
  this.uid = `${this.componentName}-${generateRandomValue(8)}`;
3796
+ this.mediaService.isDarkMode().subscribe(isDark => {
3797
+ if (isDark) {
3798
+ this.isDarkMode = isDark;
3799
+ this.colorSchema = WindowColorSchemes.dark;
3800
+ }
3801
+ });
3733
3802
  }
3734
3803
  /**
3735
3804
  * @description Cleanup lifecycle hook invoked when the directive is destroyed.
@@ -3742,6 +3811,11 @@ class NgxComponentDirective extends DecafComponent {
3742
3811
  ngOnDestroy() {
3743
3812
  this.mediaService.destroy();
3744
3813
  }
3814
+ //TODO: Pass to ui decoretators
3815
+ async refresh(...args) {
3816
+ this.log.for(this.refresh).debug(`Refresh called with args: ${args}`);
3817
+ this.refreshEvent.emit(true);
3818
+ }
3745
3819
  /**
3746
3820
  * @description Getter for the current locale context identifier.
3747
3821
  * @summary Returns the current locale identifier by calling the getLocale method.
@@ -3767,8 +3841,7 @@ class NgxComponentDirective extends DecafComponent {
3767
3841
  if (!this._repository) {
3768
3842
  this._repository = getModelAndRepository(this.model)?.repository;
3769
3843
  if (this.model && !this.pk)
3770
- this.pk =
3771
- this._repository.pk || 'id';
3844
+ this.pk = Model.pk(this._repository?.class);
3772
3845
  }
3773
3846
  }
3774
3847
  catch (error) {
@@ -3776,6 +3849,9 @@ class NgxComponentDirective extends DecafComponent {
3776
3849
  }
3777
3850
  return this._repository;
3778
3851
  }
3852
+ set repository(repository) {
3853
+ this._repository = repository;
3854
+ }
3779
3855
  /**
3780
3856
  * @description Angular lifecycle hook for handling input property changes.
3781
3857
  * @summary Responds to changes in component input properties, specifically monitoring changes
@@ -3795,21 +3871,39 @@ class NgxComponentDirective extends DecafComponent {
3795
3871
  if (!this.initialized)
3796
3872
  this.initialized = true;
3797
3873
  }
3874
+ // if (changes[UIKeys.HANDLERS]) {
3875
+ // const { currentValue, previousValue } = changes[UIKeys.HANDLERS];
3876
+ // if (currentValue && typeof currentValue !== previousValue) {
3877
+ // for(const key in currentValue) {
3878
+ // const event = currentValue[key]();
3879
+ // if (event && typeof event === 'function') {
3880
+ // const clazz = new event();
3881
+ // this.handlers[key] = clazz[key].bind(this);
3882
+ // console.log(this.handlers);
3883
+ // }
3884
+ // }
3885
+ // }
3886
+ // }
3798
3887
  if (changes[UIKeys.EVENTS]) {
3799
3888
  const { currentValue, previousValue } = changes[UIKeys.EVENTS];
3800
- if (currentValue && typeof currentValue !== previousValue) {
3889
+ if (currentValue && currentValue !== previousValue) {
3801
3890
  if (!this._repository)
3802
3891
  this._repository = this.repository;
3803
3892
  for (const key in currentValue) {
3804
3893
  const event = currentValue[key]();
3805
3894
  if (event && typeof event === 'function') {
3806
- const clazz = new event();
3807
- this.events[key] = clazz[key].bind(this);
3808
- if (event[key] instanceof Promise) {
3809
- await clazz[key].bind(this)();
3895
+ try {
3896
+ const clazz = new event();
3897
+ this.events[key] = clazz[key].bind(this);
3898
+ if (event[key] instanceof Promise) {
3899
+ await clazz[key].bind(this)();
3900
+ }
3901
+ else {
3902
+ clazz[key].bind(this)();
3903
+ }
3810
3904
  }
3811
- else {
3812
- clazz[key].bind(this)();
3905
+ catch (error) {
3906
+ this.log.for(this.ngOnChanges).warn(`Error occurred while processing event "${key}": ${error?.message || error}`);
3813
3907
  }
3814
3908
  }
3815
3909
  }
@@ -3839,7 +3933,7 @@ class NgxComponentDirective extends DecafComponent {
3839
3933
  ;
3840
3934
  }
3841
3935
  checkDarkMode() {
3842
- this.mediaService.isDarkMode().subscribe(isDark => {
3936
+ this.mediaService.isDarkMode().subscribe((isDark) => {
3843
3937
  this.isDarkMode = isDark;
3844
3938
  this.mediaService.toggleClass([this.component], AngularEngineKeys.DARK_PALETTE_CLASS, this.isDarkMode);
3845
3939
  });
@@ -4016,7 +4110,7 @@ class NgxComponentDirective extends DecafComponent {
4016
4110
  * end
4017
4111
  * @memberOf module:lib/engine/NgxComponentDirective
4018
4112
  */
4019
- async handleEvent(event) {
4113
+ async handleEvent(event, repository) {
4020
4114
  let name = "";
4021
4115
  const log = this.log.for(this.handleEvent);
4022
4116
  if (event instanceof CustomEvent) {
@@ -4031,8 +4125,11 @@ class NgxComponentDirective extends DecafComponent {
4031
4125
  if (!handlers[name])
4032
4126
  return log.debug(`No handler found for event ${name}`);
4033
4127
  try {
4034
- const clazz = new handlers[name](this.router);
4035
- const result = clazz.handle(event);
4128
+ const clazz = new handlers[name]();
4129
+ const handler = clazz.handle.bind(this);
4130
+ //const clazz = new event();
4131
+ // this.events[key] = clazz[key].bind(this);
4132
+ const result = handler(event);
4036
4133
  return (result instanceof Promise) ?
4037
4134
  await result : result;
4038
4135
  }
@@ -4042,6 +4139,10 @@ class NgxComponentDirective extends DecafComponent {
4042
4139
  }
4043
4140
  this.listenEvent.emit(event);
4044
4141
  }
4142
+ // passed for ui decorators
4143
+ // async submit(...args: unknown[]): Promise<any> {
4144
+ // this.log.for(this.submit).info(`submit for ${this.componentName} with ${JSON.stringify(args)}`);
4145
+ // }
4045
4146
  /**
4046
4147
  * @description Determines if a specific operation is allowed in the current context.
4047
4148
  * @summary This method checks if an operation is included in the list of available
@@ -4068,7 +4169,9 @@ class NgxComponentDirective extends DecafComponent {
4068
4169
  isAllowed(operation) {
4069
4170
  if (!this.operations)
4070
4171
  return false;
4071
- return this.operations.includes(operation) && (this.operation !== OperationKeys.CREATE && ((this.operation || "").toLowerCase() !== operation || !this.operation));
4172
+ return (this.operations.includes(operation) &&
4173
+ this.operation !== OperationKeys.CREATE &&
4174
+ ((this.operation || '').toLowerCase() !== operation || !this.operation));
4072
4175
  }
4073
4176
  /**
4074
4177
  * @description Navigates to a different operation for the current model.
@@ -4105,7 +4208,7 @@ class NgxComponentDirective extends DecafComponent {
4105
4208
  return this.router.navigateByUrl(page);
4106
4209
  }
4107
4210
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxComponentDirective, deps: [{ token: CPTKN }, { token: CPTKN }], target: i0.ɵɵFactoryTarget.Directive }); }
4108
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: NgxComponentDirective, isStandalone: true, inputs: { enableDarkMode: "enableDarkMode", isDarkMode: "isDarkMode", name: "name", childOf: "childOf", uid: "uid", model: "model", modelId: "modelId", pk: "pk", mapper: "mapper", operations: "operations", operation: "operation", row: "row", col: "col", className: "className", locale: "locale", item: "item", props: "props", route: "route", borders: "borders", isModalChild: "isModalChild", handlers: "handlers", events: "events" }, outputs: { listenEvent: "listenEvent" }, host: { properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); }
4211
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: NgxComponentDirective, isStandalone: true, inputs: { enableDarkMode: "enableDarkMode", isDarkMode: "isDarkMode", name: "name", childOf: "childOf", uid: "uid", model: "model", modelId: "modelId", value: "value", pk: "pk", mapper: "mapper", operations: "operations", operation: "operation", row: "row", col: "col", className: "className", locale: "locale", item: "item", props: "props", route: "route", borders: "borders", isModalChild: "isModalChild", handlers: "handlers", events: "events" }, outputs: { listenEvent: "listenEvent", refreshEvent: "refreshEvent" }, host: { properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); }
4109
4212
  }
4110
4213
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxComponentDirective, decorators: [{
4111
4214
  type: Directive,
@@ -4133,6 +4236,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
4133
4236
  type: Input
4134
4237
  }], modelId: [{
4135
4238
  type: Input
4239
+ }], value: [{
4240
+ type: Input
4136
4241
  }], pk: [{
4137
4242
  type: Input
4138
4243
  }], mapper: [{
@@ -4149,6 +4254,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
4149
4254
  type: Input
4150
4255
  }], listenEvent: [{
4151
4256
  type: Output
4257
+ }], refreshEvent: [{
4258
+ type: Output
4152
4259
  }], locale: [{
4153
4260
  type: Input
4154
4261
  }], item: [{
@@ -4913,7 +5020,7 @@ class ModelRendererComponent extends NgxRenderableComponentDirective {
4913
5020
  * @description Refreshes the rendered model
4914
5021
  * @param {string | M} model - The model to be rendered
4915
5022
  */
4916
- refresh(model) {
5023
+ async refresh(model) {
4917
5024
  model =
4918
5025
  typeof model === 'string'
4919
5026
  ? Model.build({}, model)
@@ -5090,15 +5197,17 @@ class NgxParentComponentDirective extends NgxComponentDirective {
5090
5197
  if (this.timerSubscription)
5091
5198
  this.timerSubscription.unsubscribe();
5092
5199
  }
5093
- getActivePage(page) {
5094
- const content = this.children[page];
5095
- this.activePage = undefined;
5096
- this.preloadCards = [...new Array(1)];
5097
- this.timerSubscription = timer(1).subscribe(() => this.activePage = { ...this.children[page] });
5098
- this.activeIndex = page;
5099
- if (content)
5100
- return content;
5101
- return undefined;
5200
+ getActivePage(page, firstClick = true) {
5201
+ if (firstClick || this.activeIndex !== page) {
5202
+ const content = this.children[page];
5203
+ this.activePage = undefined;
5204
+ this.preloadCards = [...new Array(1)];
5205
+ this.timerSubscription = timer(25).subscribe(() => this.activePage = { ...this.children[page] });
5206
+ this.activeIndex = page;
5207
+ if (content)
5208
+ return content;
5209
+ return undefined;
5210
+ }
5102
5211
  }
5103
5212
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxParentComponentDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
5104
5213
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: NgxParentComponentDirective, isStandalone: true, inputs: { page: "page", pages: "pages", parentForm: "parentForm", children: "children", cols: "cols", rows: "rows", cardBody: "cardBody", cardType: "cardType", breakpoint: "breakpoint", match: "match" }, usesInheritance: true, ngImport: i0 }); }
@@ -5180,6 +5289,13 @@ let ModalComponent = class ModalComponent extends NgxParentComponentDirective {
5180
5289
  * @default false
5181
5290
  */
5182
5291
  this.lightBox = false;
5292
+ /**
5293
+ * @description Controls the visibility of the modal header.
5294
+ * @summary When set to true, the modal header is displayed; when false, it is hidden.
5295
+ * @type {boolean}
5296
+ * @default true
5297
+ */
5298
+ this.showHeader = true;
5183
5299
  /**
5184
5300
  * @description Event emitted when the modal is about to be dismissed.
5185
5301
  * @summary Emits an OverlayEventDetail object containing details about the dismiss event.
@@ -5284,7 +5400,7 @@ let ModalComponent = class ModalComponent extends NgxParentComponentDirective {
5284
5400
  await this.modal.dismiss(event?.data || undefined, ActionRoles.confirm);
5285
5401
  }
5286
5402
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5287
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: ModalComponent, isStandalone: true, selector: "ngx-decaf-modal", inputs: { title: "title", isOpen: "isOpen", tag: "tag", options: "options", globals: "globals", inlineContent: "inlineContent", inlineContentPosition: "inlineContentPosition", fullscreen: "fullscreen", lightBox: "lightBox" }, outputs: { willDismissEvent: "willDismissEvent" }, host: { properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["component"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ion-modal\n [id]=\"uid\"\n [isOpen]=\"isOpen\"\n (willDismiss)=\"handleWillDismiss($event)\"\n [backdropDismiss]=\"options?.backdropDismiss\"\n [showBackdrop]=\"options?.showBackdrop\"\n [animated]=\"options?.animated\"\n [canDismiss]=\"options?.canDismiss\"\n [class.dcf-fullscreen-modal]=\"fullscreen\"\n [class.dcf-lightbox-modal]=\"lightBox\"\n class=\"dcf-modal-component\"\n #component\n>\n <ng-template>\n <ion-header [transparent]=\"lightBox\">\n <ion-toolbar>\n @if (title) {\n <ion-title>{{ title | translate }}</ion-title>\n }\n <ion-buttons slot=\"end\">\n <ion-button size=\"small\" type=\"button\" class=\"dcf-button-close\" (click)=\"cancel()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n\n <ion-content>\n <section class=\"dcf-modal-body\">\n @if (!tag && !model && !inlineContent) {\n <div class=\"dcf-loading-container\">\n <ion-spinner name=\"crescent\" color=\"primary\"></ion-spinner>\n </div>\n } @else {\n @if (inlineContent && inlineContentPosition === \"top\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n @if (model) {\n <ngx-decaf-model-renderer\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"globals\"\n />\n }\n @if(tag && globals) {\n <ngx-decaf-component-renderer\n [tag]=\"tag\"\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"{props: globals}\"\n />\n }\n @if (inlineContent && inlineContentPosition === \"bottom\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n }\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".dcf-modal-component.dcf-fullscreen-modal{--height: 100%;--width: 100%;--max-width: 100%;--border-radius: 0}.dcf-modal-component.dcf-fullscreen-modal.dcf-lightbox-modal{padding:var(--dcf-padding-small)}.dcf-modal-component.dcf-lightbox-modal{--background: transparent;--box-shadow: none !important}@media (max-width: 767px){.dcf-modal-component.dcf-lightbox-modal{padding:var(--dcf-padding-xsmall)}.dcf-modal-component.dcf-lightbox-modal ion-button{transform:translate(2px,2px)!important}}.dcf-modal-component.dcf-lightbox-modal ion-header{--background: transparent !important;background-color:transparent;box-shadow:none!important;padding:unset!important;margin:unset!important;height:30px}.dcf-modal-component.dcf-lightbox-modal ion-header ion-button{margin:0!important;width:32px!important;height:25px!important;--background: var(--dcf-color-light) !important;transform:translate(2px);--border-radius: var(--dcf-border-radius-small) !important}.dcf-modal-component.dcf-lightbox-modal ion-header ion-button *{margin:-5px}.dcf-modal-component.dcf-lightbox-modal ion-header ion-toolbar{--background: transparent !important;padding:unset!important;margin:unset!important}.dcf-modal-component.dcf-lightbox-modal ion-content{--background: transparent !important}.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body{display:flex;height:auto;justify-content:center;align-items:center;background:#fff!important}.dcf-modal-component:not(.dcf-lightbox-modal) .dcf-modal-body{height:100%;padding:1.5rem 1rem}.dcf-modal-component .dcf-loading-container{height:50%;display:flex;justify-content:center;align-items:center}.dcf-modal-component .dcf-loading-container ion-spinner{width:60px;height:60px}\n"], dependencies: [{ kind: "component", type: IonModal, selector: "ion-modal" }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "component", type: ModelRendererComponent, selector: "ngx-decaf-model-renderer", inputs: ["projectable"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
5403
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: ModalComponent, isStandalone: true, selector: "ngx-decaf-modal", inputs: { title: "title", isOpen: "isOpen", tag: "tag", options: "options", globals: "globals", inlineContent: "inlineContent", inlineContentPosition: "inlineContentPosition", fullscreen: "fullscreen", lightBox: "lightBox", showHeader: "showHeader" }, outputs: { willDismissEvent: "willDismissEvent" }, host: { properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["component"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ion-modal\n [id]=\"uid\"\n [isOpen]=\"isOpen\"\n (willDismiss)=\"handleWillDismiss($event)\"\n [backdropDismiss]=\"options?.backdropDismiss\"\n [showBackdrop]=\"options?.showBackdrop\"\n [animated]=\"options?.animated\"\n [canDismiss]=\"options?.canDismiss\"\n [class.dcf-fullscreen-modal]=\"fullscreen\"\n [class.dcf-lightbox-modal]=\"lightBox\"\n [class.dcf-modal-no-header]=\"!showHeader\"\n [class]=\"'dcf-modal-component ' + className\"\n #component\n>\n <ng-template>\n <ion-header [transparent]=\"lightBox\">\n <ion-toolbar>\n @if (title) {\n <ion-title>{{ title | translate }}</ion-title>\n }\n <ion-buttons slot=\"end\">\n <ion-button size=\"small\" type=\"button\" class=\"dcf-button-close\" (click)=\"cancel()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n\n <ion-content>\n <section class=\"dcf-modal-body\">\n @if (!tag && !model && !inlineContent) {\n <div class=\"dcf-loading-container\">\n <ion-spinner name=\"crescent\" color=\"primary\"></ion-spinner>\n </div>\n } @else {\n @if (inlineContent && inlineContentPosition === \"top\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n @if (model) {\n <ngx-decaf-model-renderer\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"globals\"\n />\n }\n @if(tag && globals) {\n <ngx-decaf-component-renderer\n [tag]=\"tag\"\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"{props: globals}\"\n />\n }\n @if (inlineContent && inlineContentPosition === \"bottom\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n }\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".dcf-modal-component.dcf-modal-expand{--height: 90%;--width: 90%;--max-width: 100%;--border-radius: 0}.dcf-modal-component.dcf-modal-expand ion-button{--background: var(--dcf-color-light) !important;--border-radius: var(--dcf-border-radius-small) !important}.dcf-modal-component.dcf-fullscreen-modal{--height: 100%;--width: 100%;--max-width: 100%;--border-radius: 0}.dcf-modal-component.dcf-fullscreen-modal.dcf-lightbox-modal{padding:var(--dcf-padding-small)}.dcf-modal-component.dcf-lightbox-modal{--background: transparent;--box-shadow: none !important}@media (max-width: 767px){.dcf-modal-component.dcf-lightbox-modal{padding:var(--dcf-padding-xsmall)}.dcf-modal-component.dcf-lightbox-modal ion-button{transform:translate(2px,2px)!important}}.dcf-modal-component.dcf-lightbox-modal ion-header{--background: transparent !important;background-color:transparent;box-shadow:none!important;padding:unset!important;margin:unset!important;height:30px}.dcf-modal-component.dcf-lightbox-modal ion-header ion-button{margin:0!important;width:32px!important;height:25px!important;--background: var(--dcf-color-light) !important;transform:translate(2px);--border-radius: var(--dcf-border-radius-small) !important}.dcf-modal-component.dcf-lightbox-modal ion-header ion-button *{margin:-5px}.dcf-modal-component.dcf-lightbox-modal ion-header ion-toolbar{--background: transparent !important;padding:unset!important;margin:unset!important}.dcf-modal-component.dcf-lightbox-modal ion-content{--background: transparent !important}.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body{display:flex;height:auto;justify-content:center;align-items:center;background:#fff!important}.dcf-modal-component:not(.dcf-lightbox-modal) .dcf-modal-body{height:100%;padding:1.5rem 1rem}.dcf-modal-component .dcf-loading-container{height:50%;display:flex;justify-content:center;align-items:center}.dcf-modal-component .dcf-loading-container ion-spinner{width:60px;height:60px}\n"], dependencies: [{ kind: "component", type: IonModal, selector: "ion-modal" }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "component", type: ModelRendererComponent, selector: "ngx-decaf-model-renderer", inputs: ["projectable"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
5288
5404
  };
5289
5405
  ModalComponent = __decorate([
5290
5406
  Dynamic(),
@@ -5292,7 +5408,7 @@ ModalComponent = __decorate([
5292
5408
  ], ModalComponent);
5293
5409
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ModalComponent, decorators: [{
5294
5410
  type: Component,
5295
- args: [{ selector: 'ngx-decaf-modal', standalone: true, imports: [IonModal, ComponentRendererComponent, ModelRendererComponent, TranslatePipe, IonSpinner, IonButton, IonButtons, IonContent, IonHeader, IonTitle, IonToolbar], host: { '[attr.id]': 'uid' }, template: "<ion-modal\n [id]=\"uid\"\n [isOpen]=\"isOpen\"\n (willDismiss)=\"handleWillDismiss($event)\"\n [backdropDismiss]=\"options?.backdropDismiss\"\n [showBackdrop]=\"options?.showBackdrop\"\n [animated]=\"options?.animated\"\n [canDismiss]=\"options?.canDismiss\"\n [class.dcf-fullscreen-modal]=\"fullscreen\"\n [class.dcf-lightbox-modal]=\"lightBox\"\n class=\"dcf-modal-component\"\n #component\n>\n <ng-template>\n <ion-header [transparent]=\"lightBox\">\n <ion-toolbar>\n @if (title) {\n <ion-title>{{ title | translate }}</ion-title>\n }\n <ion-buttons slot=\"end\">\n <ion-button size=\"small\" type=\"button\" class=\"dcf-button-close\" (click)=\"cancel()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n\n <ion-content>\n <section class=\"dcf-modal-body\">\n @if (!tag && !model && !inlineContent) {\n <div class=\"dcf-loading-container\">\n <ion-spinner name=\"crescent\" color=\"primary\"></ion-spinner>\n </div>\n } @else {\n @if (inlineContent && inlineContentPosition === \"top\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n @if (model) {\n <ngx-decaf-model-renderer\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"globals\"\n />\n }\n @if(tag && globals) {\n <ngx-decaf-component-renderer\n [tag]=\"tag\"\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"{props: globals}\"\n />\n }\n @if (inlineContent && inlineContentPosition === \"bottom\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n }\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".dcf-modal-component.dcf-fullscreen-modal{--height: 100%;--width: 100%;--max-width: 100%;--border-radius: 0}.dcf-modal-component.dcf-fullscreen-modal.dcf-lightbox-modal{padding:var(--dcf-padding-small)}.dcf-modal-component.dcf-lightbox-modal{--background: transparent;--box-shadow: none !important}@media (max-width: 767px){.dcf-modal-component.dcf-lightbox-modal{padding:var(--dcf-padding-xsmall)}.dcf-modal-component.dcf-lightbox-modal ion-button{transform:translate(2px,2px)!important}}.dcf-modal-component.dcf-lightbox-modal ion-header{--background: transparent !important;background-color:transparent;box-shadow:none!important;padding:unset!important;margin:unset!important;height:30px}.dcf-modal-component.dcf-lightbox-modal ion-header ion-button{margin:0!important;width:32px!important;height:25px!important;--background: var(--dcf-color-light) !important;transform:translate(2px);--border-radius: var(--dcf-border-radius-small) !important}.dcf-modal-component.dcf-lightbox-modal ion-header ion-button *{margin:-5px}.dcf-modal-component.dcf-lightbox-modal ion-header ion-toolbar{--background: transparent !important;padding:unset!important;margin:unset!important}.dcf-modal-component.dcf-lightbox-modal ion-content{--background: transparent !important}.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body{display:flex;height:auto;justify-content:center;align-items:center;background:#fff!important}.dcf-modal-component:not(.dcf-lightbox-modal) .dcf-modal-body{height:100%;padding:1.5rem 1rem}.dcf-modal-component .dcf-loading-container{height:50%;display:flex;justify-content:center;align-items:center}.dcf-modal-component .dcf-loading-container ion-spinner{width:60px;height:60px}\n"] }]
5411
+ args: [{ selector: 'ngx-decaf-modal', standalone: true, imports: [IonModal, ComponentRendererComponent, ModelRendererComponent, TranslatePipe, IonSpinner, IonButton, IonButtons, IonContent, IonHeader, IonTitle, IonToolbar], host: { '[attr.id]': 'uid' }, template: "<ion-modal\n [id]=\"uid\"\n [isOpen]=\"isOpen\"\n (willDismiss)=\"handleWillDismiss($event)\"\n [backdropDismiss]=\"options?.backdropDismiss\"\n [showBackdrop]=\"options?.showBackdrop\"\n [animated]=\"options?.animated\"\n [canDismiss]=\"options?.canDismiss\"\n [class.dcf-fullscreen-modal]=\"fullscreen\"\n [class.dcf-lightbox-modal]=\"lightBox\"\n [class.dcf-modal-no-header]=\"!showHeader\"\n [class]=\"'dcf-modal-component ' + className\"\n #component\n>\n <ng-template>\n <ion-header [transparent]=\"lightBox\">\n <ion-toolbar>\n @if (title) {\n <ion-title>{{ title | translate }}</ion-title>\n }\n <ion-buttons slot=\"end\">\n <ion-button size=\"small\" type=\"button\" class=\"dcf-button-close\" (click)=\"cancel()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n\n <ion-content>\n <section class=\"dcf-modal-body\">\n @if (!tag && !model && !inlineContent) {\n <div class=\"dcf-loading-container\">\n <ion-spinner name=\"crescent\" color=\"primary\"></ion-spinner>\n </div>\n } @else {\n @if (inlineContent && inlineContentPosition === \"top\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n @if (model) {\n <ngx-decaf-model-renderer\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"globals\"\n />\n }\n @if(tag && globals) {\n <ngx-decaf-component-renderer\n [tag]=\"tag\"\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"{props: globals}\"\n />\n }\n @if (inlineContent && inlineContentPosition === \"bottom\") {\n <div [innerHTML]=\"inlineContent\"></div>\n }\n }\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".dcf-modal-component.dcf-modal-expand{--height: 90%;--width: 90%;--max-width: 100%;--border-radius: 0}.dcf-modal-component.dcf-modal-expand ion-button{--background: var(--dcf-color-light) !important;--border-radius: var(--dcf-border-radius-small) !important}.dcf-modal-component.dcf-fullscreen-modal{--height: 100%;--width: 100%;--max-width: 100%;--border-radius: 0}.dcf-modal-component.dcf-fullscreen-modal.dcf-lightbox-modal{padding:var(--dcf-padding-small)}.dcf-modal-component.dcf-lightbox-modal{--background: transparent;--box-shadow: none !important}@media (max-width: 767px){.dcf-modal-component.dcf-lightbox-modal{padding:var(--dcf-padding-xsmall)}.dcf-modal-component.dcf-lightbox-modal ion-button{transform:translate(2px,2px)!important}}.dcf-modal-component.dcf-lightbox-modal ion-header{--background: transparent !important;background-color:transparent;box-shadow:none!important;padding:unset!important;margin:unset!important;height:30px}.dcf-modal-component.dcf-lightbox-modal ion-header ion-button{margin:0!important;width:32px!important;height:25px!important;--background: var(--dcf-color-light) !important;transform:translate(2px);--border-radius: var(--dcf-border-radius-small) !important}.dcf-modal-component.dcf-lightbox-modal ion-header ion-button *{margin:-5px}.dcf-modal-component.dcf-lightbox-modal ion-header ion-toolbar{--background: transparent !important;padding:unset!important;margin:unset!important}.dcf-modal-component.dcf-lightbox-modal ion-content{--background: transparent !important}.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body{display:flex;height:auto;justify-content:center;align-items:center;background:#fff!important}.dcf-modal-component:not(.dcf-lightbox-modal) .dcf-modal-body{height:100%;padding:1.5rem 1rem}.dcf-modal-component .dcf-loading-container{height:50%;display:flex;justify-content:center;align-items:center}.dcf-modal-component .dcf-loading-container ion-spinner{width:60px;height:60px}\n"] }]
5296
5412
  }], ctorParameters: () => [], propDecorators: { modal: [{
5297
5413
  type: ViewChild,
5298
5414
  args: ['component']
@@ -5314,6 +5430,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
5314
5430
  type: Input
5315
5431
  }], lightBox: [{
5316
5432
  type: Input
5433
+ }], showHeader: [{
5434
+ type: Input
5317
5435
  }], willDismissEvent: [{
5318
5436
  type: Output
5319
5437
  }] } });
@@ -5346,6 +5464,19 @@ async function getNgxModalComponent(props = {}, modalProps = {}, injector) {
5346
5464
  async function presentNgxLightBoxModal(inlineContent, props = {}, injector) {
5347
5465
  return (await getNgxModalComponent({ props, ...{ inlineContent, lightBox: true } }, {}, injector || undefined)).present();
5348
5466
  }
5467
+ /**
5468
+ * @description Presents a lightbox modal with inline content.
5469
+ * @summary Displays a modal in lightbox mode with the specified content and properties.
5470
+ *
5471
+ * @param {string | SafeHtml} inlineContent - The content to display in the lightbox modal.
5472
+ * @param {Partial<ModalComponent>} [props={}] - Properties to initialize the modal component.
5473
+ * @param {EnvironmentInjector} [injector] - Optional environment injector for dependency injection.
5474
+ * @returns {Promise<void>} - A promise that resolves when the modal is presented.
5475
+ */
5476
+ async function presentNgxInlineModal(inlineContent, props = {}, injector) {
5477
+ const className = `${props?.className ?? ''} dcf-modal-expand`;
5478
+ return (await getNgxModalComponent({ props, ...{ inlineContent, className } }, {}, injector || undefined)).present();
5479
+ }
5349
5480
  /**
5350
5481
  * @description Retrieves a modal for selecting options.
5351
5482
  * @summary Creates and initializes a modal component for displaying a list of selectable options.
@@ -5723,7 +5854,7 @@ let CrudFieldComponent = class CrudFieldComponent extends NgxFormFieldDirective
5723
5854
  this.value = this.formControl.value;
5724
5855
  }
5725
5856
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CrudFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
5726
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CrudFieldComponent, isStandalone: true, selector: "ngx-decaf-crud-field", inputs: { operation: "operation", name: "name", className: "className", path: "path", childOf: "childOf", type: "type", value: "value", disabled: "disabled", label: "label", placeholder: "placeholder", format: "format", hidden: "hidden", max: "max", maxlength: "maxlength", min: "min", minlength: "minlength", pattern: "pattern", readonly: "readonly", required: "required", step: "step", equals: "equals", different: "different", lessThan: "lessThan", lessThanOrEqual: "lessThanOrEqual", greaterThan: "greaterThan", greaterThanOrEqual: "greaterThanOrEqual", alignment: "alignment", checked: "checked", justify: "justify", cancelText: "cancelText", interface: "interface", options: "options", mode: "mode", spellcheck: "spellcheck", inputmode: "inputmode", autocomplete: "autocomplete", fill: "fill", labelPlacement: "labelPlacement", updateOn: "updateOn", formGroup: "formGroup", formControl: "formControl", multiple: "multiple", uid: "uid", page: "page", translatable: "translatable" }, host: { listeners: { "window:fieldsetUpdateGroupEvent": "handleFieldsetUpdateGroupEvent($event)" }, properties: { "attr.id": "uid", "attr.class": "className" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: "@if (operation === 'read' || operation === 'delete') {\n <ng-container>\n <div>\n <ion-item [class]=\"'dcf-input-item ' + operation\" #component>\n <ion-label>\n {{ label | translate }}<br />\n @if (value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n @if (['checkbox'].includes(type)) {\n <ion-icon aria-hidden=\"true\" class=\"dcf-margin-small-top\" [color]=\"!isDarkMode ? 'primary' : 'light'\" size=\"large\" name=\"checkmark-circle-outline\"></ion-icon>\n } @else {\n <br />\n }\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n @if (formControl) {\n <ng-container [formGroup]=\"multiple ? activeFormGroup : formControl.parent\">\n <div\n [id]=\"uid\" #container\n [class]=\"'dcf-input-item ' + (operation || 'create')\"\n [class.dcf-field-required]=\"required\"\n [class.dcf-field-readonly]=\"readonly\"\n >\n @if (type === 'textarea') {\n <ion-textarea\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [inputmode]=\"inputmode\"\n [spellcheck]=\"spellcheck\"\n [rows]=\"rows\"\n [labelPlacement]=\"labelPlacement\"\n [value]=\"value\"\n [fill]=\"fill\"\n [errorText]=\"getErrors(container)\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [label]=\"label | translate\"\n #component>\n </ion-textarea>\n }\n @else if (type === 'checkbox') {\n @if (!options?.length) {\n <ion-item class=\"dcf-width-1-1\" [hidden]=\"hidden\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify || 'start'\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span>{{label | translate}}</span>\n </ion-checkbox>\n\n </ion-item>\n } @else {\n <div class=\"dcf-checkbox-group\">\n <label class=\"dcf-label\" [for]=\"path\">{{ label | translate }}</label>\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-item class=\"dcf-width-1-1\" [button]=\"true\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"option.text\"\n [mode]=\"'md'\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"option.value\"\n [readonly]=\"readonly\"\n [checked]=\"isOptionChecked(option.value)\"\n (ionChange)=\"toggleOptionSelection(option.value, $event)\"\n #component>\n <span>{{ $index + 1 }}. {{ option?.text | translate }}</span>\n </ion-checkbox>\n </ion-item>\n }\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n }\n\n }\n @else if (type === 'radio' && options?.length) {\n <ion-radio-group class=\"dcf-width-1-1\" [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track $index) {\n <ion-item>\n <ion-radio\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [errorText]=\"getErrors(container)\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ option?.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if (type === 'select') {\n <div>\n <ion-select\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [interface]=\"interface\"\n [mode]=\"'md'\"\n [hidden]=\"hidden || !options?.length\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"label | translate\"\n [value]=\"value\"\n (click)=\"openSelectOptions($event, interface)\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [interface]=\"interface\" #component>\n @if (options?.length) {\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n }\n </ion-select>\n <div class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></div>\n @if (!options?.length) {\n <ion-text color=\"danger\">\n * {{ 'errors.empty_options' | translate:{'0': name} }}\n </ion-text>\n }\n </div>\n }\n @else {\n <ion-input\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [type]=\"type\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [max]=\"max !== undefined ? max : null\"\n [min]=\"min !== undefined ? min : null\"\n [pattern]=\"pattern !== undefined ? pattern : null\"\n [step]=\"step !== undefined ? step : null\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [label]=\"label | translate\" #component />\n }\n </div>\n </ng-container>\n } @else {\n <div>\n <p class=\"dcf-error\">\n {{ 'errors.form.control' | translate:{'0': name} }}\n </p>\n </div>\n }\n\n}\n\n", styles: ["ion-item{--border-color: transparent}ion-item:not(.dcf-input-item){--inner-padding-start: 0rem;--padding-start: 0rem;--background: transparent}ion-item.dcf-input-item{--padding-end: 0rem;--padding-start: 0px !important;--padding-top: 0px !important;--inner-padding-start: .75rem;--background: transparent;--background-hover-opacity: .1;--background-activated-opacity: .15;--background-focused-opacity: .15;--background-hover: var(--dcf-color-primary);--background-focused: var(--dcf-color-primary);--border-color: var(--dcf-color-gray-2)}ion-item.dcf-input-item.dcf-palette-dark{--border-color: var(--dcf-color-gray-6) !important}ion-item.dcf-input-item.read,ion-item.dcf-input-item.delete{--min-height: 30px;padding:unset;margin:unset!important;margin-bottom:var(--dcf-margin-xsmall)!important}ion-item.dcf-input-item.read ion-label,ion-item.dcf-input-item.delete ion-label{font-weight:600;margin-top:0!important;margin-bottom:.25rem!important;font-size:.925rem}ion-item.dcf-input-item.read ion-label:not(:first-of-type),ion-item.dcf-input-item.delete ion-label:not(:first-of-type){margin:100rem}ion-item.dcf-input-item.read span,ion-item.dcf-input-item.read ion-text,ion-item.dcf-input-item.delete span,ion-item.dcf-input-item.delete ion-text{font-weight:400!important;font-size:.825rem;min-height:.5rem!important}ion-item.dcf-input-item.read span:not(.dcf-display-block),ion-item.dcf-input-item.read ion-text:not(.dcf-display-block),ion-item.dcf-input-item.delete span:not(.dcf-display-block),ion-item.dcf-input-item.delete ion-text:not(.dcf-display-block){display:inline-block}ion-item.dcf-input-item.read span.dcf-display-block,ion-item.dcf-input-item.read ion-text.dcf-display-block,ion-item.dcf-input-item.delete span.dcf-display-block,ion-item.dcf-input-item.delete ion-text.dcf-display-block{display:block!important}ion-item.dcf-input-item>*,ion-item.dcf-input-item ion-select{width:100%!important}ion-item.dcf-input-item.create.checkbox+.checkbox,ion-item.dcf-input-item.update.checkbox+.checkbox{margin-top:-.25rem!important}ion-item.dcf-input-item.create ion-item,ion-item.dcf-input-item.update ion-item{--border-color: transparent}ion-item.dcf-input-item.create ion-item.dcf-text-wrap ion-label>*,ion-item.dcf-input-item.update ion-item.dcf-text-wrap ion-label>*{white-space:wrap!important;word-break:break-all!important}ion-textarea textarea{scrollbar-width:thin!important;margin-bottom:.5rem!important}ion-select.dcf-select-label-placement-floating::part(label){line-height:1.2rem!important}.dcf-proccessing,.dcf-proccessing *{pointer-events:none;touch-action:none;cursor:text}ion-checkbox::part(container){border:2px solid var(--dcf-color-primary);margin-left:.5rem;margin-right:.5rem;border-radius:var(--dcf-border-radius-small);padding:3px}ion-checkbox{--size: 1.5rem;--checkbox-background-checked: var(--dcf-color-primary);--checkmark-width: 2px}ion-radio-group .dcf-radio-group-label{font-weight:600}ion-radio-group .dcf-radio-group-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}ion-radio-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-checkbox-group{width:100%}.dcf-checkbox-group .dcf-label{font-weight:600}.dcf-checkbox-group .dcf-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}.dcf-checkbox-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-error{position:absolute;color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999}.dcf-error .ti,.dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.dcf-helper{font-size:.875rem!important;font-weight:500;margin-top:.25rem;margin-bottom:-.75rem}.dcf-helper.dcf-has-action{cursor:pointer;text-decoration:underline}.dcf-error+.dcf-helper{padding-top:1rem}::ng-deep ion-textarea{min-height:80px!important;scrollbar-color:#888 #f0f0f0;scrollbar-width:thin}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonRadioGroup, selector: "ion-radio-group", inputs: ["allowEmptySelection", "compareWith", "errorText", "helperText", "name", "value"] }, { kind: "component", type: IonRadio, selector: "ion-radio", inputs: ["alignment", "color", "disabled", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
5857
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CrudFieldComponent, isStandalone: true, selector: "ngx-decaf-crud-field", inputs: { operation: "operation", name: "name", className: "className", path: "path", childOf: "childOf", type: "type", value: "value", disabled: "disabled", label: "label", placeholder: "placeholder", format: "format", hidden: "hidden", max: "max", maxlength: "maxlength", min: "min", minlength: "minlength", pattern: "pattern", readonly: "readonly", required: "required", step: "step", equals: "equals", different: "different", lessThan: "lessThan", lessThanOrEqual: "lessThanOrEqual", greaterThan: "greaterThan", greaterThanOrEqual: "greaterThanOrEqual", alignment: "alignment", checked: "checked", justify: "justify", cancelText: "cancelText", interface: "interface", options: "options", mode: "mode", spellcheck: "spellcheck", inputmode: "inputmode", autocomplete: "autocomplete", fill: "fill", labelPlacement: "labelPlacement", updateOn: "updateOn", formGroup: "formGroup", formControl: "formControl", multiple: "multiple", uid: "uid", page: "page", translatable: "translatable" }, host: { listeners: { "window:fieldsetUpdateGroupEvent": "handleFieldsetUpdateGroupEvent($event)" }, properties: { "attr.id": "uid", "attr.class": "className" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: "@if ((operation === 'read' || operation === 'delete') || readonly) {\n <ng-container>\n <div >\n <ion-item [class]=\"'dcf-input-item ' + operation\" #component>\n <ion-label>\n {{ label | translate }}<br />\n @if (value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n @if (['checkbox'].includes(type)) {\n <ion-icon aria-hidden=\"true\" class=\"dcf-margin-small-top\" [color]=\"!isDarkMode ? 'primary' : 'light'\" size=\"large\" name=\"checkmark-circle-outline\"></ion-icon>\n } @else {\n <br />\n }\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n @if (formControl) {\n <ng-container [formGroup]=\"multiple ? activeFormGroup : formControl.parent\">\n <div\n [id]=\"uid\" #container\n [class]=\"'dcf-input-item ' + (operation || 'create')\"\n [class.dcf-field-required]=\"required\"\n [class.dcf-field-readonly]=\"readonly\"\n >\n @if (type === 'textarea') {\n <ion-textarea\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [inputmode]=\"inputmode\"\n [spellcheck]=\"spellcheck\"\n [rows]=\"rows\"\n [labelPlacement]=\"labelPlacement\"\n [value]=\"value\"\n [fill]=\"fill\"\n [errorText]=\"getErrors(container)\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [label]=\"label | translate\"\n #component>\n </ion-textarea>\n }\n @else if (type === 'checkbox') {\n @if (!options?.length) {\n <ion-item class=\"dcf-width-1-1\" [hidden]=\"hidden\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify || 'start'\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span>{{label | translate}}</span>\n </ion-checkbox>\n\n </ion-item>\n } @else {\n <div class=\"dcf-checkbox-group\">\n <label class=\"dcf-label\" [for]=\"path\">{{ label | translate }}</label>\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-item class=\"dcf-width-1-1\" [button]=\"true\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"option.text\"\n [mode]=\"'md'\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"option.value\"\n [readonly]=\"readonly\"\n [checked]=\"isOptionChecked(option.value)\"\n (ionChange)=\"toggleOptionSelection(option.value, $event)\"\n #component>\n <span>{{ $index + 1 }}. {{ option?.text | translate }}</span>\n </ion-checkbox>\n </ion-item>\n }\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n }\n\n }\n @else if (type === 'radio' && options?.length) {\n <ion-radio-group class=\"dcf-width-1-1\" [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track $index) {\n <ion-item>\n <ion-radio\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [errorText]=\"getErrors(container)\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ option?.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if (type === 'select') {\n <div>\n <ion-select\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [interface]=\"interface\"\n [mode]=\"'md'\"\n [hidden]=\"hidden || !options?.length\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"label | translate\"\n [value]=\"value\"\n (click)=\"openSelectOptions($event, interface)\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [interface]=\"interface\" #component>\n @if (options?.length) {\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n }\n </ion-select>\n <div class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></div>\n @if (!options?.length) {\n <ion-text color=\"danger\">\n * {{ 'errors.empty_options' | translate:{'0': name} }}\n </ion-text>\n }\n </div>\n }\n @else {\n <ion-input\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [type]=\"type\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [max]=\"max !== undefined ? max : null\"\n [min]=\"min !== undefined ? min : null\"\n [pattern]=\"pattern !== undefined ? pattern : null\"\n [step]=\"step !== undefined ? step : null\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [label]=\"label | translate\" #component />\n }\n </div>\n </ng-container>\n } @else {\n <div>\n <p class=\"dcf-error\">\n {{ 'errors.form.control' | translate:{'0': name} }}\n </p>\n </div>\n }\n\n}\n\n", styles: ["ion-item{--border-color: transparent}ion-item:not(.dcf-input-item){--inner-padding-start: 0rem;--padding-start: 0rem;--background: transparent}ion-item.dcf-input-item{--padding-end: 0rem;--padding-start: 0px !important;--padding-top: 0px !important;--inner-padding-start: .75rem;--background: transparent;--background-hover-opacity: .1;--background-activated-opacity: .15;--background-focused-opacity: .15;--background-hover: var(--dcf-color-primary);--background-focused: var(--dcf-color-primary);--border-color: var(--dcf-color-gray-2)}ion-item.dcf-input-item.dcf-palette-dark{--border-color: var(--dcf-color-gray-6) !important}ion-item.dcf-input-item.read,ion-item.dcf-input-item.delete{--min-height: 30px;padding:unset;margin:unset!important;margin-bottom:var(--dcf-margin-xsmall)!important}ion-item.dcf-input-item.read ion-label,ion-item.dcf-input-item.delete ion-label{font-weight:600;margin-top:0!important;margin-bottom:.25rem!important;font-size:.925rem}ion-item.dcf-input-item.read ion-label:not(:first-of-type),ion-item.dcf-input-item.delete ion-label:not(:first-of-type){margin:100rem}ion-item.dcf-input-item.read span,ion-item.dcf-input-item.read ion-text,ion-item.dcf-input-item.delete span,ion-item.dcf-input-item.delete ion-text{font-weight:400!important;font-size:.825rem;min-height:.5rem!important}ion-item.dcf-input-item.read span:not(.dcf-display-block),ion-item.dcf-input-item.read ion-text:not(.dcf-display-block),ion-item.dcf-input-item.delete span:not(.dcf-display-block),ion-item.dcf-input-item.delete ion-text:not(.dcf-display-block){display:inline-block}ion-item.dcf-input-item.read span.dcf-display-block,ion-item.dcf-input-item.read ion-text.dcf-display-block,ion-item.dcf-input-item.delete span.dcf-display-block,ion-item.dcf-input-item.delete ion-text.dcf-display-block{display:block!important}ion-item.dcf-input-item>*,ion-item.dcf-input-item ion-select{width:100%!important}ion-item.dcf-input-item.create.checkbox+.checkbox,ion-item.dcf-input-item.update.checkbox+.checkbox{margin-top:-.25rem!important}ion-item.dcf-input-item.create ion-item,ion-item.dcf-input-item.update ion-item{--border-color: transparent}ion-item.dcf-input-item.create ion-item.dcf-text-wrap ion-label>*,ion-item.dcf-input-item.update ion-item.dcf-text-wrap ion-label>*{white-space:wrap!important;word-break:break-all!important}ion-textarea textarea{scrollbar-width:thin!important;margin-bottom:.5rem!important}ion-select.dcf-select-label-placement-floating::part(label){line-height:1.2rem!important}.dcf-proccessing,.dcf-proccessing *{pointer-events:none;touch-action:none;cursor:text}ion-checkbox::part(container){border:2px solid var(--dcf-color-primary);margin-left:.5rem;margin-right:.5rem;border-radius:var(--dcf-border-radius-small);padding:3px}ion-checkbox{--size: 1.5rem;--checkbox-background-checked: var(--dcf-color-primary);--checkmark-width: 2px}ion-radio-group .dcf-radio-group-label{font-weight:600}ion-radio-group .dcf-radio-group-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}ion-radio-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-checkbox-group{width:100%}.dcf-checkbox-group .dcf-label{font-weight:600}.dcf-checkbox-group .dcf-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}.dcf-checkbox-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-error{position:absolute;color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999}.dcf-error .ti,.dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.dcf-helper{font-size:.875rem!important;font-weight:500;margin-top:.25rem;margin-bottom:-.75rem}.dcf-helper.dcf-has-action{cursor:pointer;text-decoration:underline}.dcf-error+.dcf-helper{padding-top:1rem}::ng-deep ion-textarea{min-height:80px!important;scrollbar-color:#888 #f0f0f0;scrollbar-width:thin}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonRadioGroup, selector: "ion-radio-group", inputs: ["allowEmptySelection", "compareWith", "errorText", "helperText", "name", "value"] }, { kind: "component", type: IonRadio, selector: "ion-radio", inputs: ["alignment", "color", "disabled", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
5727
5858
  };
5728
5859
  CrudFieldComponent = __decorate([
5729
5860
  Dynamic()
@@ -5743,7 +5874,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
5743
5874
  IonLabel,
5744
5875
  IonText,
5745
5876
  IonTextarea
5746
- ], selector: 'ngx-decaf-crud-field', schemas: [CUSTOM_ELEMENTS_SCHEMA], host: { '[attr.id]': 'uid', '[attr.class]': 'className' }, template: "@if (operation === 'read' || operation === 'delete') {\n <ng-container>\n <div>\n <ion-item [class]=\"'dcf-input-item ' + operation\" #component>\n <ion-label>\n {{ label | translate }}<br />\n @if (value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n @if (['checkbox'].includes(type)) {\n <ion-icon aria-hidden=\"true\" class=\"dcf-margin-small-top\" [color]=\"!isDarkMode ? 'primary' : 'light'\" size=\"large\" name=\"checkmark-circle-outline\"></ion-icon>\n } @else {\n <br />\n }\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n @if (formControl) {\n <ng-container [formGroup]=\"multiple ? activeFormGroup : formControl.parent\">\n <div\n [id]=\"uid\" #container\n [class]=\"'dcf-input-item ' + (operation || 'create')\"\n [class.dcf-field-required]=\"required\"\n [class.dcf-field-readonly]=\"readonly\"\n >\n @if (type === 'textarea') {\n <ion-textarea\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [inputmode]=\"inputmode\"\n [spellcheck]=\"spellcheck\"\n [rows]=\"rows\"\n [labelPlacement]=\"labelPlacement\"\n [value]=\"value\"\n [fill]=\"fill\"\n [errorText]=\"getErrors(container)\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [label]=\"label | translate\"\n #component>\n </ion-textarea>\n }\n @else if (type === 'checkbox') {\n @if (!options?.length) {\n <ion-item class=\"dcf-width-1-1\" [hidden]=\"hidden\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify || 'start'\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span>{{label | translate}}</span>\n </ion-checkbox>\n\n </ion-item>\n } @else {\n <div class=\"dcf-checkbox-group\">\n <label class=\"dcf-label\" [for]=\"path\">{{ label | translate }}</label>\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-item class=\"dcf-width-1-1\" [button]=\"true\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"option.text\"\n [mode]=\"'md'\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"option.value\"\n [readonly]=\"readonly\"\n [checked]=\"isOptionChecked(option.value)\"\n (ionChange)=\"toggleOptionSelection(option.value, $event)\"\n #component>\n <span>{{ $index + 1 }}. {{ option?.text | translate }}</span>\n </ion-checkbox>\n </ion-item>\n }\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n }\n\n }\n @else if (type === 'radio' && options?.length) {\n <ion-radio-group class=\"dcf-width-1-1\" [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track $index) {\n <ion-item>\n <ion-radio\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [errorText]=\"getErrors(container)\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ option?.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if (type === 'select') {\n <div>\n <ion-select\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [interface]=\"interface\"\n [mode]=\"'md'\"\n [hidden]=\"hidden || !options?.length\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"label | translate\"\n [value]=\"value\"\n (click)=\"openSelectOptions($event, interface)\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [interface]=\"interface\" #component>\n @if (options?.length) {\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n }\n </ion-select>\n <div class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></div>\n @if (!options?.length) {\n <ion-text color=\"danger\">\n * {{ 'errors.empty_options' | translate:{'0': name} }}\n </ion-text>\n }\n </div>\n }\n @else {\n <ion-input\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [type]=\"type\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [max]=\"max !== undefined ? max : null\"\n [min]=\"min !== undefined ? min : null\"\n [pattern]=\"pattern !== undefined ? pattern : null\"\n [step]=\"step !== undefined ? step : null\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [label]=\"label | translate\" #component />\n }\n </div>\n </ng-container>\n } @else {\n <div>\n <p class=\"dcf-error\">\n {{ 'errors.form.control' | translate:{'0': name} }}\n </p>\n </div>\n }\n\n}\n\n", styles: ["ion-item{--border-color: transparent}ion-item:not(.dcf-input-item){--inner-padding-start: 0rem;--padding-start: 0rem;--background: transparent}ion-item.dcf-input-item{--padding-end: 0rem;--padding-start: 0px !important;--padding-top: 0px !important;--inner-padding-start: .75rem;--background: transparent;--background-hover-opacity: .1;--background-activated-opacity: .15;--background-focused-opacity: .15;--background-hover: var(--dcf-color-primary);--background-focused: var(--dcf-color-primary);--border-color: var(--dcf-color-gray-2)}ion-item.dcf-input-item.dcf-palette-dark{--border-color: var(--dcf-color-gray-6) !important}ion-item.dcf-input-item.read,ion-item.dcf-input-item.delete{--min-height: 30px;padding:unset;margin:unset!important;margin-bottom:var(--dcf-margin-xsmall)!important}ion-item.dcf-input-item.read ion-label,ion-item.dcf-input-item.delete ion-label{font-weight:600;margin-top:0!important;margin-bottom:.25rem!important;font-size:.925rem}ion-item.dcf-input-item.read ion-label:not(:first-of-type),ion-item.dcf-input-item.delete ion-label:not(:first-of-type){margin:100rem}ion-item.dcf-input-item.read span,ion-item.dcf-input-item.read ion-text,ion-item.dcf-input-item.delete span,ion-item.dcf-input-item.delete ion-text{font-weight:400!important;font-size:.825rem;min-height:.5rem!important}ion-item.dcf-input-item.read span:not(.dcf-display-block),ion-item.dcf-input-item.read ion-text:not(.dcf-display-block),ion-item.dcf-input-item.delete span:not(.dcf-display-block),ion-item.dcf-input-item.delete ion-text:not(.dcf-display-block){display:inline-block}ion-item.dcf-input-item.read span.dcf-display-block,ion-item.dcf-input-item.read ion-text.dcf-display-block,ion-item.dcf-input-item.delete span.dcf-display-block,ion-item.dcf-input-item.delete ion-text.dcf-display-block{display:block!important}ion-item.dcf-input-item>*,ion-item.dcf-input-item ion-select{width:100%!important}ion-item.dcf-input-item.create.checkbox+.checkbox,ion-item.dcf-input-item.update.checkbox+.checkbox{margin-top:-.25rem!important}ion-item.dcf-input-item.create ion-item,ion-item.dcf-input-item.update ion-item{--border-color: transparent}ion-item.dcf-input-item.create ion-item.dcf-text-wrap ion-label>*,ion-item.dcf-input-item.update ion-item.dcf-text-wrap ion-label>*{white-space:wrap!important;word-break:break-all!important}ion-textarea textarea{scrollbar-width:thin!important;margin-bottom:.5rem!important}ion-select.dcf-select-label-placement-floating::part(label){line-height:1.2rem!important}.dcf-proccessing,.dcf-proccessing *{pointer-events:none;touch-action:none;cursor:text}ion-checkbox::part(container){border:2px solid var(--dcf-color-primary);margin-left:.5rem;margin-right:.5rem;border-radius:var(--dcf-border-radius-small);padding:3px}ion-checkbox{--size: 1.5rem;--checkbox-background-checked: var(--dcf-color-primary);--checkmark-width: 2px}ion-radio-group .dcf-radio-group-label{font-weight:600}ion-radio-group .dcf-radio-group-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}ion-radio-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-checkbox-group{width:100%}.dcf-checkbox-group .dcf-label{font-weight:600}.dcf-checkbox-group .dcf-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}.dcf-checkbox-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-error{position:absolute;color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999}.dcf-error .ti,.dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.dcf-helper{font-size:.875rem!important;font-weight:500;margin-top:.25rem;margin-bottom:-.75rem}.dcf-helper.dcf-has-action{cursor:pointer;text-decoration:underline}.dcf-error+.dcf-helper{padding-top:1rem}::ng-deep ion-textarea{min-height:80px!important;scrollbar-color:#888 #f0f0f0;scrollbar-width:thin}\n"] }]
5877
+ ], selector: 'ngx-decaf-crud-field', schemas: [CUSTOM_ELEMENTS_SCHEMA], host: { '[attr.id]': 'uid', '[attr.class]': 'className' }, template: "@if ((operation === 'read' || operation === 'delete') || readonly) {\n <ng-container>\n <div >\n <ion-item [class]=\"'dcf-input-item ' + operation\" #component>\n <ion-label>\n {{ label | translate }}<br />\n @if (value) {\n <ion-text [innerHTML]=\"type === 'password' ? '********' : value\"></ion-text>\n } @else {\n @if (['checkbox'].includes(type)) {\n <ion-icon aria-hidden=\"true\" class=\"dcf-margin-small-top\" [color]=\"!isDarkMode ? 'primary' : 'light'\" size=\"large\" name=\"checkmark-circle-outline\"></ion-icon>\n } @else {\n <br />\n }\n }\n </ion-label>\n </ion-item>\n </div>\n </ng-container>\n} @else {\n @if (formControl) {\n <ng-container [formGroup]=\"multiple ? activeFormGroup : formControl.parent\">\n <div\n [id]=\"uid\" #container\n [class]=\"'dcf-input-item ' + (operation || 'create')\"\n [class.dcf-field-required]=\"required\"\n [class.dcf-field-readonly]=\"readonly\"\n >\n @if (type === 'textarea') {\n <ion-textarea\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [autoGrow]=\"true\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [inputmode]=\"inputmode\"\n [spellcheck]=\"spellcheck\"\n [rows]=\"rows\"\n [labelPlacement]=\"labelPlacement\"\n [value]=\"value\"\n [fill]=\"fill\"\n [errorText]=\"getErrors(container)\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [label]=\"label | translate\"\n #component>\n </ion-textarea>\n }\n @else if (type === 'checkbox') {\n @if (!options?.length) {\n <ion-item class=\"dcf-width-1-1\" [hidden]=\"hidden\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [mode]=\"'md'\"\n [errorText]=\"getErrors(container)\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify || 'start'\"\n [value]=\"value\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\"\n #component>\n <span>{{label | translate}}</span>\n </ion-checkbox>\n\n </ion-item>\n } @else {\n <div class=\"dcf-checkbox-group\">\n <label class=\"dcf-label\" [for]=\"path\">{{ label | translate }}</label>\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-item class=\"dcf-width-1-1\" [button]=\"true\">\n <ion-checkbox\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"option.text\"\n [mode]=\"'md'\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [value]=\"option.value\"\n [readonly]=\"readonly\"\n [checked]=\"isOptionChecked(option.value)\"\n (ionChange)=\"toggleOptionSelection(option.value, $event)\"\n #component>\n <span>{{ $index + 1 }}. {{ option?.text | translate }}</span>\n </ion-checkbox>\n </ion-item>\n }\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n }\n\n }\n @else if (type === 'radio' && options?.length) {\n <ion-radio-group class=\"dcf-width-1-1\" [formControlName]=\"name\" [value]=\"value\" #component>\n <label class=\"dcf-radio-group-label\" [for]=\"path\">{{label | translate}}</label>\n @for(option of options; track $index) {\n <ion-item>\n <ion-radio\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [errorText]=\"getErrors(container)\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [readonly]=\"readonly\"\n [value]=\"option.value\"\n >{{ option?.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if (type === 'select') {\n <div>\n <ion-select\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [interface]=\"interface\"\n [mode]=\"'md'\"\n [hidden]=\"hidden || !options?.length\"\n [labelPlacement]=\"labelPlacement\"\n [label]=\"label | translate\"\n [value]=\"value\"\n (click)=\"openSelectOptions($event, interface)\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [interface]=\"interface\" #component>\n @if (options?.length) {\n @for(option of options; track trackItemFn($index, option.text)) {\n <ion-select-option [value]=\"option.value\">\n {{ option.text | translate }}\n </ion-select-option>\n }\n }\n </ion-select>\n <div class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></div>\n @if (!options?.length) {\n <ion-text color=\"danger\">\n * {{ 'errors.empty_options' | translate:{'0': name} }}\n </ion-text>\n }\n </div>\n }\n @else {\n <ion-input\n (ionInput)=\"handleModalChildChanges()\"\n (ionChange)=\"handleModalChildChanges()\"\n [id]=\"name\"\n [type]=\"type\"\n [mode]=\"'md'\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [labelPlacement]=\"labelPlacement\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [max]=\"max !== undefined ? max : null\"\n [min]=\"min !== undefined ? min : null\"\n [pattern]=\"pattern !== undefined ? pattern : null\"\n [step]=\"step !== undefined ? step : null\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [errorText]=\"getErrors(container)\"\n [label]=\"label | translate\" #component />\n }\n </div>\n </ng-container>\n } @else {\n <div>\n <p class=\"dcf-error\">\n {{ 'errors.form.control' | translate:{'0': name} }}\n </p>\n </div>\n }\n\n}\n\n", styles: ["ion-item{--border-color: transparent}ion-item:not(.dcf-input-item){--inner-padding-start: 0rem;--padding-start: 0rem;--background: transparent}ion-item.dcf-input-item{--padding-end: 0rem;--padding-start: 0px !important;--padding-top: 0px !important;--inner-padding-start: .75rem;--background: transparent;--background-hover-opacity: .1;--background-activated-opacity: .15;--background-focused-opacity: .15;--background-hover: var(--dcf-color-primary);--background-focused: var(--dcf-color-primary);--border-color: var(--dcf-color-gray-2)}ion-item.dcf-input-item.dcf-palette-dark{--border-color: var(--dcf-color-gray-6) !important}ion-item.dcf-input-item.read,ion-item.dcf-input-item.delete{--min-height: 30px;padding:unset;margin:unset!important;margin-bottom:var(--dcf-margin-xsmall)!important}ion-item.dcf-input-item.read ion-label,ion-item.dcf-input-item.delete ion-label{font-weight:600;margin-top:0!important;margin-bottom:.25rem!important;font-size:.925rem}ion-item.dcf-input-item.read ion-label:not(:first-of-type),ion-item.dcf-input-item.delete ion-label:not(:first-of-type){margin:100rem}ion-item.dcf-input-item.read span,ion-item.dcf-input-item.read ion-text,ion-item.dcf-input-item.delete span,ion-item.dcf-input-item.delete ion-text{font-weight:400!important;font-size:.825rem;min-height:.5rem!important}ion-item.dcf-input-item.read span:not(.dcf-display-block),ion-item.dcf-input-item.read ion-text:not(.dcf-display-block),ion-item.dcf-input-item.delete span:not(.dcf-display-block),ion-item.dcf-input-item.delete ion-text:not(.dcf-display-block){display:inline-block}ion-item.dcf-input-item.read span.dcf-display-block,ion-item.dcf-input-item.read ion-text.dcf-display-block,ion-item.dcf-input-item.delete span.dcf-display-block,ion-item.dcf-input-item.delete ion-text.dcf-display-block{display:block!important}ion-item.dcf-input-item>*,ion-item.dcf-input-item ion-select{width:100%!important}ion-item.dcf-input-item.create.checkbox+.checkbox,ion-item.dcf-input-item.update.checkbox+.checkbox{margin-top:-.25rem!important}ion-item.dcf-input-item.create ion-item,ion-item.dcf-input-item.update ion-item{--border-color: transparent}ion-item.dcf-input-item.create ion-item.dcf-text-wrap ion-label>*,ion-item.dcf-input-item.update ion-item.dcf-text-wrap ion-label>*{white-space:wrap!important;word-break:break-all!important}ion-textarea textarea{scrollbar-width:thin!important;margin-bottom:.5rem!important}ion-select.dcf-select-label-placement-floating::part(label){line-height:1.2rem!important}.dcf-proccessing,.dcf-proccessing *{pointer-events:none;touch-action:none;cursor:text}ion-checkbox::part(container){border:2px solid var(--dcf-color-primary);margin-left:.5rem;margin-right:.5rem;border-radius:var(--dcf-border-radius-small);padding:3px}ion-checkbox{--size: 1.5rem;--checkbox-background-checked: var(--dcf-color-primary);--checkmark-width: 2px}ion-radio-group .dcf-radio-group-label{font-weight:600}ion-radio-group .dcf-radio-group-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}ion-radio-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-checkbox-group{width:100%}.dcf-checkbox-group .dcf-label{font-weight:600}.dcf-checkbox-group .dcf-label~ion-item{margin-top:.5rem;--inner-padding-start: .75rem}.dcf-checkbox-group+.dcf-helper{padding-left:.75rem;position:relative}.dcf-error{position:absolute;color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999}.dcf-error .ti,.dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.dcf-helper{font-size:.875rem!important;font-weight:500;margin-top:.25rem;margin-bottom:-.75rem}.dcf-helper.dcf-has-action{cursor:pointer;text-decoration:underline}.dcf-error+.dcf-helper{padding-top:1rem}::ng-deep ion-textarea{min-height:80px!important;scrollbar-color:#888 #f0f0f0;scrollbar-width:thin}\n"] }]
5747
5878
  }], propDecorators: { operation: [{
5748
5879
  type: Input,
5749
5880
  args: [{ required: true }]
@@ -6060,7 +6191,7 @@ class NgxFormDirective extends NgxParentComponentDirective {
6060
6191
  return NgxFormService.reset(this.formGroup);
6061
6192
  this.location.back();
6062
6193
  }
6063
- async handleSubmit(event, eventName, componentName) {
6194
+ async submit(event, eventName, componentName) {
6064
6195
  if (event) {
6065
6196
  event.preventDefault();
6066
6197
  event.stopImmediatePropagation();
@@ -6530,7 +6661,7 @@ let LayoutComponent = class LayoutComponent extends NgxParentComponentDirective
6530
6661
  this.changeDetectorRef.detectChanges();
6531
6662
  }
6532
6663
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: LayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6533
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: LayoutComponent, isStandalone: true, selector: "ngx-decaf-layout", inputs: { gap: "gap", grid: "grid", flexMode: "flexMode", rowCard: "rowCard", maxColsLength: "maxColsLength" }, usesInheritance: true, ngImport: i0, template: "<section class=\"dcf-layout-container\">\n @if (initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n @if (row?.cols?.length) {\n <div\n [id]=\"uid\"\n [class]=\"\n (!grid\n ? 'dcf-layout-row '\n : 'dcf-layout-row dcf-grid ' + 'dcf-grid-' + gap) +\n ' ' +\n (className || '')\n \"\n [class.dcf-grid-match]=\"match\"\n [class.dcf-grid-bordered]=\"borders\"\n >\n @if (row?.title?.length) {\n <div class=\"dcf-width-1-1 dcf-grid-title\">\n <h3 class=\"\">{{ row.title | translate }}</h3>\n </div>\n }\n @for (\n child of row.cols;\n track trackItemFn($index, child.col);\n let colIndex = $index\n ) {\n\n <div\n [class]=\"'dcf-grid-col ' + child.colClass\"\n [class.dcf-first-column]=\"$index === 0\"\n [class.dcf-layout-separator]=\"child.props?.separator ?? false\"\n >\n <div>\n\n @if (child.tag === \"ngx-decaf-crud-form\") {\n\n <ngx-decaf-card\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ngx-decaf-card>\n } @else {\n\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [parentForm]=\"parentForm || child.parentForm || child?.formGroup\"\n [children]=\"child?.children || []\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{ props: child.props }\"\n />\n }\n </div>\n </div>\n }\n </div>\n }\n }\n }\n</section>\n", styles: [".dcf-grid.dcf-grid-bordered>div>div{padding:var(--dcf-padding-small) var(--dcf-padding);border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-2);background:var(--dcf-card-background)!important}.dcf-grid .dcf-grid-title{padding:unset;margin:unset}.dcf-grid .dcf-grid-title>*{padding:unset;margin:unset;padding-left:var(--dcf-padding-small);font-size:1.05rem!important;font-weight:600;background:none;box-shadow:none;display:flex;align-items:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.dcf-grid.dcf-grid-match ::ng-deep ngx-decaf-component-renderer>*>*{height:100%!important}.dcf-grid.dcf-grid-small.dcf-grid-nested{padding:0 .5rem!important}.dcf-grid.dcf-grid-small>div{margin-bottom:1.75rem}.dcf-grid.dcf-grid-small>div.dcf-layout-separator{margin-bottom:1rem}.dcf-grid.dcf-grid-small>div.dcf-grid-bordered:last-child{margin-bottom:0}.dcf-grid.dcf-grid-small+.dcf-grid-small{margin-bottom:1.75rem}.dcf-grid.dcf-grid-small+.dcf-grid-small.dcf-layout-separator{margin-bottom:1rem}::ng-deep ngx-decaf-component-renderer>*>div{margin-bottom:0!important}\n"], dependencies: [{ kind: "component", type: CardComponent, selector: "ngx-decaf-card", inputs: ["type", "title", "body", "subtitle", "color", "separator", "borders", "inlineContent", "inlineContentPosition"] }, { kind: "component", type: ModelRendererComponent, selector: "ngx-decaf-model-renderer", inputs: ["projectable"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
6664
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: LayoutComponent, isStandalone: true, selector: "ngx-decaf-layout", inputs: { gap: "gap", grid: "grid", flexMode: "flexMode", rowCard: "rowCard", maxColsLength: "maxColsLength" }, usesInheritance: true, ngImport: i0, template: "<section class=\"dcf-layout-container\">\n @if (initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n @if (row?.cols?.length) {\n <div\n [id]=\"uid\"\n [class]=\"\n (!grid\n ? 'dcf-layout-row '\n : 'dcf-layout-row dcf-grid ' + 'dcf-grid-' + gap) +\n ' ' +\n (className || '')\n \"\n [class.dcf-grid-match]=\"match\"\n [class.dcf-grid-bordered]=\"borders\"\n >\n @if (row?.title?.length) {\n <div class=\"dcf-width-1-1 dcf-grid-title\">\n <h3 class=\"\">{{ row.title | translate }}</h3>\n </div>\n }\n @for (\n child of row.cols;\n track trackItemFn($index, child.col);\n let colIndex = $index\n ) {\n\n <div\n [class]=\"'dcf-grid-col ' + child.colClass\"\n [class.dcf-first-column]=\"$index === 0\"\n [class.dcf-layout-separator]=\"child.props?.separator ?? false\"\n >\n <div>\n\n @if (child.tag === \"ngx-decaf-crud-form\") {\n\n <ngx-decaf-card\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ngx-decaf-card>\n } @else {\n\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [parentForm]=\"parentForm || child.parentForm || child?.formGroup\"\n [children]=\"child?.children || []\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{ props: child.props }\"\n />\n }\n </div>\n </div>\n }\n </div>\n }\n }\n }\n</section>\n", styles: [".dcf-grid.dcf-grid-collapse.read>div{margin:var(--dcf-margin-small) 0!important}.dcf-grid.dcf-grid-bordered>div>div{padding:var(--dcf-padding-small) var(--dcf-padding);border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-2);background:var(--dcf-card-background)!important}.dcf-grid .dcf-grid-title{padding:unset;margin:unset}.dcf-grid .dcf-grid-title>*{padding:unset;margin:unset;padding-left:var(--dcf-padding-small);font-size:1.05rem!important;font-weight:600;background:none;box-shadow:none;display:flex;align-items:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.dcf-grid.dcf-grid-match ::ng-deep ngx-decaf-component-renderer>*>*{height:100%!important}.dcf-grid.dcf-grid-small.dcf-grid-nested{padding:0 .5rem!important}.dcf-grid.dcf-grid-small>div{margin-bottom:1.75rem}.dcf-grid.dcf-grid-small>div.dcf-layout-separator{margin-bottom:1rem}.dcf-grid.dcf-grid-small>div.dcf-grid-bordered:last-child{margin-bottom:0}.dcf-grid.dcf-grid-small+.dcf-grid-small{margin-bottom:1.75rem}.dcf-grid.dcf-grid-small+.dcf-grid-small.dcf-layout-separator{margin-bottom:1rem}::ng-deep ngx-decaf-component-renderer>*>div{margin-bottom:0!important}\n"], dependencies: [{ kind: "component", type: CardComponent, selector: "ngx-decaf-card", inputs: ["type", "title", "body", "subtitle", "color", "separator", "borders", "inlineContent", "inlineContentPosition"] }, { kind: "component", type: ModelRendererComponent, selector: "ngx-decaf-model-renderer", inputs: ["projectable"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
6534
6665
  };
6535
6666
  LayoutComponent = __decorate([
6536
6667
  Dynamic(),
@@ -6538,7 +6669,7 @@ LayoutComponent = __decorate([
6538
6669
  ], LayoutComponent);
6539
6670
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: LayoutComponent, decorators: [{
6540
6671
  type: Component,
6541
- args: [{ selector: 'ngx-decaf-layout', imports: [TranslatePipe, CardComponent, ModelRendererComponent, ComponentRendererComponent], standalone: true, template: "<section class=\"dcf-layout-container\">\n @if (initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n @if (row?.cols?.length) {\n <div\n [id]=\"uid\"\n [class]=\"\n (!grid\n ? 'dcf-layout-row '\n : 'dcf-layout-row dcf-grid ' + 'dcf-grid-' + gap) +\n ' ' +\n (className || '')\n \"\n [class.dcf-grid-match]=\"match\"\n [class.dcf-grid-bordered]=\"borders\"\n >\n @if (row?.title?.length) {\n <div class=\"dcf-width-1-1 dcf-grid-title\">\n <h3 class=\"\">{{ row.title | translate }}</h3>\n </div>\n }\n @for (\n child of row.cols;\n track trackItemFn($index, child.col);\n let colIndex = $index\n ) {\n\n <div\n [class]=\"'dcf-grid-col ' + child.colClass\"\n [class.dcf-first-column]=\"$index === 0\"\n [class.dcf-layout-separator]=\"child.props?.separator ?? false\"\n >\n <div>\n\n @if (child.tag === \"ngx-decaf-crud-form\") {\n\n <ngx-decaf-card\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ngx-decaf-card>\n } @else {\n\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [parentForm]=\"parentForm || child.parentForm || child?.formGroup\"\n [children]=\"child?.children || []\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{ props: child.props }\"\n />\n }\n </div>\n </div>\n }\n </div>\n }\n }\n }\n</section>\n", styles: [".dcf-grid.dcf-grid-bordered>div>div{padding:var(--dcf-padding-small) var(--dcf-padding);border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-2);background:var(--dcf-card-background)!important}.dcf-grid .dcf-grid-title{padding:unset;margin:unset}.dcf-grid .dcf-grid-title>*{padding:unset;margin:unset;padding-left:var(--dcf-padding-small);font-size:1.05rem!important;font-weight:600;background:none;box-shadow:none;display:flex;align-items:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.dcf-grid.dcf-grid-match ::ng-deep ngx-decaf-component-renderer>*>*{height:100%!important}.dcf-grid.dcf-grid-small.dcf-grid-nested{padding:0 .5rem!important}.dcf-grid.dcf-grid-small>div{margin-bottom:1.75rem}.dcf-grid.dcf-grid-small>div.dcf-layout-separator{margin-bottom:1rem}.dcf-grid.dcf-grid-small>div.dcf-grid-bordered:last-child{margin-bottom:0}.dcf-grid.dcf-grid-small+.dcf-grid-small{margin-bottom:1.75rem}.dcf-grid.dcf-grid-small+.dcf-grid-small.dcf-layout-separator{margin-bottom:1rem}::ng-deep ngx-decaf-component-renderer>*>div{margin-bottom:0!important}\n"] }]
6672
+ args: [{ selector: 'ngx-decaf-layout', imports: [TranslatePipe, CardComponent, ModelRendererComponent, ComponentRendererComponent], standalone: true, template: "<section class=\"dcf-layout-container\">\n @if (initialized) {\n @for (row of rows; track trackItemFn($index, row); let rowIndex = $index) {\n @if (row?.cols?.length) {\n <div\n [id]=\"uid\"\n [class]=\"\n (!grid\n ? 'dcf-layout-row '\n : 'dcf-layout-row dcf-grid ' + 'dcf-grid-' + gap) +\n ' ' +\n (className || '')\n \"\n [class.dcf-grid-match]=\"match\"\n [class.dcf-grid-bordered]=\"borders\"\n >\n @if (row?.title?.length) {\n <div class=\"dcf-width-1-1 dcf-grid-title\">\n <h3 class=\"\">{{ row.title | translate }}</h3>\n </div>\n }\n @for (\n child of row.cols;\n track trackItemFn($index, child.col);\n let colIndex = $index\n ) {\n\n <div\n [class]=\"'dcf-grid-col ' + child.colClass\"\n [class.dcf-first-column]=\"$index === 0\"\n [class.dcf-layout-separator]=\"child.props?.separator ?? false\"\n >\n <div>\n\n @if (child.tag === \"ngx-decaf-crud-form\") {\n\n <ngx-decaf-card\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ngx-decaf-card>\n } @else {\n\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n [className]=\"\n (match ? 'dcf-height-1-1 dcf-card-layout' : '') +\n className\n \"\n [parentForm]=\"parentForm || child.parentForm || child?.formGroup\"\n [children]=\"child?.children || []\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]=\"{ props: child.props }\"\n />\n }\n </div>\n </div>\n }\n </div>\n }\n }\n }\n</section>\n", styles: [".dcf-grid.dcf-grid-collapse.read>div{margin:var(--dcf-margin-small) 0!important}.dcf-grid.dcf-grid-bordered>div>div{padding:var(--dcf-padding-small) var(--dcf-padding);border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-2);background:var(--dcf-card-background)!important}.dcf-grid .dcf-grid-title{padding:unset;margin:unset}.dcf-grid .dcf-grid-title>*{padding:unset;margin:unset;padding-left:var(--dcf-padding-small);font-size:1.05rem!important;font-weight:600;background:none;box-shadow:none;display:flex;align-items:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.dcf-grid.dcf-grid-match ::ng-deep ngx-decaf-component-renderer>*>*{height:100%!important}.dcf-grid.dcf-grid-small.dcf-grid-nested{padding:0 .5rem!important}.dcf-grid.dcf-grid-small>div{margin-bottom:1.75rem}.dcf-grid.dcf-grid-small>div.dcf-layout-separator{margin-bottom:1rem}.dcf-grid.dcf-grid-small>div.dcf-grid-bordered:last-child{margin-bottom:0}.dcf-grid.dcf-grid-small+.dcf-grid-small{margin-bottom:1.75rem}.dcf-grid.dcf-grid-small+.dcf-grid-small.dcf-layout-separator{margin-bottom:1rem}::ng-deep ngx-decaf-component-renderer>*>div{margin-bottom:0!important}\n"] }]
6542
6673
  }], ctorParameters: () => [], propDecorators: { gap: [{
6543
6674
  type: Input
6544
6675
  }], grid: [{
@@ -6587,7 +6718,7 @@ let CrudFormComponent = class CrudFormComponent extends NgxFormDirective {
6587
6718
  });
6588
6719
  }
6589
6720
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CrudFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6590
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CrudFormComponent, isStandalone: true, selector: "ngx-decaf-crud-form", host: { properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "@if (operation !== 'read' && operation !== 'delete') {\n <form\n [class]=\"'dcf-form-grid ' + operation\" #component\n [id]=\"rendererId\"\n [formGroup]=\"formGroup\"\n (ngSubmit)=\"handleSubmit($event)\"\n novalidate\n [target]=\"target\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n <ngx-decaf-layout\n [className]=\"'dcf-crud-form-grid dcf-grid-nested '\"\n [children]=\"children || []\"\n [parentForm]=\"formGroup || parentForm\"\n [match]=\"match ?? false\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [cols]=\"cols\" />\n }\n @if (initialized) {\n <div class=\"dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left\">\n <div>\n <ion-button type=\"submit\" [expand]=\"action ? 'block' : 'default'\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{ action ? action : options.buttons.submit.text}}\n </ion-button>\n </div>\n @if (!action) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n Back\n </ion-button>\n </div>\n }\n </div>\n }\n\n </form>\n} @else {\n <section [class]=\"'dcf-grid dcf-grid-small dcf-child-width-1-1 dcf-form-grid ' + operation\" #component [id]=\"uid\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n @for (child of children; track $index) {\n <div class=\"dcf-form-item\">\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n [projectable]=\"false\"\n [children]=\"child?.children || []\"\n [globals]=\"{props: child.props}\"\n />\n </div>\n }\n }\n </section>\n <section [class]=\"'dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if ([OperationKeys.READ, OperationKeys.DELETE].includes(operation) && modelId) {\n <div>\n <ion-button\n (click)=\"handleDelete()\"\n color=\"danger\"\n type=\"button\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n Delete\n </ion-button>\n </div>\n\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n\n <div>\n <ion-button\n type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n </div>\n }\n\n @if (options.buttons.clear) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{ [OperationKeys.DELETE, OperationKeys.READ, OperationKeys.UPDATE].includes(operation) ? 'Back' : options.buttons.clear?.text}}\n </ion-button>\n </div>\n\n }\n </section>\n}\n\n", styles: [".dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (min-width: 577px){.dcf-buttons-grid.dcf-flex{flex-direction:row-reverse}}@media (max-width: 576px){.dcf-buttons-grid.dcf-flex>div{width:100%}.dcf-buttons-grid.dcf-flex>div+div{margin-top:1rem}.dcf-buttons-grid.dcf-flex ion-button{width:100%}}.dcf-form-grid.create,.dcf-form-grid.update{margin-top:var(--dcf-margin-small)}.dcf-form-grid .dcf-form-item{margin-top:0!important}.dcf-form-grid.read .dcf-form-item{margin-bottom:var(--dcf-margin-small)}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: LayoutComponent, selector: "ngx-decaf-layout", inputs: ["gap", "grid", "flexMode", "rowCard", "maxColsLength"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
6721
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CrudFormComponent, isStandalone: true, selector: "ngx-decaf-crud-form", host: { properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "@if (operation !== 'read' && operation !== 'delete') {\n <form\n [class]=\"'dcf-form-grid ' + operation\" #component\n [id]=\"rendererId\"\n [formGroup]=\"formGroup\"\n (ngSubmit)=\"submit($event)\"\n novalidate\n [target]=\"target\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n <ngx-decaf-layout\n [className]=\"'dcf-crud-form-grid dcf-grid-nested '\"\n [children]=\"children || []\"\n [parentForm]=\"formGroup || parentForm\"\n [match]=\"match ?? false\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [cols]=\"cols\" />\n }\n @if (initialized) {\n <div class=\"dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left\">\n <div>\n <ion-button type=\"submit\" [expand]=\"action ? 'block' : 'default'\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{ action ? action : options.buttons.submit.text}}\n </ion-button>\n </div>\n @if (!action) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n Back\n </ion-button>\n </div>\n }\n </div>\n }\n\n </form>\n} @else {\n <section [class]=\"'dcf-grid dcf-grid-small dcf-child-width-1-1 dcf-form-grid ' + operation\" #component [id]=\"uid\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n @for (child of children; track $index) {\n <div class=\"dcf-form-item\">\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n [projectable]=\"false\"\n [children]=\"child?.children || []\"\n [globals]=\"{props: child.props}\"\n />\n </div>\n }\n }\n </section>\n <section [class]=\"'dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if ([OperationKeys.READ, OperationKeys.DELETE].includes(operation) && modelId) {\n <div>\n <ion-button\n (click)=\"handleDelete()\"\n color=\"danger\"\n type=\"button\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n Delete\n </ion-button>\n </div>\n\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n\n <div>\n <ion-button\n type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n </div>\n }\n\n @if (options.buttons.clear) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{ [OperationKeys.DELETE, OperationKeys.READ, OperationKeys.UPDATE].includes(operation) ? 'Back' : options.buttons.clear?.text}}\n </ion-button>\n </div>\n\n }\n </section>\n}\n\n", styles: [".dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (min-width: 577px){.dcf-buttons-grid.dcf-flex{flex-direction:row-reverse}}@media (max-width: 576px){.dcf-buttons-grid.dcf-flex>div{width:100%}.dcf-buttons-grid.dcf-flex>div+div{margin-top:1rem}.dcf-buttons-grid.dcf-flex ion-button{width:100%}}.dcf-form-grid.create,.dcf-form-grid.update{margin-top:var(--dcf-margin-small)}.dcf-form-grid .dcf-form-item{margin-top:0!important}.dcf-form-grid.read .dcf-form-item{margin-bottom:var(--dcf-margin-small)}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: LayoutComponent, selector: "ngx-decaf-layout", inputs: ["gap", "grid", "flexMode", "rowCard", "maxColsLength"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
6591
6722
  };
6592
6723
  CrudFormComponent = __decorate([
6593
6724
  Dynamic(),
@@ -6595,7 +6726,7 @@ CrudFormComponent = __decorate([
6595
6726
  ], CrudFormComponent);
6596
6727
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CrudFormComponent, decorators: [{
6597
6728
  type: Component,
6598
- args: [{ standalone: true, selector: 'ngx-decaf-crud-form', imports: [ReactiveFormsModule, LayoutComponent, ComponentRendererComponent, IonButton, IonIcon], host: { '[attr.id]': 'uid' }, template: "@if (operation !== 'read' && operation !== 'delete') {\n <form\n [class]=\"'dcf-form-grid ' + operation\" #component\n [id]=\"rendererId\"\n [formGroup]=\"formGroup\"\n (ngSubmit)=\"handleSubmit($event)\"\n novalidate\n [target]=\"target\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n <ngx-decaf-layout\n [className]=\"'dcf-crud-form-grid dcf-grid-nested '\"\n [children]=\"children || []\"\n [parentForm]=\"formGroup || parentForm\"\n [match]=\"match ?? false\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [cols]=\"cols\" />\n }\n @if (initialized) {\n <div class=\"dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left\">\n <div>\n <ion-button type=\"submit\" [expand]=\"action ? 'block' : 'default'\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{ action ? action : options.buttons.submit.text}}\n </ion-button>\n </div>\n @if (!action) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n Back\n </ion-button>\n </div>\n }\n </div>\n }\n\n </form>\n} @else {\n <section [class]=\"'dcf-grid dcf-grid-small dcf-child-width-1-1 dcf-form-grid ' + operation\" #component [id]=\"uid\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n @for (child of children; track $index) {\n <div class=\"dcf-form-item\">\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n [projectable]=\"false\"\n [children]=\"child?.children || []\"\n [globals]=\"{props: child.props}\"\n />\n </div>\n }\n }\n </section>\n <section [class]=\"'dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if ([OperationKeys.READ, OperationKeys.DELETE].includes(operation) && modelId) {\n <div>\n <ion-button\n (click)=\"handleDelete()\"\n color=\"danger\"\n type=\"button\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n Delete\n </ion-button>\n </div>\n\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n\n <div>\n <ion-button\n type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n </div>\n }\n\n @if (options.buttons.clear) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{ [OperationKeys.DELETE, OperationKeys.READ, OperationKeys.UPDATE].includes(operation) ? 'Back' : options.buttons.clear?.text}}\n </ion-button>\n </div>\n\n }\n </section>\n}\n\n", styles: [".dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (min-width: 577px){.dcf-buttons-grid.dcf-flex{flex-direction:row-reverse}}@media (max-width: 576px){.dcf-buttons-grid.dcf-flex>div{width:100%}.dcf-buttons-grid.dcf-flex>div+div{margin-top:1rem}.dcf-buttons-grid.dcf-flex ion-button{width:100%}}.dcf-form-grid.create,.dcf-form-grid.update{margin-top:var(--dcf-margin-small)}.dcf-form-grid .dcf-form-item{margin-top:0!important}.dcf-form-grid.read .dcf-form-item{margin-bottom:var(--dcf-margin-small)}\n"] }]
6729
+ args: [{ standalone: true, selector: 'ngx-decaf-crud-form', imports: [ReactiveFormsModule, LayoutComponent, ComponentRendererComponent, IonButton, IonIcon], host: { '[attr.id]': 'uid' }, template: "@if (operation !== 'read' && operation !== 'delete') {\n <form\n [class]=\"'dcf-form-grid ' + operation\" #component\n [id]=\"rendererId\"\n [formGroup]=\"formGroup\"\n (ngSubmit)=\"submit($event)\"\n novalidate\n [target]=\"target\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n <ngx-decaf-layout\n [className]=\"'dcf-crud-form-grid dcf-grid-nested '\"\n [children]=\"children || []\"\n [parentForm]=\"formGroup || parentForm\"\n [match]=\"match ?? false\"\n [gap]=\"'small'\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [cols]=\"cols\" />\n }\n @if (initialized) {\n <div class=\"dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left\">\n <div>\n <ion-button type=\"submit\" [expand]=\"action ? 'block' : 'default'\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{ action ? action : options.buttons.submit.text}}\n </ion-button>\n </div>\n @if (!action) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n Back\n </ion-button>\n </div>\n }\n </div>\n }\n\n </form>\n} @else {\n <section [class]=\"'dcf-grid dcf-grid-small dcf-child-width-1-1 dcf-form-grid ' + operation\" #component [id]=\"uid\">\n @if (!children?.length) {\n <ng-content #formContent></ng-content>\n } @else {\n @for (child of children; track $index) {\n <div class=\"dcf-form-item\">\n <ngx-decaf-component-renderer\n [tag]=\"child?.tag\"\n [projectable]=\"false\"\n [children]=\"child?.children || []\"\n [globals]=\"{props: child.props}\"\n />\n </div>\n }\n }\n </section>\n <section [class]=\"'dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left ' + operation\" [id]=\"uid\">\n @if ([OperationKeys.READ, OperationKeys.DELETE].includes(operation) && modelId) {\n <div>\n <ion-button\n (click)=\"handleDelete()\"\n color=\"danger\"\n type=\"button\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n Delete\n </ion-button>\n </div>\n\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n\n <div>\n <ion-button\n type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n </div>\n }\n\n @if (options.buttons.clear) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{ [OperationKeys.DELETE, OperationKeys.READ, OperationKeys.UPDATE].includes(operation) ? 'Back' : options.buttons.clear?.text}}\n </ion-button>\n </div>\n\n }\n </section>\n}\n\n", styles: [".dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (min-width: 577px){.dcf-buttons-grid.dcf-flex{flex-direction:row-reverse}}@media (max-width: 576px){.dcf-buttons-grid.dcf-flex>div{width:100%}.dcf-buttons-grid.dcf-flex>div+div{margin-top:1rem}.dcf-buttons-grid.dcf-flex ion-button{width:100%}}.dcf-form-grid.create,.dcf-form-grid.update{margin-top:var(--dcf-margin-small)}.dcf-form-grid .dcf-form-item{margin-top:0!important}.dcf-form-grid.read .dcf-form-item{margin-bottom:var(--dcf-margin-small)}\n"] }]
6599
6730
  }], ctorParameters: () => [] });
6600
6731
 
6601
6732
  class NgxSvgDirective {
@@ -7323,6 +7454,53 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
7323
7454
  // this.formGroup = (this.formGroup as FormGroup)
7324
7455
  // this.changeDetectorRef.detectChanges();
7325
7456
  }
7457
+ async refresh() {
7458
+ this.refreshing = true;
7459
+ this.changeDetectorRef.detectChanges();
7460
+ if ([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation)) {
7461
+ // if(!this.multiple) {
7462
+ // this.required = this.collapsable = false;
7463
+ // }
7464
+ this.items = [...this.value.map((v) => {
7465
+ return this.children.map((child) => {
7466
+ const { props, tag } = child;
7467
+ return {
7468
+ tag,
7469
+ props: {
7470
+ ...props,
7471
+ value: v[props.name] || ""
7472
+ }
7473
+ };
7474
+ });
7475
+ })];
7476
+ }
7477
+ if ([OperationKeys.CREATE, OperationKeys.UPDATE].includes(this.operation)) {
7478
+ const value = [...this.value];
7479
+ this.value = [];
7480
+ value.map(v => {
7481
+ const formGroup = this.activeFormGroup;
7482
+ if (value.length > formGroup.parent.length)
7483
+ NgxFormService.addGroupToParent(formGroup.parent);
7484
+ if (!Object.keys(this.mapper).length)
7485
+ this.mapper = this.getMapper(v);
7486
+ Object.entries(v).forEach(([key, value]) => {
7487
+ if (key === this.pk)
7488
+ formGroup.addControl(key, new FormControl({ value: value, disabled: false }));
7489
+ const control = formGroup.get(key);
7490
+ if (control instanceof FormControl) {
7491
+ control.setValue(value);
7492
+ control.updateValueAndValidity();
7493
+ formGroup.updateValueAndValidity();
7494
+ }
7495
+ });
7496
+ this.activeFormGroupIndex = formGroup.parent.length - 1;
7497
+ });
7498
+ this.setValue();
7499
+ this.changeDetectorRef.detectChanges();
7500
+ }
7501
+ this.refreshing = false;
7502
+ this.changeDetectorRef.detectChanges();
7503
+ }
7326
7504
  /**
7327
7505
  * @description Handles removal of the fieldset with slide animation.
7328
7506
  * @summary Initiates the removal process for the fieldset with a smooth slide-up animation.
@@ -7344,13 +7522,6 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
7344
7522
  this.activeFormGroupIndex = 0;
7345
7523
  this.accordionComponent.value = '';
7346
7524
  this.changeDetectorRef.detectChanges();
7347
- // this.component.nativeElement.classList.add('dcf-animation', 'dcf-animation-slide-top-medium', 'dcf-animation-reverse', 'dcf-animation-fast');
7348
- // setTimeout(() => {
7349
- // // Use Renderer2 to safely remove the element
7350
- // const parent = this.renderer.parentNode(this.component.nativeElement);
7351
- // if (parent)
7352
- // this.renderer.removeChild(parent, this.component.nativeElement);
7353
- // }, 150);
7354
7525
  }
7355
7526
  /**
7356
7527
  * @description Handles creating new items or triggering group addition events.
@@ -7586,7 +7757,7 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
7586
7757
  return child;
7587
7758
  });
7588
7759
  });
7589
- if (this.multiple)
7760
+ if (this.multiple && [OperationKeys.CREATE, OperationKeys.UPDATE].includes(this.operation))
7590
7761
  this.getFormArrayIndex(this.activeFormGroupIndex);
7591
7762
  return this.children;
7592
7763
  }
@@ -7601,9 +7772,10 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
7601
7772
  * @memberOf FieldsetComponent
7602
7773
  */
7603
7774
  setValue() {
7604
- this.value = this.formGroup.controls.map(({ value }) => value);
7775
+ const formGroup = this.formGroup;
7776
+ this.value = formGroup.controls.map(({ value }) => value);
7605
7777
  this.items = this.value
7606
- .filter((v) => (v[this.pk] || '').trim().length)
7778
+ .filter((v) => `${v[this.pk] || ''}`.trim().length)
7607
7779
  .map((v, index) => {
7608
7780
  return {
7609
7781
  ...itemMapper(Object.assign({}, v), this.mapper),
@@ -7643,7 +7815,7 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
7643
7815
  return this.mapper;
7644
7816
  }
7645
7817
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldsetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7646
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: FieldsetComponent, isStandalone: true, selector: "ngx-decaf-fieldset", inputs: { formControl: "formControl", collapsable: "collapsable", customTypes: "customTypes", title: "title", description: "description", multiple: "multiple", value: "value", borders: "borders", max: "max", required: "required", ordenable: "ordenable", editable: "editable" }, viewQueries: [{ propertyName: "accordionComponent", first: true, predicate: ["accordionComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.open]=\"isOpen\"\n [class.dcf-not-collapsable]=\"!collapsable\"\n #component>\n <div class=\"dcf-width-1-1\">\n @if (!collapsable || required) {\n <legend class=\"dcf-title\">{{ (title ? title : name) | translate }}</legend>\n }\n <ion-accordion-group class=\"dcf-width-1-1\" [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" [value]=\"(operation === 'read' || !collapsable) ? 'open' : ''\" #accordionComponent>\n <ion-accordion\n value=\"open\"\n [class.dcf-disabled]=\"!activePage\"\n [class.dcf-empty]=\"!items?.length\"\n >\n @if (collapsable && !required) {\n <ion-item slot=\"header\" [button]=\"collapsable\" (click)=\"handleAccordionToggle($event)\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-width-1-1\">\n <div class=\"dcf-width-expand\">\n <legend>{{ (title ? title : name) | translate }}</legend>\n </div>\n @if (!isRequired && ['create', 'update'].includes(operation) && collapsable && multiple) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleClear($event)\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n </div>\n </ion-item>\n }\n\n <div slot=\"content\" [attr.aria-hidden]=\"!isOpen\">\n @if (activePage) {\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested'\"\n [flexMode]=\"props.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [children]=\"activePage || []\"\n [parentForm]=\"formGroup || parentForm\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [borders]=\"activePage?.borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [hidden]=\"items.length === max && !updatingItem\"\n />\n </div>\n }\n </div>\n </ion-accordion>\n </ion-accordion-group>\n\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group [formGroup]=\"formGroup.parent\" [disabled]=\"updatingItem\" (ionItemReorder)=\"handleReorderItems($any($event))\" #accordionComponent>\n @for(item of items; track item.index) {\n <ion-item [class.not-unique]=\"item.title === isUniqueError\" [class.updating]=\"updatingItem?.[pk] === item.title\" lines=\"full\" [button]=\"false\">\n @if(ordenable) {\n @if (items?.length > 1 && !updatingItem) {\n <ion-reorder slot=\"start\">\n <ion-icon aria-hidden=\"true\" name=\"swap-vertical-outline\"></ion-icon>\n </ion-reorder>\n } @else {\n <div slot=\"start\">\n <ion-icon aria-hidden=\"true\" class=\"dcf-reorder-disabled\" size=\"small\" name=\"swap-vertical-outline\" disabled></ion-icon>\n </div>\n }\n }\n\n <ion-label [color]=\"(item.title === isUniqueError && !updatingItem?.[pk] === item.title) ? 'danger' : ''\">{{ item.index }}. {{ item.title }}\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{item.description}}</ion-text>\n }\n </ion-label>\n\n @if(editable) {\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleUpdateItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"create-outline\" color=\"dark\" ></ion-icon>\n </ion-button>\n }\n }\n\n\n @if (!updatingItem) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleRemoveItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"close-outline\" color=\"dark\"></ion-icon>\n </ion-button>\n }\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (isUniqueError) {\n <div class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\">\n <div class=\" dcf-grid dcf-grid-collapse dcf-width-1-1 \">\n <div class=\"dcf-auto\" [attr.style]=\"'max-width: 50px'\">\n <ion-icon aria-hidden=\"true\" name=\"alert-circle-outline\"></ion-icon>\n </div>\n <div class=\"dcf-width-expand\">\n <ion-text color=\"danger\" class=\"dcf-text-small\">{{ locale + '.not_unique' | translate : { value: isUniqueError } }}</ion-text>\n </div>\n </div>\n </div>\n }\n @if(max) {\n <div class=\"dcf-width-1-1 dcf-max-message-container\">\n <ion-text class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{ locale + (items.length !== max ? '.max_items' : '.max_items_reached') | translate : { '0': max } }}\n </ion-text>\n </div>\n }\n\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\" [class.dcf-not-collapsable]=\"!collapsable\" [class.dcf-empty]=\"!activePage\" [class.dcf-blank]=\"!borders\">\n @if (updatingItem) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ locale + '.cancel' | translate }}\n </ion-button>\n </div>\n <div>\n <ion-button size=\"small\" fill=\"clear\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update' | translate }}\n </ion-button>\n </div>\n } @else {\n\n @if (items.length < max || !max) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" [color]=\"isDarkMode ? 'light' : 'dark'\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"add-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.add' | translate }}\n </ion-button>\n </div>\n }\n }\n </div>\n }\n </div>\n</fieldset>\n\n", styles: ["ion-accordion ion-item[slot=header] .dcf-delete{width:30px}ion-accordion ion-item[slot=header] .dcf-delete ion-button{transform:translateY(-2px)}ion-accordion ion-item[slot=header] .dcf-delete ion-icon{font-size:1.15rem}ion-accordion.dcf-disabled [slot=content]{padding-bottom:0rem!important}ion-accordion.dcf-empty,ion-accordion.dcf-disabled{opacity:1!important}ion-accordion.dcf-empty ::ng-deep .ion-accordion-toggle-icon,ion-accordion.dcf-disabled ::ng-deep .ion-accordion-toggle-icon{display:none!important}ion-accordion.dcf-empty .dcf-delete,ion-accordion.dcf-disabled .dcf-delete{display:none!important}ion-accordion.dcf-empty ion-item[slot=header],ion-accordion.dcf-disabled ion-item[slot=header]{pointer-events:none;cursor:default!important}.dcf-not-collapsable .dcf-max-message-container{margin:.75rem;margin-top:0rem!important}.dcf-not-collapsable .dcf-max-message-container+.dcf-buttons-container{margin-top:var(--dcf-margin-small)!important}.dcf-fieldset-component{border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-3)}.dcf-fieldset-component.dcf-blank{border-color:transparent;padding:0rem!important;margin:0!important}.dcf-fieldset-component *{overflow-x:hidden!important}.dcf-fieldset-component ion-accordion:not(.dcf-empty){background:var(--dcf-card-background)!important}.dcf-fieldset-component ion-accordion ion-item{--background-hover: transparent !important}.dcf-fieldset-component.read,.dcf-fieldset-component.delete{margin:var(--dcf-margin-small) 0rem!important}.dcf-fieldset-component.read [slot=header],.dcf-fieldset-component.delete [slot=header]{margin-bottom:0rem!important}.dcf-fieldset-component [slot=header]{--border-color: transparent;--border-radius: 6px;--inner-border-width: 0;--padding-start: .65rem;--color: var(--ion-color-text) !important;margin:unset}.dcf-fieldset-component legend,.dcf-fieldset-component .dcf-title{font-weight:500;font-size:1rem;line-height:1.5rem;font-weight:600;margin:0;color:var(--ion-color-text)!important}.dcf-fieldset-component .dcf-title{padding:.8rem!important}.dcf-fieldset-component [slot=content]{padding:var(--dcf-padding-small) .25rem!important}.dcf-fieldset-component [slot=content]>div{padding-top:.25rem!important}.dcf-fieldset-component:not(.dcf-blank) ion-accordion [slot=header]{margin-top:.125rem}.dcf-fieldset-component .dcf-max-message-container{margin:var(--dcf-padding-small) .75rem}.dcf-not-unique-container{display:flex;justify-content:center;align-items:center;margin-bottom:var(--dcf-spacement);flex:1 1 auto}.dcf-not-unique-container>div{display:flex;justify-content:center;align-items:center}.dcf-not-unique-container ion-icon{transform:translatey(2px);margin-right:5px}.dcf-fields-list{padding:.25rem var(--dcf-margin-small);margin-bottom:var(--dcf-margin-small)!important}.dcf-fields-list ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--border-color: var(--dcf-color-gray-2) !important}.dcf-fields-list ion-item ion-icon.dcf-reorder-disabled{width:var(--dcf-spacement);transform:translatey(2px);color:var(--dcf-color-gray-4)}.dcf-fields-list ion-item.updating{--background: rgba(var(--dcf-color-primary-rgb), .1) !important}.dcf-fields-list ion-item.not-unique{--background: rgba(var(--dcf-color-danger-rgb), .05) !important}.dcf-fields-list ion-item .dcf-subtitle{font-size:.925rem;color:var(--ion-color-gray-4)}.dcf-buttons-container{margin-bottom:0!important;margin-top:-.5rem;padding:0rem .125rem}.dcf-buttons-container:not(.dcf-blank){padding-bottom:var(--dcf-padding-small)!important}.dcf-buttons-container.dcf-not-collapsable.dcf-empty{position:relative;top:-1rem!important}@media (max-width: 480px){.dcf-buttons-container{flex-direction:column-reverse;gap:.5rem;align-items:stretch}.dcf-buttons-container ion-button{width:100%;justify-content:center;height:40px}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: IonAccordionGroup, selector: "ion-accordion-group", inputs: ["animated", "disabled", "expand", "mode", "multiple", "readonly", "value"] }, { kind: "component", type: IonAccordion, selector: "ion-accordion", inputs: ["disabled", "mode", "readonly", "toggleIcon", "toggleIconSlot", "value"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonReorder, selector: "ion-reorder" }, { kind: "component", type: IonReorderGroup, selector: "ion-reorder-group", inputs: ["disabled"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: LayoutComponent, selector: "ngx-decaf-layout", inputs: ["gap", "grid", "flexMode", "rowCard", "maxColsLength"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
7818
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: FieldsetComponent, isStandalone: true, selector: "ngx-decaf-fieldset", inputs: { formControl: "formControl", collapsable: "collapsable", customTypes: "customTypes", title: "title", description: "description", multiple: "multiple", value: "value", borders: "borders", max: "max", required: "required", ordenable: "ordenable", editable: "editable" }, viewQueries: [{ propertyName: "accordionComponent", first: true, predicate: ["accordionComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n\n <fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.open]=\"isOpen\"\n [class.dcf-not-collapsable]=\"!collapsable\"\n #component>\n <div class=\"dcf-width-1-1\">\n @if (!collapsable || required) {\n <legend class=\"dcf-title\">{{ (title ? title : name) | translate }}</legend>\n }\n <ion-accordion-group class=\"dcf-width-1-1\" [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" [value]=\"(operation === 'read' || !collapsable) ? 'open' : ''\" #accordionComponent>\n <ion-accordion\n value=\"open\"\n [class.dcf-disabled]=\"!activePage\"\n [class.dcf-empty]=\"!items?.length\"\n >\n @if (collapsable && !required) {\n <ion-item slot=\"header\" [button]=\"collapsable\" (click)=\"handleAccordionToggle($event)\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-width-1-1\">\n <div class=\"dcf-width-expand\">\n <legend>{{ (title ? title : name) | translate }}</legend>\n </div>\n @if (!isRequired && ['create'].includes(operation) && collapsable && multiple) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleClear($event)\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n </div>\n </ion-item>\n }\n\n <div slot=\"content\" [attr.aria-hidden]=\"!isOpen\">\n @if (['create', 'update'].includes(operation) || !multiple) {\n @if(activePage) {\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested'\"\n [flexMode]=\"props.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [children]=\"activePage || []\"\n [parentForm]=\"formGroup || parentForm\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [borders]=\"activePage?.borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [hidden]=\"items.length === max && !updatingItem\"\n />\n </div>\n }\n } @else {\n @if(refreshing) {\n <div class=\"dcf-loading-container\">\n <ion-spinner name=\"crescent\" color=\"primary\"></ion-spinner>\n </div>\n } @else {\n @if(!items.length) {\n <div class=\"dcf-padding-xsmall\">\n <ion-text>{{ locale + '.empty' | translate }}</ion-text>\n </div>\n } @else {\n @for(item of items; track trackItemFn($index, item)) {\n <div class=\"dcf-fieldset-item\">\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested ' + operation\"\n [flexMode]=\"item?.props?.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'collapse'\"\n [children]=\"item || []\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [borders]=\"item?.props?.borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n />\n </div>\n </div>\n }\n }\n }\n }\n </div>\n </ion-accordion>\n </ion-accordion-group>\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group [formGroup]=\"formGroup.parent\" [disabled]=\"updatingItem\" (ionItemReorder)=\"handleReorderItems($any($event))\" #accordionComponent>\n @for(item of items; track item.index) {\n <ion-item [class.not-unique]=\"item.title === isUniqueError\" [class.updating]=\"updatingItem?.[pk] === item.title\" lines=\"full\" [button]=\"false\">\n @if(ordenable) {\n @if (items?.length > 1 && !updatingItem) {\n <ion-reorder slot=\"start\">\n <ion-icon aria-hidden=\"true\" name=\"swap-vertical-outline\"></ion-icon>\n </ion-reorder>\n } @else {\n <div slot=\"start\">\n <ion-icon aria-hidden=\"true\" class=\"dcf-reorder-disabled\" size=\"small\" name=\"swap-vertical-outline\" disabled></ion-icon>\n </div>\n }\n }\n\n <ion-label [color]=\"(item.title === isUniqueError && !updatingItem?.[pk] === item.title) ? 'danger' : ''\">{{ item.index }}. {{ item.title }}\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{item.description}}</ion-text>\n }\n </ion-label>\n\n @if(editable) {\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleUpdateItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"create-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\"></ion-icon>\n </ion-button>\n }\n }\n\n\n @if (!updatingItem) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleRemoveItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"close-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\"></ion-icon>\n </ion-button>\n }\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (isUniqueError) {\n <div class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\">\n <div class=\" dcf-grid dcf-grid-collapse dcf-width-1-1 \">\n <div class=\"dcf-auto\" [attr.style]=\"'max-width: 50px'\">\n <ion-icon aria-hidden=\"true\" name=\"alert-circle-outline\"></ion-icon>\n </div>\n <div class=\"dcf-width-expand\">\n <ion-text color=\"danger\" class=\"dcf-text-small\">{{ locale + '.not_unique' | translate : { value: isUniqueError } }}</ion-text>\n </div>\n </div>\n </div>\n }\n\n @if(max) {\n <div class=\"dcf-width-1-1 dcf-max-message-container\">\n <ion-text class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{ locale + (items.length !== max ? '.max_items' : '.max_items_reached') | translate : { '0': max } }}\n </ion-text>\n </div>\n }\n\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\" [class.dcf-not-collapsable]=\"!collapsable\" [class.dcf-empty]=\"!activePage\" [class.dcf-blank]=\"!borders\">\n @if (updatingItem) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ locale + '.cancel' | translate }}\n </ion-button>\n </div>\n <div>\n <ion-button size=\"small\" fill=\"clear\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update' | translate }}\n </ion-button>\n </div>\n } @else {\n @if (items.length < max || !max) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" [color]=\"isDarkMode ? 'light' : 'dark'\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"add-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.add' | translate }}\n </ion-button>\n </div>\n }\n }\n </div>\n }\n </div>\n </fieldset>\n\n\n", styles: [".dcf-fieldset-item{border:1px solid var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-small);padding:var(--dcf-padding-small) var(--dcf-padding-xsmall);padding-bottom:0;margin-bottom:var(--dcf-margin-small)}.dcf-loading-container{height:50%;display:flex;justify-content:center;align-items:center}.dcf-loading-container ion-spinner{width:30px;height:30px}ion-accordion{background:transparent!important;--background: transparent !important}ion-accordion ion-item[slot=header] .dcf-delete{width:30px}ion-accordion ion-item[slot=header] .dcf-delete ion-button{transform:translateY(-2px)}ion-accordion ion-item[slot=header] .dcf-delete ion-icon{font-size:1.15rem}ion-accordion.dcf-disabled [slot=content]{padding-bottom:0rem!important}ion-accordion.dcf-empty,ion-accordion.dcf-disabled{opacity:1!important}ion-accordion.dcf-empty ::ng-deep .ion-accordion-toggle-icon,ion-accordion.dcf-disabled ::ng-deep .ion-accordion-toggle-icon{display:none!important}ion-accordion.dcf-empty .dcf-delete,ion-accordion.dcf-disabled .dcf-delete{display:none!important}ion-accordion.dcf-empty ion-item[slot=header],ion-accordion.dcf-disabled ion-item[slot=header]{pointer-events:none;cursor:default!important}.dcf-not-collapsable .dcf-max-message-container{margin:.75rem;margin-top:0rem!important}.dcf-not-collapsable .dcf-max-message-container+.dcf-buttons-container{margin-top:var(--dcf-margin-small)!important}.dcf-fieldset-component{border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-3)}.dcf-fieldset-component.dcf-blank{border-color:transparent;padding:0rem!important;margin:0!important}.dcf-fieldset-component *{overflow-x:hidden!important}.dcf-fieldset-component ion-accordion ion-item{--background-hover: transparent !important}.dcf-fieldset-component.read,.dcf-fieldset-component.delete{margin:var(--dcf-margin-small) 0rem!important}.dcf-fieldset-component.read [slot=header],.dcf-fieldset-component.delete [slot=header]{margin-bottom:0rem!important}.dcf-fieldset-component [slot=header]{--border-color: transparent;--border-radius: 6px;--inner-border-width: 0;--padding-start: .65rem;--color: var(--ion-color-text) !important;margin:unset}.dcf-fieldset-component legend,.dcf-fieldset-component .dcf-title{font-weight:500;font-size:1rem;line-height:1.5rem;font-weight:600;margin:0;color:var(--ion-color-text)!important}.dcf-fieldset-component .dcf-title{padding:.8rem!important}.dcf-fieldset-component [slot=content]{padding:var(--dcf-padding-small) .25rem!important;background:transparent!important;--background: transparent !important}.dcf-fieldset-component [slot=content]>div{padding-top:.25rem!important}.dcf-fieldset-component:not(.dcf-blank) ion-accordion [slot=header]{margin-top:.125rem}.dcf-fieldset-component .dcf-max-message-container{margin:var(--dcf-padding-small) .75rem}.dcf-not-unique-container{display:flex;justify-content:center;align-items:center;margin-bottom:var(--dcf-spacement);flex:1 1 auto}.dcf-not-unique-container>div{display:flex;justify-content:center;align-items:center}.dcf-not-unique-container ion-icon{transform:translatey(2px);margin-right:5px}.dcf-fields-list{padding:.25rem var(--dcf-margin-small);padding-bottom:var(--dcf-padding)!important}.dcf-fields-list ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--border-color: var(--dcf-color-gray-2) !important}.dcf-fields-list ion-item ion-icon.dcf-reorder-disabled{width:var(--dcf-spacement);transform:translatey(2px);color:var(--dcf-color-gray-4)}.dcf-fields-list ion-item.updating{--background: rgba(var(--dcf-color-primary-rgb), .1) !important}.dcf-fields-list ion-item.not-unique{--background: rgba(var(--dcf-color-danger-rgb), .05) !important}.dcf-fields-list ion-item .dcf-subtitle{font-size:.925rem;color:var(--ion-color-gray-4)}.dcf-buttons-container{margin-bottom:0!important;margin-top:-.5rem;padding:0rem .125rem}.dcf-buttons-container:not(.dcf-blank){padding-bottom:var(--dcf-padding-small)!important}.dcf-buttons-container.dcf-not-collapsable.dcf-empty{position:relative;top:-1rem!important}@media (max-width: 480px){.dcf-buttons-container{flex-direction:column-reverse;gap:.5rem;align-items:stretch}.dcf-buttons-container ion-button{width:100%;justify-content:center;height:40px}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: IonAccordionGroup, selector: "ion-accordion-group", inputs: ["animated", "disabled", "expand", "mode", "multiple", "readonly", "value"] }, { kind: "component", type: IonAccordion, selector: "ion-accordion", inputs: ["disabled", "mode", "readonly", "toggleIcon", "toggleIconSlot", "value"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonReorder, selector: "ion-reorder" }, { kind: "component", type: IonReorderGroup, selector: "ion-reorder-group", inputs: ["disabled"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: LayoutComponent, selector: "ngx-decaf-layout", inputs: ["gap", "grid", "flexMode", "rowCard", "maxColsLength"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
7647
7819
  };
7648
7820
  FieldsetComponent = __decorate([
7649
7821
  Dynamic(),
@@ -7665,7 +7837,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
7665
7837
  IonButton,
7666
7838
  IonIcon,
7667
7839
  LayoutComponent,
7668
- ], template: "\n\n<fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.open]=\"isOpen\"\n [class.dcf-not-collapsable]=\"!collapsable\"\n #component>\n <div class=\"dcf-width-1-1\">\n @if (!collapsable || required) {\n <legend class=\"dcf-title\">{{ (title ? title : name) | translate }}</legend>\n }\n <ion-accordion-group class=\"dcf-width-1-1\" [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" [value]=\"(operation === 'read' || !collapsable) ? 'open' : ''\" #accordionComponent>\n <ion-accordion\n value=\"open\"\n [class.dcf-disabled]=\"!activePage\"\n [class.dcf-empty]=\"!items?.length\"\n >\n @if (collapsable && !required) {\n <ion-item slot=\"header\" [button]=\"collapsable\" (click)=\"handleAccordionToggle($event)\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-width-1-1\">\n <div class=\"dcf-width-expand\">\n <legend>{{ (title ? title : name) | translate }}</legend>\n </div>\n @if (!isRequired && ['create', 'update'].includes(operation) && collapsable && multiple) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleClear($event)\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n </div>\n </ion-item>\n }\n\n <div slot=\"content\" [attr.aria-hidden]=\"!isOpen\">\n @if (activePage) {\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested'\"\n [flexMode]=\"props.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [children]=\"activePage || []\"\n [parentForm]=\"formGroup || parentForm\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [borders]=\"activePage?.borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [hidden]=\"items.length === max && !updatingItem\"\n />\n </div>\n }\n </div>\n </ion-accordion>\n </ion-accordion-group>\n\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group [formGroup]=\"formGroup.parent\" [disabled]=\"updatingItem\" (ionItemReorder)=\"handleReorderItems($any($event))\" #accordionComponent>\n @for(item of items; track item.index) {\n <ion-item [class.not-unique]=\"item.title === isUniqueError\" [class.updating]=\"updatingItem?.[pk] === item.title\" lines=\"full\" [button]=\"false\">\n @if(ordenable) {\n @if (items?.length > 1 && !updatingItem) {\n <ion-reorder slot=\"start\">\n <ion-icon aria-hidden=\"true\" name=\"swap-vertical-outline\"></ion-icon>\n </ion-reorder>\n } @else {\n <div slot=\"start\">\n <ion-icon aria-hidden=\"true\" class=\"dcf-reorder-disabled\" size=\"small\" name=\"swap-vertical-outline\" disabled></ion-icon>\n </div>\n }\n }\n\n <ion-label [color]=\"(item.title === isUniqueError && !updatingItem?.[pk] === item.title) ? 'danger' : ''\">{{ item.index }}. {{ item.title }}\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{item.description}}</ion-text>\n }\n </ion-label>\n\n @if(editable) {\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleUpdateItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"create-outline\" color=\"dark\" ></ion-icon>\n </ion-button>\n }\n }\n\n\n @if (!updatingItem) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleRemoveItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"close-outline\" color=\"dark\"></ion-icon>\n </ion-button>\n }\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (isUniqueError) {\n <div class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\">\n <div class=\" dcf-grid dcf-grid-collapse dcf-width-1-1 \">\n <div class=\"dcf-auto\" [attr.style]=\"'max-width: 50px'\">\n <ion-icon aria-hidden=\"true\" name=\"alert-circle-outline\"></ion-icon>\n </div>\n <div class=\"dcf-width-expand\">\n <ion-text color=\"danger\" class=\"dcf-text-small\">{{ locale + '.not_unique' | translate : { value: isUniqueError } }}</ion-text>\n </div>\n </div>\n </div>\n }\n @if(max) {\n <div class=\"dcf-width-1-1 dcf-max-message-container\">\n <ion-text class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{ locale + (items.length !== max ? '.max_items' : '.max_items_reached') | translate : { '0': max } }}\n </ion-text>\n </div>\n }\n\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\" [class.dcf-not-collapsable]=\"!collapsable\" [class.dcf-empty]=\"!activePage\" [class.dcf-blank]=\"!borders\">\n @if (updatingItem) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ locale + '.cancel' | translate }}\n </ion-button>\n </div>\n <div>\n <ion-button size=\"small\" fill=\"clear\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update' | translate }}\n </ion-button>\n </div>\n } @else {\n\n @if (items.length < max || !max) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" [color]=\"isDarkMode ? 'light' : 'dark'\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"add-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.add' | translate }}\n </ion-button>\n </div>\n }\n }\n </div>\n }\n </div>\n</fieldset>\n\n", styles: ["ion-accordion ion-item[slot=header] .dcf-delete{width:30px}ion-accordion ion-item[slot=header] .dcf-delete ion-button{transform:translateY(-2px)}ion-accordion ion-item[slot=header] .dcf-delete ion-icon{font-size:1.15rem}ion-accordion.dcf-disabled [slot=content]{padding-bottom:0rem!important}ion-accordion.dcf-empty,ion-accordion.dcf-disabled{opacity:1!important}ion-accordion.dcf-empty ::ng-deep .ion-accordion-toggle-icon,ion-accordion.dcf-disabled ::ng-deep .ion-accordion-toggle-icon{display:none!important}ion-accordion.dcf-empty .dcf-delete,ion-accordion.dcf-disabled .dcf-delete{display:none!important}ion-accordion.dcf-empty ion-item[slot=header],ion-accordion.dcf-disabled ion-item[slot=header]{pointer-events:none;cursor:default!important}.dcf-not-collapsable .dcf-max-message-container{margin:.75rem;margin-top:0rem!important}.dcf-not-collapsable .dcf-max-message-container+.dcf-buttons-container{margin-top:var(--dcf-margin-small)!important}.dcf-fieldset-component{border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-3)}.dcf-fieldset-component.dcf-blank{border-color:transparent;padding:0rem!important;margin:0!important}.dcf-fieldset-component *{overflow-x:hidden!important}.dcf-fieldset-component ion-accordion:not(.dcf-empty){background:var(--dcf-card-background)!important}.dcf-fieldset-component ion-accordion ion-item{--background-hover: transparent !important}.dcf-fieldset-component.read,.dcf-fieldset-component.delete{margin:var(--dcf-margin-small) 0rem!important}.dcf-fieldset-component.read [slot=header],.dcf-fieldset-component.delete [slot=header]{margin-bottom:0rem!important}.dcf-fieldset-component [slot=header]{--border-color: transparent;--border-radius: 6px;--inner-border-width: 0;--padding-start: .65rem;--color: var(--ion-color-text) !important;margin:unset}.dcf-fieldset-component legend,.dcf-fieldset-component .dcf-title{font-weight:500;font-size:1rem;line-height:1.5rem;font-weight:600;margin:0;color:var(--ion-color-text)!important}.dcf-fieldset-component .dcf-title{padding:.8rem!important}.dcf-fieldset-component [slot=content]{padding:var(--dcf-padding-small) .25rem!important}.dcf-fieldset-component [slot=content]>div{padding-top:.25rem!important}.dcf-fieldset-component:not(.dcf-blank) ion-accordion [slot=header]{margin-top:.125rem}.dcf-fieldset-component .dcf-max-message-container{margin:var(--dcf-padding-small) .75rem}.dcf-not-unique-container{display:flex;justify-content:center;align-items:center;margin-bottom:var(--dcf-spacement);flex:1 1 auto}.dcf-not-unique-container>div{display:flex;justify-content:center;align-items:center}.dcf-not-unique-container ion-icon{transform:translatey(2px);margin-right:5px}.dcf-fields-list{padding:.25rem var(--dcf-margin-small);margin-bottom:var(--dcf-margin-small)!important}.dcf-fields-list ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--border-color: var(--dcf-color-gray-2) !important}.dcf-fields-list ion-item ion-icon.dcf-reorder-disabled{width:var(--dcf-spacement);transform:translatey(2px);color:var(--dcf-color-gray-4)}.dcf-fields-list ion-item.updating{--background: rgba(var(--dcf-color-primary-rgb), .1) !important}.dcf-fields-list ion-item.not-unique{--background: rgba(var(--dcf-color-danger-rgb), .05) !important}.dcf-fields-list ion-item .dcf-subtitle{font-size:.925rem;color:var(--ion-color-gray-4)}.dcf-buttons-container{margin-bottom:0!important;margin-top:-.5rem;padding:0rem .125rem}.dcf-buttons-container:not(.dcf-blank){padding-bottom:var(--dcf-padding-small)!important}.dcf-buttons-container.dcf-not-collapsable.dcf-empty{position:relative;top:-1rem!important}@media (max-width: 480px){.dcf-buttons-container{flex-direction:column-reverse;gap:.5rem;align-items:stretch}.dcf-buttons-container ion-button{width:100%;justify-content:center;height:40px}}\n"] }]
7840
+ IonSpinner
7841
+ ], template: "\n\n <fieldset\n (fieldsetAddGroupEvent)=\"handleCreateItem($event)\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.open]=\"isOpen\"\n [class.dcf-not-collapsable]=\"!collapsable\"\n #component>\n <div class=\"dcf-width-1-1\">\n @if (!collapsable || required) {\n <legend class=\"dcf-title\">{{ (title ? title : name) | translate }}</legend>\n }\n <ion-accordion-group class=\"dcf-width-1-1\" [class.open]=\"isOpen\" [class.hasValidationErrors]=\"hasValidationErrors\" [value]=\"(operation === 'read' || !collapsable) ? 'open' : ''\" #accordionComponent>\n <ion-accordion\n value=\"open\"\n [class.dcf-disabled]=\"!activePage\"\n [class.dcf-empty]=\"!items?.length\"\n >\n @if (collapsable && !required) {\n <ion-item slot=\"header\" [button]=\"collapsable\" (click)=\"handleAccordionToggle($event)\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-width-1-1\">\n <div class=\"dcf-width-expand\">\n <legend>{{ (title ? title : name) | translate }}</legend>\n </div>\n @if (!isRequired && ['create'].includes(operation) && collapsable && multiple) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleClear($event)\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" color=\"dark\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n </div>\n </ion-item>\n }\n\n <div slot=\"content\" [attr.aria-hidden]=\"!isOpen\">\n @if (['create', 'update'].includes(operation) || !multiple) {\n @if(activePage) {\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested'\"\n [flexMode]=\"props.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [children]=\"activePage || []\"\n [parentForm]=\"formGroup || parentForm\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [borders]=\"activePage?.borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [hidden]=\"items.length === max && !updatingItem\"\n />\n </div>\n }\n } @else {\n @if(refreshing) {\n <div class=\"dcf-loading-container\">\n <ion-spinner name=\"crescent\" color=\"primary\"></ion-spinner>\n </div>\n } @else {\n @if(!items.length) {\n <div class=\"dcf-padding-xsmall\">\n <ion-text>{{ locale + '.empty' | translate }}</ion-text>\n </div>\n } @else {\n @for(item of items; track trackItemFn($index, item)) {\n <div class=\"dcf-fieldset-item\">\n <div>\n <ngx-decaf-layout\n [className]=\"'dcf-fieldset-grid dcf-grid-nested ' + operation\"\n [flexMode]=\"item?.props?.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'collapse'\"\n [children]=\"item || []\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [borders]=\"item?.props?.borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n />\n </div>\n </div>\n }\n }\n }\n }\n </div>\n </ion-accordion>\n </ion-accordion-group>\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group [formGroup]=\"formGroup.parent\" [disabled]=\"updatingItem\" (ionItemReorder)=\"handleReorderItems($any($event))\" #accordionComponent>\n @for(item of items; track item.index) {\n <ion-item [class.not-unique]=\"item.title === isUniqueError\" [class.updating]=\"updatingItem?.[pk] === item.title\" lines=\"full\" [button]=\"false\">\n @if(ordenable) {\n @if (items?.length > 1 && !updatingItem) {\n <ion-reorder slot=\"start\">\n <ion-icon aria-hidden=\"true\" name=\"swap-vertical-outline\"></ion-icon>\n </ion-reorder>\n } @else {\n <div slot=\"start\">\n <ion-icon aria-hidden=\"true\" class=\"dcf-reorder-disabled\" size=\"small\" name=\"swap-vertical-outline\" disabled></ion-icon>\n </div>\n }\n }\n\n <ion-label [color]=\"(item.title === isUniqueError && !updatingItem?.[pk] === item.title) ? 'danger' : ''\">{{ item.index }}. {{ item.title }}\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{item.description}}</ion-text>\n }\n </ion-label>\n\n @if(editable) {\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button fill=\"clear\" size=\"small\" (click)=\"handleUpdateItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"create-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\"></ion-icon>\n </ion-button>\n }\n }\n\n\n @if (!updatingItem) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleRemoveItem($index)\">\n <ion-icon aria-hidden=\"true\" name=\"close-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\"></ion-icon>\n </ion-button>\n }\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (isUniqueError) {\n <div class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\">\n <div class=\" dcf-grid dcf-grid-collapse dcf-width-1-1 \">\n <div class=\"dcf-auto\" [attr.style]=\"'max-width: 50px'\">\n <ion-icon aria-hidden=\"true\" name=\"alert-circle-outline\"></ion-icon>\n </div>\n <div class=\"dcf-width-expand\">\n <ion-text color=\"danger\" class=\"dcf-text-small\">{{ locale + '.not_unique' | translate : { value: isUniqueError } }}</ion-text>\n </div>\n </div>\n </div>\n }\n\n @if(max) {\n <div class=\"dcf-width-1-1 dcf-max-message-container\">\n <ion-text class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{ locale + (items.length !== max ? '.max_items' : '.max_items_reached') | translate : { '0': max } }}\n </ion-text>\n </div>\n }\n\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\" [class.dcf-not-collapsable]=\"!collapsable\" [class.dcf-empty]=\"!activePage\" [class.dcf-blank]=\"!borders\">\n @if (updatingItem) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" color=\"danger\" (click)=\"handleCancelUpdateItem()\">\n {{ locale + '.cancel' | translate }}\n </ion-button>\n </div>\n <div>\n <ion-button size=\"small\" fill=\"clear\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update' | translate }}\n </ion-button>\n </div>\n } @else {\n @if (items.length < max || !max) {\n <div>\n <ion-button size=\"small\" fill=\"clear\" class=\"dcf-button-add\" [color]=\"isDarkMode ? 'light' : 'dark'\" (click)=\"handleCreateItem()\">\n <ion-icon aria-hidden=\"true\" name=\"add-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.add' | translate }}\n </ion-button>\n </div>\n }\n }\n </div>\n }\n </div>\n </fieldset>\n\n\n", styles: [".dcf-fieldset-item{border:1px solid var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-small);padding:var(--dcf-padding-small) var(--dcf-padding-xsmall);padding-bottom:0;margin-bottom:var(--dcf-margin-small)}.dcf-loading-container{height:50%;display:flex;justify-content:center;align-items:center}.dcf-loading-container ion-spinner{width:30px;height:30px}ion-accordion{background:transparent!important;--background: transparent !important}ion-accordion ion-item[slot=header] .dcf-delete{width:30px}ion-accordion ion-item[slot=header] .dcf-delete ion-button{transform:translateY(-2px)}ion-accordion ion-item[slot=header] .dcf-delete ion-icon{font-size:1.15rem}ion-accordion.dcf-disabled [slot=content]{padding-bottom:0rem!important}ion-accordion.dcf-empty,ion-accordion.dcf-disabled{opacity:1!important}ion-accordion.dcf-empty ::ng-deep .ion-accordion-toggle-icon,ion-accordion.dcf-disabled ::ng-deep .ion-accordion-toggle-icon{display:none!important}ion-accordion.dcf-empty .dcf-delete,ion-accordion.dcf-disabled .dcf-delete{display:none!important}ion-accordion.dcf-empty ion-item[slot=header],ion-accordion.dcf-disabled ion-item[slot=header]{pointer-events:none;cursor:default!important}.dcf-not-collapsable .dcf-max-message-container{margin:.75rem;margin-top:0rem!important}.dcf-not-collapsable .dcf-max-message-container+.dcf-buttons-container{margin-top:var(--dcf-margin-small)!important}.dcf-fieldset-component{border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-3)}.dcf-fieldset-component.dcf-blank{border-color:transparent;padding:0rem!important;margin:0!important}.dcf-fieldset-component *{overflow-x:hidden!important}.dcf-fieldset-component ion-accordion ion-item{--background-hover: transparent !important}.dcf-fieldset-component.read,.dcf-fieldset-component.delete{margin:var(--dcf-margin-small) 0rem!important}.dcf-fieldset-component.read [slot=header],.dcf-fieldset-component.delete [slot=header]{margin-bottom:0rem!important}.dcf-fieldset-component [slot=header]{--border-color: transparent;--border-radius: 6px;--inner-border-width: 0;--padding-start: .65rem;--color: var(--ion-color-text) !important;margin:unset}.dcf-fieldset-component legend,.dcf-fieldset-component .dcf-title{font-weight:500;font-size:1rem;line-height:1.5rem;font-weight:600;margin:0;color:var(--ion-color-text)!important}.dcf-fieldset-component .dcf-title{padding:.8rem!important}.dcf-fieldset-component [slot=content]{padding:var(--dcf-padding-small) .25rem!important;background:transparent!important;--background: transparent !important}.dcf-fieldset-component [slot=content]>div{padding-top:.25rem!important}.dcf-fieldset-component:not(.dcf-blank) ion-accordion [slot=header]{margin-top:.125rem}.dcf-fieldset-component .dcf-max-message-container{margin:var(--dcf-padding-small) .75rem}.dcf-not-unique-container{display:flex;justify-content:center;align-items:center;margin-bottom:var(--dcf-spacement);flex:1 1 auto}.dcf-not-unique-container>div{display:flex;justify-content:center;align-items:center}.dcf-not-unique-container ion-icon{transform:translatey(2px);margin-right:5px}.dcf-fields-list{padding:.25rem var(--dcf-margin-small);padding-bottom:var(--dcf-padding)!important}.dcf-fields-list ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--border-color: var(--dcf-color-gray-2) !important}.dcf-fields-list ion-item ion-icon.dcf-reorder-disabled{width:var(--dcf-spacement);transform:translatey(2px);color:var(--dcf-color-gray-4)}.dcf-fields-list ion-item.updating{--background: rgba(var(--dcf-color-primary-rgb), .1) !important}.dcf-fields-list ion-item.not-unique{--background: rgba(var(--dcf-color-danger-rgb), .05) !important}.dcf-fields-list ion-item .dcf-subtitle{font-size:.925rem;color:var(--ion-color-gray-4)}.dcf-buttons-container{margin-bottom:0!important;margin-top:-.5rem;padding:0rem .125rem}.dcf-buttons-container:not(.dcf-blank){padding-bottom:var(--dcf-padding-small)!important}.dcf-buttons-container.dcf-not-collapsable.dcf-empty{position:relative;top:-1rem!important}@media (max-width: 480px){.dcf-buttons-container{flex-direction:column-reverse;gap:.5rem;align-items:stretch}.dcf-buttons-container ion-button{width:100%;justify-content:center;height:40px}}\n"] }]
7669
7842
  }], ctorParameters: () => [], propDecorators: { accordionComponent: [{
7670
7843
  type: ViewChild,
7671
7844
  args: ['accordionComponent', { static: false }]
@@ -8238,7 +8411,7 @@ let FilterComponent = class FilterComponent extends NgxComponentDirective {
8238
8411
  * @memberOf FilterComponent
8239
8412
  */
8240
8413
  constructor() {
8241
- super("FilterComponent");
8414
+ super('FilterComponent');
8242
8415
  /**
8243
8416
  * @description Available field indexes for filtering operations.
8244
8417
  * @summary Defines the list of field names that users can filter by. These represent
@@ -8261,7 +8434,14 @@ let FilterComponent = class FilterComponent extends NgxComponentDirective {
8261
8434
  * @default []
8262
8435
  * @memberOf FilterComponent
8263
8436
  */
8264
- this.conditions = ['Equal', 'Contains', 'Not Contains', 'Greater Than', 'Less Than', 'Not Equal'];
8437
+ this.conditions = [
8438
+ 'Equal',
8439
+ 'Contains',
8440
+ 'Not Contains',
8441
+ 'Greater Than',
8442
+ 'Less Than',
8443
+ 'Not Equal',
8444
+ ];
8265
8445
  /**
8266
8446
  * @description Available sorting options for the filtered data.
8267
8447
  * @summary Defines the list of field names that can be used for sorting the filtered results.
@@ -8394,7 +8574,15 @@ let FilterComponent = class FilterComponent extends NgxComponentDirective {
8394
8574
  * @memberOf FilterComponent
8395
8575
  */
8396
8576
  this.searchEvent = new EventEmitter();
8397
- addIcons({ chevronDownOutline, trashOutline, closeOutline, searchOutline, arrowDownOutline, arrowUpOutline, chevronUpOutline });
8577
+ addIcons({
8578
+ chevronDownOutline,
8579
+ trashOutline,
8580
+ closeOutline,
8581
+ searchOutline,
8582
+ arrowDownOutline,
8583
+ arrowUpOutline,
8584
+ chevronUpOutline,
8585
+ });
8398
8586
  }
8399
8587
  /**
8400
8588
  * @description Initializes the component after Angular first displays the data-bound properties.
@@ -8443,11 +8631,13 @@ let FilterComponent = class FilterComponent extends NgxComponentDirective {
8443
8631
  */
8444
8632
  getIndexes() {
8445
8633
  if (this.model)
8446
- this.indexes = Object.keys(Repository.indexes(this.model) || {});
8634
+ this.indexes = Object.keys(Model.indexes(this.model) || {});
8447
8635
  if (!this.disableSort) {
8448
8636
  this.sortBy = [...this.sortBy, ...this.indexes];
8449
- if (this.repository)
8450
- this.sortValue = this.repository.pk || this.sortValue;
8637
+ if (this.repository) {
8638
+ const pk = Model.pk(this.repository.class);
8639
+ this.sortValue = pk || this.sortValue;
8640
+ }
8451
8641
  }
8452
8642
  }
8453
8643
  /**
@@ -8579,13 +8769,13 @@ let FilterComponent = class FilterComponent extends NgxComponentDirective {
8579
8769
  *
8580
8770
  * @memberOf FilterComponent
8581
8771
  */
8582
- addFilter(value, event) {
8772
+ async addFilter(value, event) {
8583
8773
  value = value.trim();
8584
8774
  if (event instanceof KeyboardEvent && !value) {
8585
8775
  this.submit();
8586
8776
  }
8587
8777
  else {
8588
- if ((value && (!(event instanceof KeyboardEvent)) || this.step === 3)) {
8778
+ if ((value && !(event instanceof KeyboardEvent)) || this.step === 3) {
8589
8779
  const filter = this.lastFilter;
8590
8780
  switch (this.step) {
8591
8781
  case 1:
@@ -8613,7 +8803,7 @@ let FilterComponent = class FilterComponent extends NgxComponentDirective {
8613
8803
  this.filterValue[this.filterValue.length - 1] = filter;
8614
8804
  this.lastFilter = {};
8615
8805
  if (!this.multiple)
8616
- return this.submit();
8806
+ return await this.submit();
8617
8807
  }
8618
8808
  this.step++;
8619
8809
  this.value = '';
@@ -8647,7 +8837,8 @@ let FilterComponent = class FilterComponent extends NgxComponentDirective {
8647
8837
  * @memberOf FilterComponent
8648
8838
  */
8649
8839
  allowClear(option) {
8650
- return this.indexes.indexOf(option) === -1 && this.conditions.indexOf(option) === -1;
8840
+ return (this.indexes.indexOf(option) === -1 &&
8841
+ this.conditions.indexOf(option) === -1);
8651
8842
  }
8652
8843
  /**
8653
8844
  * @description Removes a complete filter from the collection based on filter value.
@@ -8676,11 +8867,11 @@ let FilterComponent = class FilterComponent extends NgxComponentDirective {
8676
8867
  function cleanString(filter) {
8677
8868
  return filter
8678
8869
  .toLowerCase() // convert all characters to lowercase
8679
- .normalize("NFD") // separate accent marks from characters
8680
- .replace(/[\u0300-\u036f]/g, "") // remove accent marks
8681
- .replace(/\s+/g, ""); // remove all whitespace
8870
+ .normalize('NFD') // separate accent marks from characters
8871
+ .replace(/[\u0300-\u036f]/g, '') // remove accent marks
8872
+ .replace(/\s+/g, ''); // remove all whitespace
8682
8873
  }
8683
- this.value = "";
8874
+ this.value = '';
8684
8875
  this.filterValue = this.filterValue.filter((item) => item?.['value'] && cleanString(item?.['value']) !== cleanString(filter));
8685
8876
  if (this.filterValue.length === 0) {
8686
8877
  this.step = 1;
@@ -8725,16 +8916,16 @@ let FilterComponent = class FilterComponent extends NgxComponentDirective {
8725
8916
  * @summary Emits the current filter array to parent components when filters are ready
8726
8917
  * to be applied. Only emits if there are active filters. Clears options after submission.
8727
8918
  *
8728
- * @returns {void}
8919
+ * @returns {Promise<void>}
8729
8920
  * @memberOf FilterComponent
8730
8921
  */
8731
- submit() {
8922
+ async submit() {
8732
8923
  this.filterEvent.emit({
8733
8924
  query: this.filterValue.length > 0 ? this.filterValue : undefined,
8734
8925
  sort: {
8735
8926
  value: this.sortValue,
8736
- direction: this.sortDirection
8737
- }
8927
+ direction: this.sortDirection,
8928
+ },
8738
8929
  });
8739
8930
  if (this.filterValue.length === 0)
8740
8931
  this.options = [];
@@ -8749,7 +8940,9 @@ let FilterComponent = class FilterComponent extends NgxComponentDirective {
8749
8940
  * @memberOf FilterComponent
8750
8941
  */
8751
8942
  handleSortDirectionChange() {
8752
- const direction = this.sortDirection === OrderDirection.ASC ? OrderDirection.DSC : OrderDirection.ASC;
8943
+ const direction = this.sortDirection === OrderDirection.ASC
8944
+ ? OrderDirection.DSC
8945
+ : OrderDirection.ASC;
8753
8946
  if (direction !== this.sortDirection) {
8754
8947
  this.sortDirection = direction;
8755
8948
  this.submit();
@@ -8811,7 +9004,9 @@ let FilterComponent = class FilterComponent extends NgxComponentDirective {
8811
9004
  }
8812
9005
  const options = optionsElement.querySelectorAll('.dcf-item');
8813
9006
  for (const option of options) {
8814
- const isActive = option.textContent?.toLowerCase().includes(value.toLowerCase());
9007
+ const isActive = option.textContent
9008
+ ?.toLowerCase()
9009
+ .includes(value.toLowerCase());
8815
9010
  if (isActive) {
8816
9011
  option.classList.add('dcf-filtering-item');
8817
9012
  break;
@@ -8850,7 +9045,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
8850
9045
  IonSelect,
8851
9046
  IonSelectOption,
8852
9047
  IonIcon,
8853
- SearchbarComponent
9048
+ SearchbarComponent,
8854
9049
  ], standalone: true, host: { '[attr.id]': 'uid' }, template: "\n@if (!indexes.length) {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n}\n\n<div [id]=\"uid\" class=\"dcf-grid dcf-grid-small dcf-grid-match dcf-filter-component\" [class.dcf-hidden]=\"!indexes.length\" #component>\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-filter\">\n <div class=\"dcf-input\">\n @for(filter of filterValue; track trackItemFn($index, filter?.['index'])) {\n @if (filter?.['index']) {\n <ion-chip [outline]=\"true\">{{ filter?.['index'] }}</ion-chip>\n }\n @if (filter?.['condition']) {\n <ion-chip [outline]=\"true\">{{ filter?.['condition'] }}</ion-chip>\n }\n @if (filter?.['value']) {\n <ion-chip [outline]=\"true\" class=\"dcf-filter-value\">\n {{ filter?.['value'] }}\n <ion-icon tabindex=\"0\" name=\"close-outline\" (click)=\"removeFilter(filter?.['value'])\" size=\"small\"></ion-icon>\n </ion-chip>\n }\n }\n <div class=\"dcf-width-1-1\">\n <!-- [readonly]=\"step !== 3\" -->\n <input\n fill=\"none\"\n [(ngModel)]=\"value\"\n (keydown.enter)=\"addFilter(value, $event)\"\n (keydown.backspace)=\"clear(value)\"\n (input)=\"handleInput($event)\"\n (click)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n type=\"text\"\n id=\"dcf-filter-field\"\n placeholder=\"{{ locale + (step === 3 ? '.type' : '.select') | translate }}\"\n\n />\n @if (windowWidth >= 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n @if (filterValue.length > 0) {\n <div class=\"dcf-icon-clear\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"clear()\">\n <ion-icon aria-hidden=\"true\" name=\"trash-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n }\n <div class=\"dcf-icon-search\">\n <ion-button fill=\"clear\" size=\"small\" (click)=\"submit()\">\n <ion-icon aria-hidden=\"true\" name=\"search-outline\" [color]=\"!isDarkMode ? 'dark' : 'light'\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </div>\n </div>\n @if (windowWidth < 768) {\n <div [class]=\"'dcf-dropdown ' + (options.length > 0 ? ' dcf-active' : '')\" #optionsFilterElement>\n <div>\n @if (filteredOptions.length > 0) {\n @for(key of filteredOptions; track key) {\n <div\n class=\"dcf-item\"\n tabindex=\"0\"\n (keydown.enter)=\"selectOption(key)\"\n (click)=\"selectOption(key)\">\n {{ key }}\n </div>\n }\n } @else {\n <div class=\"dcf-empty\"\n (click)=\"filteredOptions = options; value = ''\"\n tabindex=\"0\"\n (keydown.enter)=\"filteredOptions = options; value = ''\"\n >\n {{ locale + '.no_suggestions' | translate }}\n </div>\n }\n </div>\n </div>\n }\n </div>\n @if (!disableSort) {\n <div class=\"dcf-width-1-5@m dcf-width-1-1 dcf-sort-container\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-flex dcf-flex-middle dcf-grid-match\">\n <div class=\"dcf-width-expand\">\n <ion-select\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n class=\"dcf-sort-select\"\n (ionChange)=\"handleSortChange($event)\"\n interface=\"popover\"\n [value]=\"sortValue\"\n label-placement=\"floating\"\n fill=\"outline\"\n [label]=\"locale + '.sort' | translate\"\n >\n @for(sort of sortBy; track sort) {\n\n <ion-select-option [value]=\"sort\">{{ sort | translate }}</ion-select-option>\n }\n </ion-select>\n </div>\n <div class=\"dcf-width-auto\">\n <ion-button (click)=\"handleSortDirectionChange()\" fill=\"clear\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" [color]=\"!isDarkMode ? 'primary' : 'light'\" [name]=\"sortDirection === 'desc' ? 'arrow-down-outline' : 'arrow-up-outline'\"></ion-icon>\n </ion-button>\n </div>\n </div>\n </div>\n }\n</div>\n\n\n", styles: [":host{position:relative;z-index:1000!important}:host *{z-index:1000!important}.dcf-filter-component{padding:0 .5rem;margin-top:.75rem;margin-bottom:.75rem}.dcf-filter-component:not(.dcf-palette-dark) .dcf-filter{border:1px solid var(--dcf-color-gray-3);background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) .dcf-filter:focus-within{border-color:var(--dcf-color-primary);background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) ion-chip{border:1px solid var(--dcf-color-gray-3);color:var(--dcf-color-gray-7)}.dcf-filter-component:not(.dcf-palette-dark) ion-chip.dcf-filter-value{background:var(--dcf-color-gray-2);border-color:var(--dcf-color-gray-4)!important;color:var(--dcf-color-gray-8)!important}.dcf-filter-component:not(.dcf-palette-dark) .dcf-input input{color:var(--dcf-color-gray-7)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown{background-color:#fff}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-gray-2)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-8)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-3)}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{pointer-events:none;touch-action:none;cursor:text!important;border-color:transparent!important}.dcf-filter-component:not(.dcf-palette-dark) .dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-filter{border:1px solid var(--dcf-color-step-500)}.dcf-filter-component.dcf-palette-dark .dcf-filter ::-webkit-input-placeholder,.dcf-filter-component.dcf-palette-dark .dcf-filter ::placeholder{color:var(--dcf-color-gray-4)!important}.dcf-filter-component.dcf-palette-dark .dcf-filter:hover{border-color:var(--dcf-color-gray-2)}.dcf-filter-component.dcf-palette-dark .dcf-filter:focus-within{border-color:var(--dcf-color-gray-2)}.dcf-filter-component.dcf-palette-dark ion-chip{border-color:var(--dcf-color-step-300);background:rgba(var(--dcf-color-medium-rgb),.1)}.dcf-filter-component.dcf-palette-dark ion-chip.dcf-filter-value{background:rgba(var(--dcf-color-medium-rgb),.3)!important;border-color:var(--dcf-color-step-500)}.dcf-filter-component.dcf-palette-dark .dcf-input input{color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown{background-color:var(--dcf-item-background)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active{border:1px solid var(--dcf-color-step-600)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div{color:var(--dcf-color-gray-1)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div.dcf-filtering-item,.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:only-child{border-color:var(--dcf-color-gray-5)}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div.dcf-filtering-item.dcf-empty,.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:only-child.dcf-empty{cursor:text!important;pointer-events:none;touch-action:none;border-color:transparent!important}.dcf-filter-component.dcf-palette-dark .dcf-dropdown.dcf-active>div>div:hover{background-color:var(--dcf-color-gray-8)}ion-select{min-height:44px!important}.dcf-hidden{display:none!important}.dcf-filter{display:flex;width:100%;min-height:40px;box-shadow:0 1px 2px #0a0d120d;border-radius:var(--dcf-border-radius);box-sizing:border-box}.dcf-filter ion-chip{border-radius:6px;padding:0 8px!important;height:24px;min-height:24px;font-size:.75rem;font-style:normal;font-weight:500;flex-shrink:0;margin-right:2px;white-space:nowrap}.dcf-filter ion-chip.sc-ion-chip-md-h,.dcf-filter ion-chip.sc-ion-chip-ios-h{height:24px;min-height:24px}.dcf-filter ion-chip.sc-ion-chip-md-h .chip-native,.dcf-filter ion-chip.sc-ion-chip-ios-h .chip-native{padding:0 8px!important;height:24px;min-height:24px}.dcf-filter ion-chip ion-label{padding:0 4px;margin:0;font-size:.75rem;white-space:nowrap}.dcf-filter ion-chip ion-icon{margin:0 2px;font-size:.75rem}.dcf-filter .dcf-input{width:100%;display:flex;align-items:center;overflow-x:auto;overflow-y:hidden;white-space:nowrap;padding-left:.5rem}.dcf-filter .dcf-input input{min-height:40px;min-width:100px;width:100%;font-size:1rem;border:none;outline:none;background:transparent;border:0px!important;outline:none!important}.dcf-filter .dcf-input input:focus{border:0px!important;outline:none!important}.dcf-filter .dcf-icon-clear,.dcf-filter .dcf-icon-search{display:flex;justify-content:center;text-align:center;align-items:center;min-width:40px}.dcf-filter .dcf-icon-search ion-icon{font-size:1.25rem}.dcf-sort-container{min-width:200px!important;width:auto}@media (min-width: 990px){.dcf-sort-container{max-width:20%!important}}@media (max-width: 680px){.dcf-sort-container{min-width:100%!important;margin:.75rem 0rem}}.dcf-dropdown{position:absolute;max-height:200px;overflow-y:auto;border-radius:4px;z-index:1000!important;min-width:200px;max-width:300px;display:none}.dcf-dropdown.dcf-active{display:block;margin-top:-3px;box-shadow:0 12px 16px -4px #0a0d1214,0 4px 6px -2px #0a0d1208,0 2px 2px -1px #0a0d120a!important;border-radius:var(--dcf-border-radius);padding:.5rem .25rem}@media (max-width: 768px){.dcf-dropdown.dcf-active{margin-top:55px}}.dcf-dropdown.dcf-active>div>div{cursor:pointer;height:35px;padding:.5rem 1rem;border:1px solid transparent;font-size:1rem;display:flex;align-items:center;border-radius:6px}\n"] }]
8855
9050
  }], ctorParameters: () => [], propDecorators: { optionsFilterElement: [{
8856
9051
  type: ViewChild,
@@ -9269,7 +9464,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9269
9464
  * @memberOf ListComponent
9270
9465
  */
9271
9466
  constructor() {
9272
- super("ListComponent");
9467
+ super('ListComponent');
9273
9468
  /**
9274
9469
  * @description The display mode for the list component.
9275
9470
  * @summary Determines how the list data is loaded and displayed. Options include:
@@ -9345,7 +9540,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9345
9540
  * @default "full"
9346
9541
  * @memberOf ListComponent
9347
9542
  */
9348
- this.lines = "full";
9543
+ this.lines = 'full';
9349
9544
  /**
9350
9545
  * @description Controls whether the list has inset styling.
9351
9546
  * @summary When set to true, the list will have inset styling with rounded corners
@@ -9366,7 +9561,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9366
9561
  * @default "15%"
9367
9562
  * @memberOf ListComponent
9368
9563
  */
9369
- this.scrollThreshold = "15%";
9564
+ this.scrollThreshold = '15%';
9370
9565
  /**
9371
9566
  * @description The position where new items are added during infinite scrolling.
9372
9567
  * @summary Determines whether new items are added to the top or bottom of the list
@@ -9376,7 +9571,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9376
9571
  * @default "bottom"
9377
9572
  * @memberOf ListComponent
9378
9573
  */
9379
- this.scrollPosition = "bottom";
9574
+ this.scrollPosition = 'bottom';
9380
9575
  /**
9381
9576
  * @description Controls the visibility of the pull-to-refresh feature.
9382
9577
  * @summary When set to true, enables the pull-to-refresh functionality that allows
@@ -9405,7 +9600,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9405
9600
  * @default "circular"
9406
9601
  * @memberOf ListComponent
9407
9602
  */
9408
- this.loadingSpinner = "circular";
9603
+ this.loadingSpinner = 'circular';
9409
9604
  // /**
9410
9605
  // * @description Query parameters for data fetching.
9411
9606
  // * @summary Specifies additional query parameters to use when fetching data from
@@ -9474,17 +9669,6 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9474
9669
  * @memberOf ListComponent
9475
9670
  */
9476
9671
  this.page = 1;
9477
- /**
9478
- * @description Indicates whether a refresh operation is in progress.
9479
- * @summary When true, the component is currently fetching new data. This is used
9480
- * to control loading indicators and prevent duplicate refresh operations from
9481
- * being triggered simultaneously.
9482
- *
9483
- * @type {boolean}
9484
- * @default false
9485
- * @memberOf ListComponent
9486
- */
9487
- this.refreshing = false;
9488
9672
  /**
9489
9673
  * @description Array used for rendering skeleton loading placeholders.
9490
9674
  * @summary Contains placeholder items that are displayed during data loading.
@@ -9506,15 +9690,6 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9506
9690
  * @memberOf ListComponent
9507
9691
  */
9508
9692
  this.lastPage = 1;
9509
- /**
9510
- * @description Event emitter for refresh operations.
9511
- * @summary Emits an event when the list data is refreshed, either through pull-to-refresh
9512
- * or programmatic refresh. The event includes the refreshed data and component information.
9513
- *
9514
- * @type {EventEmitter<IBaseCustomEvent>}
9515
- * @memberOf ListComponent
9516
- */
9517
- this.refreshEvent = new EventEmitter();
9518
9693
  /**
9519
9694
  * @description Event emitter for item click interactions.
9520
9695
  * @summary Emits an event when a list item is clicked. The event includes the data
@@ -9575,9 +9750,15 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9575
9750
  * @memberOf ListComponent
9576
9751
  */
9577
9752
  async ngOnInit() {
9578
- this.observer = { refresh: async (...args) => this.observeRepository(...args) };
9579
- this.clickItemSubject.pipe(debounceTime(100)).subscribe(event => this.clickEventEmit(event));
9580
- this.observerSubjet.pipe(debounceTime(100)).subscribe(args => this.handleObserveEvent(args[0], args[1], args[2]));
9753
+ this.observer = {
9754
+ refresh: async (...args) => this.observeRepository(...args),
9755
+ };
9756
+ this.clickItemSubject
9757
+ .pipe(debounceTime(100))
9758
+ .subscribe((event) => this.clickEventEmit(event));
9759
+ this.observerSubjet
9760
+ .pipe(debounceTime(100))
9761
+ .subscribe((args) => this.handleObserveEvent(args[0], args[1], args[2]));
9581
9762
  this.limit = Number(this.limit);
9582
9763
  this.start = Number(this.start);
9583
9764
  this.enableFilter = stringToBoolean(this.enableFilter);
@@ -9685,7 +9866,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9685
9866
  async handleCreate(uid) {
9686
9867
  const result = await this._repository?.read(uid);
9687
9868
  const item = this.mapResults([result])[0];
9688
- this.items = this.data = [item, ...this.items || []];
9869
+ this.items = this.data = [item, ...(this.items || [])];
9689
9870
  }
9690
9871
  /**
9691
9872
  * @description Handles the update event from the repository.
@@ -9697,7 +9878,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9697
9878
  * @memberOf ListComponent
9698
9879
  */
9699
9880
  async handleUpdate(uid) {
9700
- const item = this.itemMapper(await this._repository?.read(uid) || {}, this.mapper);
9881
+ const item = this.itemMapper((await this._repository?.read(uid)) || {}, this.mapper);
9701
9882
  this.data = [];
9702
9883
  for (const key in this.items) {
9703
9884
  const child = this.items[key];
@@ -9724,7 +9905,8 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9724
9905
  handleDelete(uid, pk) {
9725
9906
  if (!pk)
9726
9907
  pk = this.pk;
9727
- this.items = this.data?.filter((item) => item['uid'] !== uid) || [];
9908
+ this.items =
9909
+ this.data?.filter((item) => item['uid'] !== uid) || [];
9728
9910
  }
9729
9911
  /**
9730
9912
  * @description Handles click events from list items.
@@ -9828,7 +10010,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9828
10010
  this.refreshEvent.emit({
9829
10011
  name: ComponentEventNames.REFRESH,
9830
10012
  data: data || [],
9831
- component: this.componentName
10013
+ component: this.componentName,
9832
10014
  });
9833
10015
  }
9834
10016
  /**
@@ -9904,10 +10086,10 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9904
10086
  // }
9905
10087
  this.refreshing = true;
9906
10088
  const start = this.page > 1 ? (this.page - 1) * this.limit : this.start;
9907
- const limit = (this.page * (this.limit > 12 ? 12 : this.limit));
9908
- this.data = !this.model ?
9909
- await this.getFromRequest(!!event, start, limit)
9910
- : await this.getFromModel(!!event);
10089
+ const limit = this.page * (this.limit > 12 ? 12 : this.limit);
10090
+ this.data = !this.model
10091
+ ? await this.getFromRequest(!!event, start, limit)
10092
+ : (await this.getFromModel(!!event));
9911
10093
  if (this.type === ListComponentsTypes.INFINITE) {
9912
10094
  if (this.page === this.pages) {
9913
10095
  if (event?.target)
@@ -9918,7 +10100,9 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9918
10100
  this.page += 1;
9919
10101
  this.refreshing = false;
9920
10102
  setTimeout(() => {
9921
- if (event?.target && event?.type !== ComponentEventNames.BACK_BUTTON_NAVIGATION)
10103
+ if (event?.target &&
10104
+ event?.type !==
10105
+ ComponentEventNames.BACK_BUTTON_NAVIGATION)
9922
10106
  event.target.complete();
9923
10107
  }, 200);
9924
10108
  }
@@ -9930,16 +10114,16 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9930
10114
  }
9931
10115
  }
9932
10116
  /**
9933
- * @description Handles pagination events from the pagination component.
9934
- * @summary Processes pagination events by updating the current page number and
9935
- * refreshing the list data to display the selected page. This method is called
9936
- * when a user interacts with the pagination controls to navigate between pages.
9937
- *
9938
- * @param {IPaginationCustomEvent} event - The pagination event containing page information
9939
- * @returns {void}
9940
- *
9941
- * @memberOf ListComponent
9942
- */
10117
+ * @description Handles pagination events from the pagination component.
10118
+ * @summary Processes pagination events by updating the current page number and
10119
+ * refreshing the list data to display the selected page. This method is called
10120
+ * when a user interacts with the pagination controls to navigate between pages.
10121
+ *
10122
+ * @param {IPaginationCustomEvent} event - The pagination event containing page information
10123
+ * @returns {void}
10124
+ *
10125
+ * @memberOf ListComponent
10126
+ */
9943
10127
  handlePaginate(event) {
9944
10128
  const { page } = event.data;
9945
10129
  this.page = page;
@@ -9977,8 +10161,11 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9977
10161
  * @memberOf ListComponent
9978
10162
  */
9979
10163
  parseSearchResults(results, search) {
9980
- const filtered = results.filter((item) => Object.values(item).some(v => {
9981
- if (v.toString().toLowerCase().includes(search?.toLowerCase()))
10164
+ const filtered = results.filter((item) => Object.values(item).some((v) => {
10165
+ if (v
10166
+ .toString()
10167
+ .toLowerCase()
10168
+ .includes(search?.toLowerCase()))
9982
10169
  return v;
9983
10170
  }));
9984
10171
  return filtered;
@@ -9997,25 +10184,31 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
9997
10184
  * @memberOf ListComponent
9998
10185
  */
9999
10186
  async getFromRequest(force = false, start, limit) {
10000
- let data = [...this.data || []];
10001
- if (!this.data?.length || force || this.searchValue?.length || !!this.searchValue) {
10187
+ let data = [...(this.data || [])];
10188
+ if (!this.data?.length ||
10189
+ force ||
10190
+ this.searchValue?.length ||
10191
+ !!this.searchValue) {
10002
10192
  // (self.data as ListItem[]) = [];
10003
- if (!this.searchValue?.length && !this.searchValue) {
10193
+ if (!this.searchValue?.length &&
10194
+ !this.searchValue) {
10004
10195
  if (!this.source && !this.data?.length) {
10005
10196
  this.log.info('No data and source passed to infinite list');
10006
10197
  return [];
10007
10198
  }
10008
10199
  if (this.source instanceof Function) {
10009
- data = await this.source();
10200
+ data = (await this.source());
10010
10201
  if (!Array.isArray(data))
10011
10202
  data = data?.['response']?.['data'] || data?.['results'] || [];
10012
10203
  }
10013
10204
  if (!data?.length && this.data?.length)
10014
10205
  data = this.data;
10015
- this.data = [...await this.parseResult(data)];
10206
+ this.data = [...(await this.parseResult(data))];
10016
10207
  if (this.data?.length)
10017
- this.items = this.type === ListComponentsTypes.INFINITE ?
10018
- (this.items || []).concat([...this.data.slice(start, limit)]) : [...data.slice(start, limit)];
10208
+ this.items =
10209
+ this.type === ListComponentsTypes.INFINITE
10210
+ ? (this.items || []).concat([...this.data.slice(start, limit)])
10211
+ : [...data.slice(start, limit)];
10019
10212
  }
10020
10213
  else {
10021
10214
  const data = await this.parseResult(this.parseSearchResults(this.data, this.searchValue));
@@ -10025,8 +10218,11 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
10025
10218
  }
10026
10219
  }
10027
10220
  else {
10028
- const data = [...await this.parseResult(this.data)];
10029
- this.items = this.type === ListComponentsTypes.INFINITE ? [...(this.items || []), ...(data || [])] : [...(data || [])];
10221
+ const data = [...(await this.parseResult(this.data))];
10222
+ this.items =
10223
+ this.type === ListComponentsTypes.INFINITE
10224
+ ? [...(this.items || []), ...(data || [])]
10225
+ : [...(data || [])];
10030
10226
  if (this.isModalChild)
10031
10227
  this.changeDetectorRef.detectChanges();
10032
10228
  }
@@ -10048,7 +10244,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
10048
10244
  * @memberOf ListComponent
10049
10245
  */
10050
10246
  async getFromModel(force = false) {
10051
- let data = [...this.data || []];
10247
+ let data = [...(this.data || [])];
10052
10248
  let request = [];
10053
10249
  // getting model repository
10054
10250
  if (!this._repository) {
@@ -10057,9 +10253,13 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
10057
10253
  this._repository.observe(this.observer);
10058
10254
  }
10059
10255
  const repo = this._repository;
10060
- if (!this.data?.length || force || this.searchValue?.length || !!this.searchValue) {
10256
+ if (!this.data?.length ||
10257
+ force ||
10258
+ this.searchValue?.length ||
10259
+ !!this.searchValue) {
10061
10260
  try {
10062
- if (!this.searchValue?.length && !this.searchValue) {
10261
+ if (!this.searchValue?.length &&
10262
+ !this.searchValue) {
10063
10263
  this.data = [];
10064
10264
  // const rawQuery = this.parseQuery(self.model as Repository<Model>, start, limit);
10065
10265
  // request = this.parseResult(await (this.model as any)?.paginate(start, limit));
@@ -10073,17 +10273,21 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
10073
10273
  }
10074
10274
  else {
10075
10275
  if (!this.indexes)
10076
- this.indexes = (Object.values(this.mapper) || [this.pk]);
10276
+ this.indexes = Object.values(this.mapper) || [this.pk];
10077
10277
  const condition = this.parseConditions(this.searchValue);
10078
10278
  this.changeDetectorRef.detectChanges();
10079
10279
  request = await this.parseResult(await repo.query(condition, (this.sortBy || this.pk), this.sortDirection));
10080
10280
  data = [];
10081
10281
  this.changeDetectorRef.detectChanges();
10082
10282
  }
10083
- data = this.type === ListComponentsTypes.INFINITE ? [...(data).concat(request)] : [...request];
10283
+ data =
10284
+ this.type === ListComponentsTypes.INFINITE
10285
+ ? [...data.concat(request)]
10286
+ : [...request];
10084
10287
  }
10085
10288
  catch (error) {
10086
- this.log.error(error?.message || `Unable to find ${this.model} on registry. Return empty array from component`);
10289
+ this.log.error(error?.message ||
10290
+ `Unable to find ${this.model} on registry. Return empty array from component`);
10087
10291
  }
10088
10292
  }
10089
10293
  if (data?.length) {
@@ -10123,7 +10327,8 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
10123
10327
  */
10124
10328
  parseConditions(value) {
10125
10329
  let _condition;
10126
- if (typeof value === Primitives.STRING || typeof value === Primitives.NUMBER) {
10330
+ if (typeof value === Primitives.STRING ||
10331
+ typeof value === Primitives.NUMBER) {
10127
10332
  _condition = Condition.attribute(this.pk).eq(!isNaN(value) ? Number(value) : value);
10128
10333
  for (const index of this.indexes) {
10129
10334
  if (index === this.pk)
@@ -10150,27 +10355,28 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
10150
10355
  val = Number(val);
10151
10356
  let orCondition;
10152
10357
  switch (condition) {
10153
- case "Equal":
10358
+ case 'Equal':
10154
10359
  orCondition = Condition.attribute(index).eq(val);
10155
10360
  break;
10156
- case "Not Equal":
10361
+ case 'Not Equal':
10157
10362
  orCondition = Condition.attribute(index).dif(val);
10158
10363
  break;
10159
- case "Not Contains":
10364
+ case 'Not Contains':
10160
10365
  orCondition = !Condition.attribute(index).regexp(new RegExp(`^(?!.*${val}).*$`));
10161
10366
  break;
10162
- case "Contains":
10367
+ case 'Contains':
10163
10368
  orCondition = Condition.attribute(index).regexp(val);
10164
10369
  break;
10165
- case "Greater Than":
10370
+ case 'Greater Than':
10166
10371
  orCondition = Condition.attribute(index).gte(val);
10167
10372
  break;
10168
- case "Less Than":
10373
+ case 'Less Than':
10169
10374
  orCondition = Condition.attribute(index).lte(val);
10170
10375
  break;
10171
10376
  }
10172
- _condition = (!_condition ?
10173
- orCondition : _condition.and(orCondition));
10377
+ _condition = (!_condition
10378
+ ? orCondition
10379
+ : _condition.and(orCondition));
10174
10380
  });
10175
10381
  this.sortBy = sort?.value || this.pk;
10176
10382
  this.sortDirection = sort?.direction || this.sortDirection;
@@ -10190,22 +10396,24 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
10190
10396
  * @memberOf ListComponent
10191
10397
  */
10192
10398
  async parseResult(result) {
10193
- if (!Array.isArray(result) && ('page' in result && 'total' in result)) {
10399
+ if (!Array.isArray(result) && 'page' in result && 'total' in result) {
10194
10400
  const paginator = result;
10195
10401
  try {
10196
10402
  result = await paginator.page(this.page);
10197
10403
  this.getMoreData(paginator.total);
10198
10404
  }
10199
10405
  catch (error) {
10200
- this.log.info(error?.message || 'Unable to get page from paginator. Return empty array from component');
10406
+ this.log.info(error?.message ||
10407
+ 'Unable to get page from paginator. Return empty array from component');
10201
10408
  result = [];
10202
10409
  }
10203
10410
  }
10204
10411
  else {
10205
10412
  this.getMoreData(result?.length || 0);
10206
10413
  }
10207
- return (Object.keys(this.mapper || {}).length) ?
10208
- this.mapResults(result) : result;
10414
+ return Object.keys(this.mapper || {}).length
10415
+ ? this.mapResults(result)
10416
+ : result;
10209
10417
  }
10210
10418
  /**
10211
10419
  * @description Updates pagination state based on data length.
@@ -10227,7 +10435,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
10227
10435
  }
10228
10436
  else {
10229
10437
  this.pages = Math.floor(length / this.limit);
10230
- if ((this.pages * this.limit) < length)
10438
+ if (this.pages * this.limit < length)
10231
10439
  this.pages += 1;
10232
10440
  if (this.pages === 1)
10233
10441
  this.loadMoreData = false;
@@ -10261,7 +10469,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
10261
10469
  }
10262
10470
  else {
10263
10471
  if (arrayValue.length === 1) {
10264
- value = item?.[value] ? item[value] : "";
10472
+ value = item?.[value] ? item[value] : '';
10265
10473
  // value = item?.[value] ? item[value] : value !== key ? value : "";
10266
10474
  if (isValidDate(value))
10267
10475
  value = `${formatDate(value)}`;
@@ -10310,18 +10518,23 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
10310
10518
  // }, {}))
10311
10519
  });
10312
10520
  return data.reduce((accum, curr) => {
10313
- accum.push({ ...this.itemMapper(curr, this.mapper, props), ...{ pk: this.pk } });
10521
+ accum.push({
10522
+ ...this.itemMapper(curr, this.mapper, props),
10523
+ ...{ pk: this.pk },
10524
+ });
10314
10525
  return accum;
10315
10526
  }, []);
10316
10527
  }
10317
10528
  parseSearchValue() {
10318
10529
  if (typeof this.searchValue === Primitives.STRING)
10319
- return this.searchValue || "";
10530
+ return this.searchValue || '';
10320
10531
  const searchValue = this.searchValue;
10321
- return (searchValue?.query).map(item => `${item.index} ${item.condition} ${item.value}`).join(", ");
10532
+ return (searchValue?.query)
10533
+ .map((item) => `${item.index} ${item.condition} ${item.value}`)
10534
+ .join(', ');
10322
10535
  }
10323
10536
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
10324
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: ListComponent, isStandalone: true, selector: "ngx-decaf-list", inputs: { type: "type", showSearchbar: "showSearchbar", data: "data", source: "source", start: "start", limit: "limit", loadMoreData: "loadMoreData", lines: "lines", inset: "inset", scrollThreshold: "scrollThreshold", scrollPosition: "scrollPosition", loadingText: "loadingText", showRefresher: "showRefresher", createButton: "createButton", loadingSpinner: "loadingSpinner", enableFilter: "enableFilter", sortDirection: "sortDirection", sortBy: "sortBy", disableSort: "disableSort", empty: "empty" }, outputs: { refreshEvent: "refreshEvent", clickEvent: "clickEvent" }, host: { listeners: { "window:ListItemClickEvent": "handleClick($event)", "window:searchbarEvent": "handleSearch($event)", "window:BackButtonNavigationEndEvent": "refresh($event)" }, properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "\n@if (showRefresher) {\n <ion-refresher slot=\"fixed\" [pullFactor]=\"1\" [pullMin]=\"100\" [pullMax]=\"200\" (ionRefresh)=\"handleRefresh($event)\">\n <ion-refresher-content />\n </ion-refresher>\n}\n\n\n@if (showSearchbar) {\n <div [hidden]=\"!data?.length\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-grid-actions\">\n <div class=\"dcf-width-expand@m dcf-width-1-1\">\n @if (model && enableFilter) {\n @if (data?.length || searching) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n } @else {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n }\n </div>\n @if(createButton) {\n <div class=\"dcf-width-auto@m dcf-button-container dcf-width-1-1 dcf-flex-middle dcf-flex dcf-flex-center dcf-flex-right@m\">\n <div>\n <ion-button expand=\"block\" (click)=\"changeOperation(OperationKeys.CREATE)\">Create</ion-button>\n </div>\n </div>\n }\n </div>\n </div>\n}\n\n@if (initialized && data?.length) {\n <ion-list [id]=\"uid\" [inset]=\"inset\" [lines]=\"lines\">\n @if (item?.tag) {\n @for(child of items; track trackItemFn($index, child)) {\n <ngx-decaf-component-renderer\n [tag]=\"item.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]='{\n item: child,\n mapper: mapper,\n route: route\n }'>\n </ngx-decaf-component-renderer>\n }\n } @else {\n <ng-content></ng-content>\n }\n </ion-list>\n\n @if (loadMoreData) {\n @if (pages > 0 && type === 'paginated' && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n\n } @else {\n <ion-infinite-scroll\n [class]=\"searchValue?.length ? 'dcf-hidden' : ''\"\n\n [position]=\"scrollPosition\"\n [threshold]=\"scrollThreshold\"\n (ionInfinite)=\"handleRefresh($event)\">\n <ion-infinite-scroll-content [loadingSpinner]=\"loadingSpinner\" [loadingText]=\"loadingText\" />\n </ion-infinite-scroll>\n }\n }\n} @else {\n @if (refreshing) {\n @for(skl of skeletonData; track $index) {\n <ion-item>\n <ion-thumbnail slot=\"start\">\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n </ion-thumbnail>\n <ion-label>\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%;\"><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text></ion-text>\n </ion-label>\n </ion-item>\n }\n\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [model]=\"model\"\n [route]=\"route\"\n [borders]=\"borders\"\n [icon]=\"empty.icon\"\n className=\"dcf-empty-data\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\" />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"model\"\n [route]=\"route\"\n [borders]=\"borders\"\n className=\"empty-search\"\n [translatable]=\"true\"\n className=\"dcf-empty-data\"\n [title]=\"locale + '.search.title' | translate\"\n [subtitle]=\"locale + '.search.subtitle' | translate: {'0': parseSearchValue()}\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n}\n\n", styles: ["ion-infinite-scroll{max-height:50px}ion-infinite-scroll:not(.infinite-scroll-loading) ::ng-deep{max-height:1.5rem}ion-infinite-scroll ::ng-deep ion-spinner{--color: var(--dcf-color-primary);padding-top:1rem}@media (max-width: 768px){#end,[slot=end]{display:none!important}}.dcf-grid-actions{padding:var(--dcf-padding-small);padding-bottom:0}@media (max-width: 768px){.dcf-grid-actions .dcf-button-container{width:100%!important}.dcf-grid-actions .dcf-button-container *{width:calc(100% - 5px)!important;display:inline-block;margin-top:0!important;margin-bottom:var(--dcf-margin-xsmall)!important}}.dcf-grid-actions>div:only-child{width:100%}\n"], dependencies: [{ kind: "component", type: IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: PaginationComponent, selector: "ngx-decaf-pagination", inputs: ["totalPages", "current"], outputs: ["clickEvent"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonThumbnail, selector: "ion-thumbnail" }, { kind: "component", type: IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }, { kind: "component", type: SearchbarComponent, selector: "ngx-decaf-searchbar", inputs: ["autocomplete", "autocorrect", "animated", "buttonCancelText", "clearIcon", "color", "debounce", "disabled", "enterkeyhint", "inputmode", "placeholder", "searchIcon", "showCancelButton", "showClearButton", "spellcheck", "type", "value", "queryKeys", "isVisible", "wrapper", "wrapperColor", "emitEventToWindow"], outputs: ["searchEvent"] }, { kind: "component", type: EmptyStateComponent, selector: "ngx-decaf-empty-state", inputs: ["title", "titleColor", "subtitle", "subtitleColor", "showIcon", "icon", "iconSize", "iconColor", "buttonLink", "buttonText", "buttonFill", "buttonColor", "buttonSize", "searchValue"] }, { kind: "component", type: FilterComponent, selector: "ngx-decaf-filter", inputs: ["indexes", "multiple", "conditions", "sortBy", "disableSort"], outputs: ["filterEvent", "searchEvent"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
10537
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: ListComponent, isStandalone: true, selector: "ngx-decaf-list", inputs: { type: "type", showSearchbar: "showSearchbar", data: "data", source: "source", start: "start", limit: "limit", loadMoreData: "loadMoreData", lines: "lines", inset: "inset", scrollThreshold: "scrollThreshold", scrollPosition: "scrollPosition", loadingText: "loadingText", showRefresher: "showRefresher", createButton: "createButton", loadingSpinner: "loadingSpinner", enableFilter: "enableFilter", sortDirection: "sortDirection", sortBy: "sortBy", disableSort: "disableSort", empty: "empty" }, outputs: { clickEvent: "clickEvent" }, host: { listeners: { "window:ListItemClickEvent": "handleClick($event)", "window:searchbarEvent": "handleSearch($event)", "window:BackButtonNavigationEndEvent": "refresh($event)" }, properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "\n@if (showRefresher) {\n <ion-refresher slot=\"fixed\" [pullFactor]=\"1\" [pullMin]=\"100\" [pullMax]=\"200\" (ionRefresh)=\"handleRefresh($event)\">\n <ion-refresher-content />\n </ion-refresher>\n}\n\n\n@if (showSearchbar) {\n <div [hidden]=\"!data?.length\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-grid-actions\">\n <div class=\"dcf-width-expand@m dcf-width-1-1\">\n @if (model && enableFilter) {\n @if (data?.length || searching) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n } @else {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n }\n </div>\n @if(createButton) {\n <div class=\"dcf-width-auto@m dcf-button-container dcf-width-1-1 dcf-flex-middle dcf-flex dcf-flex-center dcf-flex-right@m\">\n <div>\n <ion-button expand=\"block\" (click)=\"changeOperation(OperationKeys.CREATE)\">Create</ion-button>\n </div>\n </div>\n }\n </div>\n </div>\n}\n\n@if (initialized && data?.length) {\n <ion-list [id]=\"uid\" [inset]=\"inset\" [lines]=\"lines\">\n @if (item?.tag) {\n @for(child of items; track trackItemFn($index, child)) {\n <ngx-decaf-component-renderer\n [tag]=\"item.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]='{\n item: child,\n mapper: mapper,\n route: route\n }'>\n </ngx-decaf-component-renderer>\n }\n } @else {\n <ng-content></ng-content>\n }\n </ion-list>\n\n @if (loadMoreData) {\n @if (pages > 0 && type === 'paginated' && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n\n } @else {\n <ion-infinite-scroll\n [class]=\"searchValue?.length ? 'dcf-hidden' : ''\"\n\n [position]=\"scrollPosition\"\n [threshold]=\"scrollThreshold\"\n (ionInfinite)=\"handleRefresh($event)\">\n <ion-infinite-scroll-content [loadingSpinner]=\"loadingSpinner\" [loadingText]=\"loadingText\" />\n </ion-infinite-scroll>\n }\n }\n} @else {\n @if (refreshing) {\n @for(skl of skeletonData; track $index) {\n <ion-item>\n <ion-thumbnail slot=\"start\">\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n </ion-thumbnail>\n <ion-label>\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%;\"><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text></ion-text>\n </ion-label>\n </ion-item>\n }\n\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [model]=\"model\"\n [route]=\"route\"\n [borders]=\"borders\"\n [icon]=\"empty.icon\"\n className=\"dcf-empty-data\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\" />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"model\"\n [route]=\"route\"\n [borders]=\"borders\"\n className=\"empty-search\"\n [translatable]=\"true\"\n className=\"dcf-empty-data\"\n [title]=\"locale + '.search.title' | translate\"\n [subtitle]=\"locale + '.search.subtitle' | translate: {'0': parseSearchValue()}\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n}\n\n", styles: ["ion-infinite-scroll{max-height:50px}ion-infinite-scroll:not(.infinite-scroll-loading) ::ng-deep{max-height:1.5rem}ion-infinite-scroll ::ng-deep ion-spinner{--color: var(--dcf-color-primary);padding-top:1rem}@media (max-width: 768px){#end,[slot=end]{display:none!important}}.dcf-grid-actions{padding:var(--dcf-padding-small);padding-bottom:0}@media (max-width: 768px){.dcf-grid-actions .dcf-button-container{width:100%!important}.dcf-grid-actions .dcf-button-container *{width:calc(100% - 5px)!important;display:inline-block;margin-top:0!important;margin-bottom:var(--dcf-margin-xsmall)!important}}.dcf-grid-actions>div:only-child{width:100%}\n"], dependencies: [{ kind: "component", type: IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: PaginationComponent, selector: "ngx-decaf-pagination", inputs: ["totalPages", "current"], outputs: ["clickEvent"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonThumbnail, selector: "ion-thumbnail" }, { kind: "component", type: IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }, { kind: "component", type: SearchbarComponent, selector: "ngx-decaf-searchbar", inputs: ["autocomplete", "autocorrect", "animated", "buttonCancelText", "clearIcon", "color", "debounce", "disabled", "enterkeyhint", "inputmode", "placeholder", "searchIcon", "showCancelButton", "showClearButton", "spellcheck", "type", "value", "queryKeys", "isVisible", "wrapper", "wrapperColor", "emitEventToWindow"], outputs: ["searchEvent"] }, { kind: "component", type: EmptyStateComponent, selector: "ngx-decaf-empty-state", inputs: ["title", "titleColor", "subtitle", "subtitleColor", "showIcon", "icon", "iconSize", "iconColor", "buttonLink", "buttonText", "buttonFill", "buttonColor", "buttonSize", "searchValue"] }, { kind: "component", type: FilterComponent, selector: "ngx-decaf-filter", inputs: ["indexes", "multiple", "conditions", "sortBy", "disableSort"], outputs: ["filterEvent", "searchEvent"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
10325
10538
  };
10326
10539
  ListComponent = __decorate([
10327
10540
  Dynamic(),
@@ -10348,7 +10561,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
10348
10561
  SearchbarComponent,
10349
10562
  EmptyStateComponent,
10350
10563
  FilterComponent,
10351
- ComponentRendererComponent
10564
+ ComponentRendererComponent,
10352
10565
  ], host: { '[attr.id]': 'uid' }, template: "\n@if (showRefresher) {\n <ion-refresher slot=\"fixed\" [pullFactor]=\"1\" [pullMin]=\"100\" [pullMax]=\"200\" (ionRefresh)=\"handleRefresh($event)\">\n <ion-refresher-content />\n </ion-refresher>\n}\n\n\n@if (showSearchbar) {\n <div [hidden]=\"!data?.length\">\n <div class=\"dcf-grid dcf-grid-collapse dcf-grid-actions\">\n <div class=\"dcf-width-expand@m dcf-width-1-1\">\n @if (model && enableFilter) {\n @if (data?.length || searching) {\n <ngx-decaf-filter\n [model]=\"model\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n } @else {\n <ngx-decaf-searchbar [emitEventToWindow]=\"false\" [debounce]=\"500\" (searchEvent)=\"handleSearch($event)\" />\n }\n </div>\n @if(createButton) {\n <div class=\"dcf-width-auto@m dcf-button-container dcf-width-1-1 dcf-flex-middle dcf-flex dcf-flex-center dcf-flex-right@m\">\n <div>\n <ion-button expand=\"block\" (click)=\"changeOperation(OperationKeys.CREATE)\">Create</ion-button>\n </div>\n </div>\n }\n </div>\n </div>\n}\n\n@if (initialized && data?.length) {\n <ion-list [id]=\"uid\" [inset]=\"inset\" [lines]=\"lines\">\n @if (item?.tag) {\n @for(child of items; track trackItemFn($index, child)) {\n <ngx-decaf-component-renderer\n [tag]=\"item.tag\"\n (listenEvent)=\"handleEvent($event)\"\n [globals]='{\n item: child,\n mapper: mapper,\n route: route\n }'>\n </ngx-decaf-component-renderer>\n }\n } @else {\n <ng-content></ng-content>\n }\n </ion-list>\n\n @if (loadMoreData) {\n @if (pages > 0 && type === 'paginated' && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n\n } @else {\n <ion-infinite-scroll\n [class]=\"searchValue?.length ? 'dcf-hidden' : ''\"\n\n [position]=\"scrollPosition\"\n [threshold]=\"scrollThreshold\"\n (ionInfinite)=\"handleRefresh($event)\">\n <ion-infinite-scroll-content [loadingSpinner]=\"loadingSpinner\" [loadingText]=\"loadingText\" />\n </ion-infinite-scroll>\n }\n }\n} @else {\n @if (refreshing) {\n @for(skl of skeletonData; track $index) {\n <ion-item>\n <ion-thumbnail slot=\"start\">\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n </ion-thumbnail>\n <ion-label>\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n <ion-text class=\"date\" style=\"width: 20%;\"><ion-skeleton-text [animated]=\"true\"></ion-skeleton-text></ion-text>\n </ion-label>\n </ion-item>\n }\n\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"(locale + '.'+ empty.title) | translate\"\n [model]=\"model\"\n [route]=\"route\"\n [borders]=\"borders\"\n [icon]=\"empty.icon\"\n className=\"dcf-empty-data\"\n [subtitle]=\"(locale + '.'+ empty.subtitle) | translate\" />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"model\"\n [route]=\"route\"\n [borders]=\"borders\"\n className=\"empty-search\"\n [translatable]=\"true\"\n className=\"dcf-empty-data\"\n [title]=\"locale + '.search.title' | translate\"\n [subtitle]=\"locale + '.search.subtitle' | translate: {'0': parseSearchValue()}\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n}\n\n", styles: ["ion-infinite-scroll{max-height:50px}ion-infinite-scroll:not(.infinite-scroll-loading) ::ng-deep{max-height:1.5rem}ion-infinite-scroll ::ng-deep ion-spinner{--color: var(--dcf-color-primary);padding-top:1rem}@media (max-width: 768px){#end,[slot=end]{display:none!important}}.dcf-grid-actions{padding:var(--dcf-padding-small);padding-bottom:0}@media (max-width: 768px){.dcf-grid-actions .dcf-button-container{width:100%!important}.dcf-grid-actions .dcf-button-container *{width:calc(100% - 5px)!important;display:inline-block;margin-top:0!important;margin-bottom:var(--dcf-margin-xsmall)!important}}.dcf-grid-actions>div:only-child{width:100%}\n"] }]
10353
10566
  }], ctorParameters: () => [], propDecorators: { type: [{
10354
10567
  type: Input
@@ -10390,8 +10603,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
10390
10603
  type: Input
10391
10604
  }], empty: [{
10392
10605
  type: Input
10393
- }], refreshEvent: [{
10394
- type: Output
10395
10606
  }], clickEvent: [{
10396
10607
  type: Output
10397
10608
  }], handleClick: [{
@@ -11211,7 +11422,7 @@ let FileUploadComponent = class FileUploadComponent extends NgxFormFieldDirectiv
11211
11422
  *
11212
11423
  * @type {string | undefined}
11213
11424
  */
11214
- this.preview = undefined;
11425
+ this.previewFile = undefined;
11215
11426
  /**
11216
11427
  * @description List of files selected for upload.
11217
11428
  * @summary Contains the files selected by the user for upload. This array is updated
@@ -11263,6 +11474,28 @@ let FileUploadComponent = class FileUploadComponent extends NgxFormFieldDirectiv
11263
11474
  }
11264
11475
  // Convert maxFileSize from MB to bytes
11265
11476
  this.maxFileSize = this.maxFileSize * 1024 * 1024;
11477
+ this.initialize();
11478
+ }
11479
+ async initialize() {
11480
+ if (this.value && typeof this.value === Primitives.STRING) {
11481
+ try {
11482
+ const files = JSON.parse(this.value);
11483
+ this.files = files.map(file => {
11484
+ const mime = this.getFileMime(file)?.split('/') || [];
11485
+ const type = mime?.[0] === 'text' ? mime?.[1] : mime?.[0];
11486
+ return {
11487
+ name: mime?.[0] || 'file',
11488
+ type: `${type}` || 'image/*',
11489
+ source: file
11490
+ };
11491
+ });
11492
+ this.getPreview();
11493
+ }
11494
+ catch (error) {
11495
+ this.log.for(this.initialize).error(`Error parsing file list: ${error.message || error}`);
11496
+ }
11497
+ }
11498
+ this.initialized = true;
11266
11499
  }
11267
11500
  /**
11268
11501
  * @description Lifecycle hook that is called when a directive, pipe, or service is destroyed.
@@ -11360,7 +11593,7 @@ let FileUploadComponent = class FileUploadComponent extends NgxFormFieldDirectiv
11360
11593
  */
11361
11594
  handleClear() {
11362
11595
  this.clearErrors();
11363
- this.preview = undefined;
11596
+ this.previewFile = undefined;
11364
11597
  this.files = [];
11365
11598
  }
11366
11599
  /**
@@ -11435,14 +11668,15 @@ let FileUploadComponent = class FileUploadComponent extends NgxFormFieldDirectiv
11435
11668
  * @param {File | string} [file] - The file to be previewed. If not provided, the current preview file is used.
11436
11669
  * @returns {Promise<void>}
11437
11670
  */
11438
- async showFilePreview(file, fileExtension = 'image/') {
11671
+ async preview(file, fileExtension = 'image/') {
11672
+ this.log.for(this).info(`Previewing file of type: ${fileExtension}`);
11439
11673
  let content;
11440
11674
  if (file instanceof File) {
11441
11675
  const dataUrl = await this.getDataURLs(file);
11442
11676
  if (dataUrl && dataUrl.length)
11443
11677
  file = dataUrl[0];
11444
11678
  }
11445
- if (fileExtension.includes('image/'))
11679
+ if (fileExtension.includes('image'))
11446
11680
  content = '<img src="' + file + '" style="max-width: 100%; height: auto;" />';
11447
11681
  if (fileExtension.includes('xml')) {
11448
11682
  const parseXml = (xmlString) => {
@@ -11461,8 +11695,15 @@ let FileUploadComponent = class FileUploadComponent extends NgxFormFieldDirectiv
11461
11695
  return undefined;
11462
11696
  }
11463
11697
  };
11464
- content = parseXml(file);
11465
- content = `<div class="dfc-padding">${content}</div>`;
11698
+ if (this.previewHandler && typeof this.previewHandler === 'function') {
11699
+ const clazz = new this.previewHandler();
11700
+ const previewFn = clazz.handle.bind(this);
11701
+ return previewFn(file);
11702
+ }
11703
+ else {
11704
+ content = parseXml(file);
11705
+ content = `<div class="dfc-padding">${content}</div>`;
11706
+ }
11466
11707
  }
11467
11708
  await presentNgxLightBoxModal(content || "");
11468
11709
  }
@@ -11477,6 +11718,10 @@ let FileUploadComponent = class FileUploadComponent extends NgxFormFieldDirectiv
11477
11718
  isImageFile(file) {
11478
11719
  return file && file.type.startsWith('image/');
11479
11720
  }
11721
+ getFileMime(base64) {
11722
+ const match = base64.match(/^data:(.*?);base64,/);
11723
+ return match ? match[1] : "";
11724
+ }
11480
11725
  /**
11481
11726
  * @description Removes a file from the selection.
11482
11727
  * @summary Updates the file list to exclude the file at the specified index.
@@ -11499,12 +11744,15 @@ let FileUploadComponent = class FileUploadComponent extends NgxFormFieldDirectiv
11499
11744
  * @returns {Promise<void>}
11500
11745
  */
11501
11746
  async getPreview() {
11502
- this.preview = undefined;
11747
+ this.previewFile = undefined;
11503
11748
  const file = this.files && this.files.length ? this.files[0] : null;
11504
- if (file) {
11749
+ if (file instanceof File) {
11505
11750
  const dataUrl = await this.getDataURLs(file);
11506
11751
  if (dataUrl && dataUrl.length)
11507
- this.preview = dataUrl[0];
11752
+ this.previewFile = dataUrl[0];
11753
+ }
11754
+ else {
11755
+ this.previewFile = file?.['source'];
11508
11756
  }
11509
11757
  }
11510
11758
  /**
@@ -11603,7 +11851,7 @@ let FileUploadComponent = class FileUploadComponent extends NgxFormFieldDirectiv
11603
11851
  })));
11604
11852
  }
11605
11853
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FileUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
11606
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: FileUploadComponent, isStandalone: true, selector: "ngx-decaf-file-upload", inputs: { formGroup: "formGroup", name: "name", formControl: "formControl", required: "required", multiple: "multiple", type: "type", label: "label", buttonLabel: "buttonLabel", size: "size", position: "position", accept: "accept", showIcon: "showIcon", enableDirectoryMode: "enableDirectoryMode", maxFileSize: "maxFileSize" }, outputs: { changeEvent: "changeEvent" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"decaf-file-component\" #component>\n <input\n id=\"dcf-file-input\"\n type=\"file\"\n placeholder=\"Select files\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"handleSelection($event)\"\n [multiple]=\"multiple\"\n hidden\n [attr.webkitdirectory]=\"enableDirectoryMode ? true : null\"\n />\n\n <ngx-decaf-card [className]=\"className\" [body]=\"'blank'\">\n <div>\n <div\n [class]=\"\n 'dcf-drop-area '\n + ' dcf-' + size\n + ' dcf-flex dcf-flex-' + position\n + ' dcf-text-' + position\n \"\n\n [class.dcf-dragging]=\"dragging\"\n [class.dcf-has-files]=\"files.length\"\n (drop)=\"!files?.length ? handleDrop($event) : dragging = false\"\n (dragover)=\"!files?.length ? handleDragOver($event) : dragging = false\"\n (dragleave)=\"!files?.length ? handleDragLeave($event) : dragging = false\"\n >\n <div>\n @if (!preview) {\n @if(showIcon) {\n <ngx-decaf-icon name=\"cloud-upload-outline\" size=\"large\" />\n }\n <p class=\"dcf-drag-description\">{{ label ? (label | translate) : (locale + \".drag_file\" | translate) }}</p>\n <ion-button class=\"dcf-button-select\" (click)=\"handleClickToSelect()\" size=\"small\">\n {{ buttonLabel ? (buttonLabel | translate) : (locale + \".buttons.select\" | translate) }}\n </ion-button>\n <div #container>\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n } @else {\n @if ((!directoryMode && !multiple) ) {\n <div class=\"dcf-preview dcf-grid dcf-grid-match dcf-grid-collapse\">\n <div class=\"dcf-width-1-4@m dcf-width-1-3@s dcf-flex dcf-flex-center dcf-flex-middle\">\n <div class=\"dcf-preview-image\">\n <ion-img\n [src]=\"preview\"\n [title]=\"locale + '.preview' | translate\"\n [alt]=\"locale + '.preview' | translate\"\n />\n <div class=\"dcf-overlay\">\n <ion-button (click)=\"showFilePreview(preview)\" fill=\"clear\" color=\"light\" size=\"small\">\n {{ locale + \".buttons.preview\" | translate }}\n </ion-button>\n </div>\n </div>\n </div>\n <div class=\"description dcf-flex dcf-flex-middle dcf-width-expand@s\">\n <div>\n <p class=\"dcf-title\">{{ locale + \".preview\" | translate }}</p>\n <p class=\"subtitle\">{{ files[0].name }}</p>\n <ion-button (click)=\"handleClear()\" fill=\"clear\" color=\"danger\" size=\"small\">{{ locale + \".buttons.clear\" | translate }} </ion-button>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"dcf-margin-bottom\">\n {{ locale + \".selection\" | translate: { \"0\": files.length > 10 ? files.length : `0${files.length}` } }}\n @if(errors.length > 0) {\n <br /><span class=\"dcf-error-message\">{{ locale + \".selection_error\" | translate: { \"0\": errors.length > 10 ? errors.length : `0${errors.length}` } }}</span>\n }\n </div>\n <div class=\"dcf-preview-list-container\">\n <ion-list class=\"dcf-preview-list\">\n @for (file of errors; track $index) {\n <ion-item lines=\"full\" class=\"dcf-error-item\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <div class=\"dcf-error-message\" slot=\"end\">\n {{ locale + \".errors.\" + file.error | translate: { \"0\": file.error === 'max_size' ? maxFileSize / 1024 / 1024 : file.name.split(\".\") } }}\n </div>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n </ion-item>\n }\n\n @for (file of files; track $index) {\n <ion-item lines=\"full\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n <div class=\"dcf-flex dcf-flex-middle\" slot=\"end\">\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n (click)=\"showFilePreview(file, file.type)\"\n [name]=\"'image-outline'\"\n />\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n [name]=\"'trash-outline'\"\n (click)=\"removeFile($index)\"\n [color]=\"'danger'\"\n [size]=\"'small'\"\n />\n </div>\n </ion-item>\n }\n </ion-list>\n </div>\n }\n }\n </div>\n\n\n </div>\n </div>\n </ngx-decaf-card>\n</div>\n\n<!-- <ion-card-header>\n <ion-card-title>Upload de Imagem</ion-card-title>\n </ion-card-header>\n\n <ion-card-content>\n <div\n class=\"dcf-drop-area\"\n [class.dragging]=\"dragging\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n >\n <div class=\"dcf-drop-content\">\n <ion-icon name=\"cloud-upload-outline\" size=\"large\"></ion-icon>\n <p>Arraste e solte aqui ou</p>\n <ion-button size=\"small\" fill=\"outline\" (click)=\"triggerFileSelect()\">Selecionar arquivo</ion-button>\n </div>\n </div>\n\n <input\n #fileInput\n type=\"file\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"onFileSelected($event)\"\n hidden\n />\n\n <div *ngIf=\"previewUrl\" class=\"dcf-preview\">\n <ion-item>\n <div slot=\"start\">\n <ion-img [src]=\"previewUrl\"></ion-img>\n </div>\n <ion-label>\n <h3>Pr\u00E9-visualiza\u00E7\u00E3o</h3>\n <p *ngIf=\"files.length\">{{ files[0].name }}</p>\n </ion-label>\n </ion-item>\n </div>\n\n <ion-list *ngIf=\"files.length\">\n <ion-list-header>\n <ion-label>Arquivos selecionados</ion-label>\n </ion-list-header>\n <ion-item *ngFor=\"let f of files; let i = index\">\n <ion-label>{{ f.name }}</ion-label>\n <ion-note slot=\"end\">{{ (f.size / 1024 / 1024) | number:'1.1-1' }} MB</ion-note>\n <ion-button fill=\"clear\" slot=\"end\" (click)=\"removeFile(i)\">\n <ion-icon slot=\"icon-only\" name=\"close-circle\"></ion-icon>\n </ion-button>\n </ion-item>\n </ion-list>\n\n <div *ngIf=\"errors.length\">\n <ion-list>\n <ion-item *ngFor=\"let err of errors\">\n <ion-icon name=\"alert-circle\" slot=\"start\" color=\"danger\"></ion-icon>\n <ion-label color=\"danger\">{{ err }}</ion-label>\n </ion-item>\n </ion-list>\n </div>\n\n <ion-row class=\"dcf-actions\">\n <ion-col>\n <ion-button expand=\"block\" (click)=\"triggerFileSelect()\">Selecionar</ion-button>\n </ion-col>\n <ion-col>\n <ion-button expand=\"block\" color=\"danger\" fill=\"outline\" (click)=\"clear()\">Limpar</ion-button>\n </ion-col>\n </ion-row>\n </ion-card-content> -->\n", styles: [".decaf-file-component.dcf-palette-dark .dcf-button-select{--background: rgb(var(--dcf-color-light-rgb), .1) !important;--background-hover: rgb(var(--dcf-color-light-rgb), .75) !important;--background-activated: rgb(var(--dcf-color-light-rgb), .4) !important;--background-focused: rgb(var(--dcf-color-light-rgb), .4) !important;--color: var(--dcf-color-light) !important}.decaf-file-component.dcf-palette-dark .dcf-has-files{border-style:solid;border-color:var(--dcf-color-gray-6)!important}.decaf-file-component .dcf-upload-icon{--box-shadow: none !important}.decaf-file-component .dcf-upload-icon ion-icon{width:1.5rem!important}.decaf-file-component ion-button.dcf-button-select{--background: rgb(var(--dcf-color-primary-rgb), .1);--background-hover: rgb(var(--dcf-color-primary-rgb), .75);--background-activated: rgb(var(--dcf-color-primary-rgb), .4);--background-focused: rgb(var(--dcf-color-primary-rgb), .4);--color: var(--dcf-color-primary-shade);--border-radius: var(--dcf-border-radius-small);--box-shadow: none;--padding-top: var(--dcf-padding-xsmall);--padding-bottom: var(--dcf-padding-xsmall);--padding-start: var(--dcf-padding-small);--padding-end: var(--dcf-padding-small);font-weight:500;text-transform:none;margin-top:var(--dcf-margin-small)!important}.decaf-file-component .dcf-error{color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999;animation-duration:.05s;animation-timing-function:ease-in;animation-fill-mode:both;animation-name:fadeBottomSmallAnimation}.decaf-file-component .dcf-error .ti,.decaf-file-component .dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.decaf-file-component ion-card-content{width:100%}.decaf-file-component .dcf-error-message{color:var(--dcf-color-danger);font-size:.875rem}.decaf-file-component .dcf-drag-description{font-size:1rem;line-height:1.5rem;font-weight:500;margin-bottom:var(--dcf-margin-small)}.decaf-file-component .dcf-drop-area{display:flex;align-items:center;border:1.5px dashed var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-small)!important;transition:border-style .15s ease,border-color .15s ease;background:transparent}.decaf-file-component .dcf-drop-area.dcf-large{min-height:180px}.decaf-file-component .dcf-drop-area>div{width:100%}.decaf-file-component .dcf-drop-area.dcf-has-files{border-style:solid;border-color:var(--dcf-color-primary-shade);transition:border-style .15s ease,border-color .15s ease;padding:var(--dcf-spacement) var(--dcf-spacement-small)!important}.decaf-file-component .dcf-drop-area:not(.dcf-has-files){border-style:dashed;padding:var(--dcf-spacement) var(--dcf-spacement-medium)}.decaf-file-component .dcf-drop-area.dcf-dragging{background:#00000008;border-color:var(--ion-color-primary);box-shadow:0 2px 8px #0000000f}.decaf-file-component .dcf-preview .dcf-preview-image{border:1px solid var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-xsmall);max-width:320px;padding:.5rem;box-sizing:border-box;height:160px;position:relative;cursor:pointer;overflow:hidden}.decaf-file-component .dcf-preview .dcf-preview-image ion-img{height:140px!important;display:block;width:100%}.decaf-file-component .dcf-preview .dcf-preview-image:hover .dcf-overlay{opacity:1}.decaf-file-component .dcf-preview .dcf-preview-image .dcf-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:#0009;display:flex;justify-content:center;align-items:center;opacity:0;transition:opacity .3s ease}.decaf-file-component .dcf-preview .description{text-align:left;padding:1rem;font-size:.75rem}.decaf-file-component .dcf-preview .description .dcf-title{font-size:1rem;font-weight:500}.decaf-file-component .dcf-preview .description ion-button{margin-top:var(--dcf-margin-small)!important}.decaf-file-component .dcf-preview-list-container{max-height:150px;overflow-y:auto}.decaf-file-component .dcf-preview-list-container ion-list{padding:0!important;margin:0!important}@media (max-width: 767px){.decaf-file-component .dcf-preview-list-container ion-list{width:100%;min-width:576px;overflow-x:auto}}.decaf-file-component .dcf-preview-list-container:not(:hover){scrollbar-color:rgba(var(--dcf-color-medium-rgb),.125) transparent!important}.decaf-file-component .dcf-preview-list-container ion-item{font-size:.875rem!important}.decaf-file-component .dcf-preview-list-container ion-item.dcf-error-item{--background: rgba(var(--dcf-color-danger-rgb), .02) !important;--border-color: rgba(var(--dcf-color-danger-rgb), .2) !important}.decaf-file-component .dcf-preview-list-container ion-item ion-item{--padding-top: .25rem;--padding-bottom: 0rem;--inner-padding-start: 0rem;--padding-start: var(--dcf-padding-xsmall) !important;--padding-end: 0rem;--inner-padding-end: var(--dcf-padding-xsmall) !important;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8);--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: CardComponent, selector: "ngx-decaf-card", inputs: ["type", "title", "body", "subtitle", "color", "separator", "borders", "inlineContent", "inlineContentPosition"] }, { kind: "component", type: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "pipe", type: i1$1.DecimalPipe, name: "number" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
11854
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: FileUploadComponent, isStandalone: true, selector: "ngx-decaf-file-upload", inputs: { formGroup: "formGroup", name: "name", formControl: "formControl", required: "required", multiple: "multiple", type: "type", label: "label", buttonLabel: "buttonLabel", size: "size", position: "position", accept: "accept", showIcon: "showIcon", enableDirectoryMode: "enableDirectoryMode", previewHandler: "previewHandler", maxFileSize: "maxFileSize" }, outputs: { changeEvent: "changeEvent" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"decaf-file-component\" #component>\n <input\n id=\"dcf-file-input\"\n type=\"file\"\n placeholder=\"Select files\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"handleSelection($event)\"\n [multiple]=\"multiple\"\n hidden\n [attr.webkitdirectory]=\"enableDirectoryMode ? true : null\"\n />\n\n <ngx-decaf-card [className]=\"className\" [body]=\"'blank'\">\n @if(['create', 'update'].includes(operation)) {\n <div>\n <div\n [class]=\"\n 'dcf-drop-area '\n + ' dcf-' + size\n + ' dcf-flex dcf-flex-' + position\n + ' dcf-text-' + position\n \"\n\n [class.dcf-dragging]=\"dragging\"\n [class.dcf-has-files]=\"files.length\"\n (drop)=\"!files?.length ? handleDrop($event) : dragging = false\"\n (dragover)=\"!files?.length ? handleDragOver($event) : dragging = false\"\n (dragleave)=\"!files?.length ? handleDragLeave($event) : dragging = false\"\n >\n <div>\n @if (!previewFile) {\n @if(showIcon) {\n <ngx-decaf-icon name=\"cloud-upload-outline\" size=\"large\" />\n }\n <p class=\"dcf-drag-description\">{{ label ? (label | translate) : (locale + \".drag_file\" | translate) }}</p>\n <ion-button class=\"dcf-button-select\" (click)=\"handleClickToSelect()\" size=\"small\">\n {{ buttonLabel ? (buttonLabel | translate) : (locale + \".buttons.select\" | translate) }}\n </ion-button>\n <div #container>\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n } @else {\n @if ((!directoryMode && !multiple) ) {\n <div class=\"dcf-preview dcf-grid dcf-grid-match dcf-grid-collapse\">\n <div class=\"dcf-width-1-4@m dcf-width-1-3@s dcf-flex dcf-flex-center dcf-flex-middle\">\n <div class=\"dcf-preview-image\">\n <ion-img\n [src]=\"previewFile\"\n [title]=\"locale + '.preview' | translate\"\n [alt]=\"locale + '.preview' | translate\"\n />\n <div class=\"dcf-overlay\">\n <ion-button (click)=\"preview(previewFile)\" fill=\"clear\" color=\"light\" size=\"small\">\n {{ locale + \".buttons.preview\" | translate }}\n </ion-button>\n </div>\n </div>\n </div>\n <div class=\"description dcf-flex dcf-flex-middle dcf-width-expand@s\">\n <div>\n <p class=\"dcf-title\">{{ locale + \".preview\" | translate }}</p>\n <p class=\"subtitle\">{{ files[0].name }}</p>\n <ion-button (click)=\"handleClear()\" fill=\"clear\" color=\"danger\" size=\"small\">{{ locale + \".buttons.clear\" | translate }} </ion-button>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"dcf-margin-bottom\">\n {{ locale + \".selection\" | translate: { \"0\": files.length > 10 ? files.length : `0${files.length}` } }}\n @if(errors.length > 0) {\n <br /><span class=\"dcf-error-message\">{{ locale + \".selection_error\" | translate: { \"0\": errors.length > 10 ? errors.length : `0${errors.length}` } }}</span>\n }\n </div>\n <div class=\"dcf-preview-list-container\">\n <ion-list class=\"dcf-preview-list\">\n @for (file of errors; track $index) {\n <ion-item lines=\"full\" class=\"dcf-error-item\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <div class=\"dcf-error-message\" slot=\"end\">\n {{ locale + \".errors.\" + file.error | translate: { \"0\": file.error === 'max_size' ? maxFileSize / 1024 / 1024 : file.name.split(\".\") } }}\n </div>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n </ion-item>\n }\n\n @for (file of files; track $index) {\n <ion-item lines=\"full\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n <div class=\"dcf-flex dcf-flex-middle\" slot=\"end\">\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n (click)=\"preview(file?.source || file, file.type)\"\n [name]=\"file.type.includes('image') ? 'image-outline' : 'document-text-outline'\"\n />\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n [name]=\"'trash-outline'\"\n (click)=\"removeFile($index)\"\n [color]=\"'danger'\"\n [size]=\"'small'\"\n />\n </div>\n </ion-item>\n }\n </ion-list>\n </div>\n }\n }\n </div>\n </div>\n </div>\n } @else {\n <div class=\"dcf-preview-list-container\">\n <ion-list class=\"dcf-preview-list\">\n @if(files?.length) {\n @for (file of files; track $index) {\n <ion-item lines=\"full\">\n @if(file?.name) {\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n }\n <div class=\"dcf-flex dcf-flex-middle\" slot=\"end\">\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n (click)=\"preview(file.source, file.type)\"\n [name]=\"file.type.includes('image') ? 'image-outline' : 'document-text-outline'\"\n />\n </div>\n </ion-item>\n }\n } @else {\n <div class=\"dcf-padding-xsmall\">\n <ion-text>{{ locale + '.empty' | translate }}</ion-text>\n </div>\n }\n\n </ion-list>\n </div>\n }\n </ngx-decaf-card>\n</div>\n\n<!-- <ion-card-header>\n <ion-card-title>Upload de Imagem</ion-card-title>\n </ion-card-header>\n\n <ion-card-content>\n <div\n class=\"dcf-drop-area\"\n [class.dragging]=\"dragging\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n >\n <div class=\"dcf-drop-content\">\n <ion-icon name=\"cloud-upload-outline\" size=\"large\"></ion-icon>\n <p>Arraste e solte aqui ou</p>\n <ion-button size=\"small\" fill=\"outline\" (click)=\"triggerFileSelect()\">Selecionar arquivo</ion-button>\n </div>\n </div>\n\n <input\n #fileInput\n type=\"file\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"onFileSelected($event)\"\n hidden\n />\n\n <div *ngIf=\"previewUrl\" class=\"dcf-preview\">\n <ion-item>\n <div slot=\"start\">\n <ion-img [src]=\"previewUrl\"></ion-img>\n </div>\n <ion-label>\n <h3>Pr\u00E9-visualiza\u00E7\u00E3o</h3>\n <p *ngIf=\"files.length\">{{ files[0].name }}</p>\n </ion-label>\n </ion-item>\n </div>\n\n <ion-list *ngIf=\"files.length\">\n <ion-list-header>\n <ion-label>Arquivos selecionados</ion-label>\n </ion-list-header>\n <ion-item *ngFor=\"let f of files; let i = index\">\n <ion-label>{{ f.name }}</ion-label>\n <ion-note slot=\"end\">{{ (f.size / 1024 / 1024) | number:'1.1-1' }} MB</ion-note>\n <ion-button fill=\"clear\" slot=\"end\" (click)=\"removeFile(i)\">\n <ion-icon slot=\"icon-only\" name=\"close-circle\"></ion-icon>\n </ion-button>\n </ion-item>\n </ion-list>\n\n <div *ngIf=\"errors.length\">\n <ion-list>\n <ion-item *ngFor=\"let err of errors\">\n <ion-icon name=\"alert-circle\" slot=\"start\" color=\"danger\"></ion-icon>\n <ion-label color=\"danger\">{{ err }}</ion-label>\n </ion-item>\n </ion-list>\n </div>\n\n <ion-row class=\"dcf-actions\">\n <ion-col>\n <ion-button expand=\"block\" (click)=\"triggerFileSelect()\">Selecionar</ion-button>\n </ion-col>\n <ion-col>\n <ion-button expand=\"block\" color=\"danger\" fill=\"outline\" (click)=\"clear()\">Limpar</ion-button>\n </ion-col>\n </ion-row>\n </ion-card-content> -->\n", styles: [".decaf-file-component.dcf-palette-dark .dcf-button-select{--background: rgb(var(--dcf-color-light-rgb), .1) !important;--background-hover: rgb(var(--dcf-color-light-rgb), .75) !important;--background-activated: rgb(var(--dcf-color-light-rgb), .4) !important;--background-focused: rgb(var(--dcf-color-light-rgb), .4) !important;--color: var(--dcf-color-light) !important}.decaf-file-component.dcf-palette-dark .dcf-has-files{border-style:solid;border-color:var(--dcf-color-gray-6)!important}.decaf-file-component .dcf-upload-icon{--box-shadow: none !important}.decaf-file-component .dcf-upload-icon ion-icon{width:1.5rem!important}.decaf-file-component ion-button.dcf-button-select{--background: rgb(var(--dcf-color-primary-rgb), .1);--background-hover: rgb(var(--dcf-color-primary-rgb), .75);--background-activated: rgb(var(--dcf-color-primary-rgb), .4);--background-focused: rgb(var(--dcf-color-primary-rgb), .4);--color: var(--dcf-color-primary-shade);--border-radius: var(--dcf-border-radius-small);--box-shadow: none;--padding-top: var(--dcf-padding-xsmall);--padding-bottom: var(--dcf-padding-xsmall);--padding-start: var(--dcf-padding-small);--padding-end: var(--dcf-padding-small);font-weight:500;text-transform:none;margin-top:var(--dcf-margin-small)!important}.decaf-file-component .dcf-error{color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999;animation-duration:.05s;animation-timing-function:ease-in;animation-fill-mode:both;animation-name:fadeBottomSmallAnimation}.decaf-file-component .dcf-error .ti,.decaf-file-component .dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.decaf-file-component ion-card-content{width:100%}.decaf-file-component .dcf-error-message{color:var(--dcf-color-danger);font-size:.875rem}.decaf-file-component .dcf-drag-description{font-size:1rem;line-height:1.5rem;font-weight:500;margin-bottom:var(--dcf-margin-small)}.decaf-file-component .dcf-drop-area{display:flex;align-items:center;border:1.5px dashed var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-small)!important;transition:border-style .15s ease,border-color .15s ease;background:transparent}.decaf-file-component .dcf-drop-area.dcf-large{min-height:180px}.decaf-file-component .dcf-drop-area>div{width:100%}.decaf-file-component .dcf-drop-area.dcf-has-files{border-style:solid;border-color:var(--dcf-color-primary-shade);transition:border-style .15s ease,border-color .15s ease;padding:var(--dcf-spacement) var(--dcf-spacement-small)!important}.decaf-file-component .dcf-drop-area:not(.dcf-has-files){border-style:dashed;padding:var(--dcf-spacement) var(--dcf-spacement-medium)}.decaf-file-component .dcf-drop-area.dcf-dragging{background:#00000008;border-color:var(--ion-color-primary);box-shadow:0 2px 8px #0000000f}.decaf-file-component .dcf-preview .dcf-preview-image{border:1px solid var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-xsmall);max-width:320px;padding:.5rem;box-sizing:border-box;height:160px;position:relative;cursor:pointer;overflow:hidden}.decaf-file-component .dcf-preview .dcf-preview-image ion-img{height:140px!important;display:block;width:100%}.decaf-file-component .dcf-preview .dcf-preview-image:hover .dcf-overlay{opacity:1}.decaf-file-component .dcf-preview .dcf-preview-image .dcf-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:#0009;display:flex;justify-content:center;align-items:center;opacity:0;transition:opacity .3s ease}.decaf-file-component .dcf-preview .description{text-align:left;padding:1rem;font-size:.75rem}.decaf-file-component .dcf-preview .description .dcf-title{font-size:1rem;font-weight:500}.decaf-file-component .dcf-preview .description ion-button{margin-top:var(--dcf-margin-small)!important}.decaf-file-component .dcf-preview-list-container{max-height:150px;overflow-y:auto}.decaf-file-component .dcf-preview-list-container ion-list{padding:0!important;margin:0!important}@media (max-width: 767px){.decaf-file-component .dcf-preview-list-container ion-list{width:100%;min-width:576px;overflow-x:auto}}.decaf-file-component .dcf-preview-list-container:not(:hover){scrollbar-color:rgba(var(--dcf-color-medium-rgb),.125) transparent!important}.decaf-file-component .dcf-preview-list-container ion-item{font-size:.875rem!important}.decaf-file-component .dcf-preview-list-container ion-item.dcf-error-item{--background: rgba(var(--dcf-color-danger-rgb), .02) !important;--border-color: rgba(var(--dcf-color-danger-rgb), .2) !important}.decaf-file-component .dcf-preview-list-container ion-item ion-item{--padding-top: .25rem;--padding-bottom: 0rem;--inner-padding-start: 0rem;--padding-start: var(--dcf-padding-xsmall) !important;--padding-end: 0rem;--inner-padding-end: var(--dcf-padding-xsmall) !important;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8);--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: CardComponent, selector: "ngx-decaf-card", inputs: ["type", "title", "body", "subtitle", "color", "separator", "borders", "inlineContent", "inlineContentPosition"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "pipe", type: i1$1.DecimalPipe, name: "number" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
11607
11855
  };
11608
11856
  FileUploadComponent = __decorate([
11609
11857
  Dynamic(),
@@ -11611,7 +11859,7 @@ FileUploadComponent = __decorate([
11611
11859
  ], FileUploadComponent);
11612
11860
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FileUploadComponent, decorators: [{
11613
11861
  type: Component,
11614
- args: [{ selector: 'ngx-decaf-file-upload', standalone: true, imports: [CommonModule, ReactiveFormsModule, CardComponent, IconComponent, IonList, IonLabel, IonItem, TranslatePipe, IonButton], template: "<div class=\"decaf-file-component\" #component>\n <input\n id=\"dcf-file-input\"\n type=\"file\"\n placeholder=\"Select files\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"handleSelection($event)\"\n [multiple]=\"multiple\"\n hidden\n [attr.webkitdirectory]=\"enableDirectoryMode ? true : null\"\n />\n\n <ngx-decaf-card [className]=\"className\" [body]=\"'blank'\">\n <div>\n <div\n [class]=\"\n 'dcf-drop-area '\n + ' dcf-' + size\n + ' dcf-flex dcf-flex-' + position\n + ' dcf-text-' + position\n \"\n\n [class.dcf-dragging]=\"dragging\"\n [class.dcf-has-files]=\"files.length\"\n (drop)=\"!files?.length ? handleDrop($event) : dragging = false\"\n (dragover)=\"!files?.length ? handleDragOver($event) : dragging = false\"\n (dragleave)=\"!files?.length ? handleDragLeave($event) : dragging = false\"\n >\n <div>\n @if (!preview) {\n @if(showIcon) {\n <ngx-decaf-icon name=\"cloud-upload-outline\" size=\"large\" />\n }\n <p class=\"dcf-drag-description\">{{ label ? (label | translate) : (locale + \".drag_file\" | translate) }}</p>\n <ion-button class=\"dcf-button-select\" (click)=\"handleClickToSelect()\" size=\"small\">\n {{ buttonLabel ? (buttonLabel | translate) : (locale + \".buttons.select\" | translate) }}\n </ion-button>\n <div #container>\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n } @else {\n @if ((!directoryMode && !multiple) ) {\n <div class=\"dcf-preview dcf-grid dcf-grid-match dcf-grid-collapse\">\n <div class=\"dcf-width-1-4@m dcf-width-1-3@s dcf-flex dcf-flex-center dcf-flex-middle\">\n <div class=\"dcf-preview-image\">\n <ion-img\n [src]=\"preview\"\n [title]=\"locale + '.preview' | translate\"\n [alt]=\"locale + '.preview' | translate\"\n />\n <div class=\"dcf-overlay\">\n <ion-button (click)=\"showFilePreview(preview)\" fill=\"clear\" color=\"light\" size=\"small\">\n {{ locale + \".buttons.preview\" | translate }}\n </ion-button>\n </div>\n </div>\n </div>\n <div class=\"description dcf-flex dcf-flex-middle dcf-width-expand@s\">\n <div>\n <p class=\"dcf-title\">{{ locale + \".preview\" | translate }}</p>\n <p class=\"subtitle\">{{ files[0].name }}</p>\n <ion-button (click)=\"handleClear()\" fill=\"clear\" color=\"danger\" size=\"small\">{{ locale + \".buttons.clear\" | translate }} </ion-button>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"dcf-margin-bottom\">\n {{ locale + \".selection\" | translate: { \"0\": files.length > 10 ? files.length : `0${files.length}` } }}\n @if(errors.length > 0) {\n <br /><span class=\"dcf-error-message\">{{ locale + \".selection_error\" | translate: { \"0\": errors.length > 10 ? errors.length : `0${errors.length}` } }}</span>\n }\n </div>\n <div class=\"dcf-preview-list-container\">\n <ion-list class=\"dcf-preview-list\">\n @for (file of errors; track $index) {\n <ion-item lines=\"full\" class=\"dcf-error-item\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <div class=\"dcf-error-message\" slot=\"end\">\n {{ locale + \".errors.\" + file.error | translate: { \"0\": file.error === 'max_size' ? maxFileSize / 1024 / 1024 : file.name.split(\".\") } }}\n </div>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n </ion-item>\n }\n\n @for (file of files; track $index) {\n <ion-item lines=\"full\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n <div class=\"dcf-flex dcf-flex-middle\" slot=\"end\">\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n (click)=\"showFilePreview(file, file.type)\"\n [name]=\"'image-outline'\"\n />\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n [name]=\"'trash-outline'\"\n (click)=\"removeFile($index)\"\n [color]=\"'danger'\"\n [size]=\"'small'\"\n />\n </div>\n </ion-item>\n }\n </ion-list>\n </div>\n }\n }\n </div>\n\n\n </div>\n </div>\n </ngx-decaf-card>\n</div>\n\n<!-- <ion-card-header>\n <ion-card-title>Upload de Imagem</ion-card-title>\n </ion-card-header>\n\n <ion-card-content>\n <div\n class=\"dcf-drop-area\"\n [class.dragging]=\"dragging\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n >\n <div class=\"dcf-drop-content\">\n <ion-icon name=\"cloud-upload-outline\" size=\"large\"></ion-icon>\n <p>Arraste e solte aqui ou</p>\n <ion-button size=\"small\" fill=\"outline\" (click)=\"triggerFileSelect()\">Selecionar arquivo</ion-button>\n </div>\n </div>\n\n <input\n #fileInput\n type=\"file\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"onFileSelected($event)\"\n hidden\n />\n\n <div *ngIf=\"previewUrl\" class=\"dcf-preview\">\n <ion-item>\n <div slot=\"start\">\n <ion-img [src]=\"previewUrl\"></ion-img>\n </div>\n <ion-label>\n <h3>Pr\u00E9-visualiza\u00E7\u00E3o</h3>\n <p *ngIf=\"files.length\">{{ files[0].name }}</p>\n </ion-label>\n </ion-item>\n </div>\n\n <ion-list *ngIf=\"files.length\">\n <ion-list-header>\n <ion-label>Arquivos selecionados</ion-label>\n </ion-list-header>\n <ion-item *ngFor=\"let f of files; let i = index\">\n <ion-label>{{ f.name }}</ion-label>\n <ion-note slot=\"end\">{{ (f.size / 1024 / 1024) | number:'1.1-1' }} MB</ion-note>\n <ion-button fill=\"clear\" slot=\"end\" (click)=\"removeFile(i)\">\n <ion-icon slot=\"icon-only\" name=\"close-circle\"></ion-icon>\n </ion-button>\n </ion-item>\n </ion-list>\n\n <div *ngIf=\"errors.length\">\n <ion-list>\n <ion-item *ngFor=\"let err of errors\">\n <ion-icon name=\"alert-circle\" slot=\"start\" color=\"danger\"></ion-icon>\n <ion-label color=\"danger\">{{ err }}</ion-label>\n </ion-item>\n </ion-list>\n </div>\n\n <ion-row class=\"dcf-actions\">\n <ion-col>\n <ion-button expand=\"block\" (click)=\"triggerFileSelect()\">Selecionar</ion-button>\n </ion-col>\n <ion-col>\n <ion-button expand=\"block\" color=\"danger\" fill=\"outline\" (click)=\"clear()\">Limpar</ion-button>\n </ion-col>\n </ion-row>\n </ion-card-content> -->\n", styles: [".decaf-file-component.dcf-palette-dark .dcf-button-select{--background: rgb(var(--dcf-color-light-rgb), .1) !important;--background-hover: rgb(var(--dcf-color-light-rgb), .75) !important;--background-activated: rgb(var(--dcf-color-light-rgb), .4) !important;--background-focused: rgb(var(--dcf-color-light-rgb), .4) !important;--color: var(--dcf-color-light) !important}.decaf-file-component.dcf-palette-dark .dcf-has-files{border-style:solid;border-color:var(--dcf-color-gray-6)!important}.decaf-file-component .dcf-upload-icon{--box-shadow: none !important}.decaf-file-component .dcf-upload-icon ion-icon{width:1.5rem!important}.decaf-file-component ion-button.dcf-button-select{--background: rgb(var(--dcf-color-primary-rgb), .1);--background-hover: rgb(var(--dcf-color-primary-rgb), .75);--background-activated: rgb(var(--dcf-color-primary-rgb), .4);--background-focused: rgb(var(--dcf-color-primary-rgb), .4);--color: var(--dcf-color-primary-shade);--border-radius: var(--dcf-border-radius-small);--box-shadow: none;--padding-top: var(--dcf-padding-xsmall);--padding-bottom: var(--dcf-padding-xsmall);--padding-start: var(--dcf-padding-small);--padding-end: var(--dcf-padding-small);font-weight:500;text-transform:none;margin-top:var(--dcf-margin-small)!important}.decaf-file-component .dcf-error{color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999;animation-duration:.05s;animation-timing-function:ease-in;animation-fill-mode:both;animation-name:fadeBottomSmallAnimation}.decaf-file-component .dcf-error .ti,.decaf-file-component .dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.decaf-file-component ion-card-content{width:100%}.decaf-file-component .dcf-error-message{color:var(--dcf-color-danger);font-size:.875rem}.decaf-file-component .dcf-drag-description{font-size:1rem;line-height:1.5rem;font-weight:500;margin-bottom:var(--dcf-margin-small)}.decaf-file-component .dcf-drop-area{display:flex;align-items:center;border:1.5px dashed var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-small)!important;transition:border-style .15s ease,border-color .15s ease;background:transparent}.decaf-file-component .dcf-drop-area.dcf-large{min-height:180px}.decaf-file-component .dcf-drop-area>div{width:100%}.decaf-file-component .dcf-drop-area.dcf-has-files{border-style:solid;border-color:var(--dcf-color-primary-shade);transition:border-style .15s ease,border-color .15s ease;padding:var(--dcf-spacement) var(--dcf-spacement-small)!important}.decaf-file-component .dcf-drop-area:not(.dcf-has-files){border-style:dashed;padding:var(--dcf-spacement) var(--dcf-spacement-medium)}.decaf-file-component .dcf-drop-area.dcf-dragging{background:#00000008;border-color:var(--ion-color-primary);box-shadow:0 2px 8px #0000000f}.decaf-file-component .dcf-preview .dcf-preview-image{border:1px solid var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-xsmall);max-width:320px;padding:.5rem;box-sizing:border-box;height:160px;position:relative;cursor:pointer;overflow:hidden}.decaf-file-component .dcf-preview .dcf-preview-image ion-img{height:140px!important;display:block;width:100%}.decaf-file-component .dcf-preview .dcf-preview-image:hover .dcf-overlay{opacity:1}.decaf-file-component .dcf-preview .dcf-preview-image .dcf-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:#0009;display:flex;justify-content:center;align-items:center;opacity:0;transition:opacity .3s ease}.decaf-file-component .dcf-preview .description{text-align:left;padding:1rem;font-size:.75rem}.decaf-file-component .dcf-preview .description .dcf-title{font-size:1rem;font-weight:500}.decaf-file-component .dcf-preview .description ion-button{margin-top:var(--dcf-margin-small)!important}.decaf-file-component .dcf-preview-list-container{max-height:150px;overflow-y:auto}.decaf-file-component .dcf-preview-list-container ion-list{padding:0!important;margin:0!important}@media (max-width: 767px){.decaf-file-component .dcf-preview-list-container ion-list{width:100%;min-width:576px;overflow-x:auto}}.decaf-file-component .dcf-preview-list-container:not(:hover){scrollbar-color:rgba(var(--dcf-color-medium-rgb),.125) transparent!important}.decaf-file-component .dcf-preview-list-container ion-item{font-size:.875rem!important}.decaf-file-component .dcf-preview-list-container ion-item.dcf-error-item{--background: rgba(var(--dcf-color-danger-rgb), .02) !important;--border-color: rgba(var(--dcf-color-danger-rgb), .2) !important}.decaf-file-component .dcf-preview-list-container ion-item ion-item{--padding-top: .25rem;--padding-bottom: 0rem;--inner-padding-start: 0rem;--padding-start: var(--dcf-padding-xsmall) !important;--padding-end: 0rem;--inner-padding-end: var(--dcf-padding-xsmall) !important;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8);--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}\n"] }]
11862
+ args: [{ selector: 'ngx-decaf-file-upload', standalone: true, imports: [CommonModule, ReactiveFormsModule, CardComponent, IonText, IconComponent, IonList, IonLabel, IonItem, TranslatePipe, IonButton], template: "<div class=\"decaf-file-component\" #component>\n <input\n id=\"dcf-file-input\"\n type=\"file\"\n placeholder=\"Select files\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"handleSelection($event)\"\n [multiple]=\"multiple\"\n hidden\n [attr.webkitdirectory]=\"enableDirectoryMode ? true : null\"\n />\n\n <ngx-decaf-card [className]=\"className\" [body]=\"'blank'\">\n @if(['create', 'update'].includes(operation)) {\n <div>\n <div\n [class]=\"\n 'dcf-drop-area '\n + ' dcf-' + size\n + ' dcf-flex dcf-flex-' + position\n + ' dcf-text-' + position\n \"\n\n [class.dcf-dragging]=\"dragging\"\n [class.dcf-has-files]=\"files.length\"\n (drop)=\"!files?.length ? handleDrop($event) : dragging = false\"\n (dragover)=\"!files?.length ? handleDragOver($event) : dragging = false\"\n (dragleave)=\"!files?.length ? handleDragLeave($event) : dragging = false\"\n >\n <div>\n @if (!previewFile) {\n @if(showIcon) {\n <ngx-decaf-icon name=\"cloud-upload-outline\" size=\"large\" />\n }\n <p class=\"dcf-drag-description\">{{ label ? (label | translate) : (locale + \".drag_file\" | translate) }}</p>\n <ion-button class=\"dcf-button-select\" (click)=\"handleClickToSelect()\" size=\"small\">\n {{ buttonLabel ? (buttonLabel | translate) : (locale + \".buttons.select\" | translate) }}\n </ion-button>\n <div #container>\n <span class=\"dcf-error\" [innerHTML]=\"getErrors(container)\"></span>\n </div>\n } @else {\n @if ((!directoryMode && !multiple) ) {\n <div class=\"dcf-preview dcf-grid dcf-grid-match dcf-grid-collapse\">\n <div class=\"dcf-width-1-4@m dcf-width-1-3@s dcf-flex dcf-flex-center dcf-flex-middle\">\n <div class=\"dcf-preview-image\">\n <ion-img\n [src]=\"previewFile\"\n [title]=\"locale + '.preview' | translate\"\n [alt]=\"locale + '.preview' | translate\"\n />\n <div class=\"dcf-overlay\">\n <ion-button (click)=\"preview(previewFile)\" fill=\"clear\" color=\"light\" size=\"small\">\n {{ locale + \".buttons.preview\" | translate }}\n </ion-button>\n </div>\n </div>\n </div>\n <div class=\"description dcf-flex dcf-flex-middle dcf-width-expand@s\">\n <div>\n <p class=\"dcf-title\">{{ locale + \".preview\" | translate }}</p>\n <p class=\"subtitle\">{{ files[0].name }}</p>\n <ion-button (click)=\"handleClear()\" fill=\"clear\" color=\"danger\" size=\"small\">{{ locale + \".buttons.clear\" | translate }} </ion-button>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"dcf-margin-bottom\">\n {{ locale + \".selection\" | translate: { \"0\": files.length > 10 ? files.length : `0${files.length}` } }}\n @if(errors.length > 0) {\n <br /><span class=\"dcf-error-message\">{{ locale + \".selection_error\" | translate: { \"0\": errors.length > 10 ? errors.length : `0${errors.length}` } }}</span>\n }\n </div>\n <div class=\"dcf-preview-list-container\">\n <ion-list class=\"dcf-preview-list\">\n @for (file of errors; track $index) {\n <ion-item lines=\"full\" class=\"dcf-error-item\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <div class=\"dcf-error-message\" slot=\"end\">\n {{ locale + \".errors.\" + file.error | translate: { \"0\": file.error === 'max_size' ? maxFileSize / 1024 / 1024 : file.name.split(\".\") } }}\n </div>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n </ion-item>\n }\n\n @for (file of files; track $index) {\n <ion-item lines=\"full\">\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n <ion-note slot=\"end\">{{ file.size / 1024 / 1024 | number: \"1.1-1\" }} MB</ion-note>\n <div class=\"dcf-flex dcf-flex-middle\" slot=\"end\">\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n (click)=\"preview(file?.source || file, file.type)\"\n [name]=\"file.type.includes('image') ? 'image-outline' : 'document-text-outline'\"\n />\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n [name]=\"'trash-outline'\"\n (click)=\"removeFile($index)\"\n [color]=\"'danger'\"\n [size]=\"'small'\"\n />\n </div>\n </ion-item>\n }\n </ion-list>\n </div>\n }\n }\n </div>\n </div>\n </div>\n } @else {\n <div class=\"dcf-preview-list-container\">\n <ion-list class=\"dcf-preview-list\">\n @if(files?.length) {\n @for (file of files; track $index) {\n <ion-item lines=\"full\">\n @if(file?.name) {\n <ion-label slot=\"start\">{{ file.name }}</ion-label>\n }\n <div class=\"dcf-flex dcf-flex-middle\" slot=\"end\">\n <ngx-decaf-icon\n [button]=\"true\"\n [slot]=\"'icon-only'\"\n (click)=\"preview(file.source, file.type)\"\n [name]=\"file.type.includes('image') ? 'image-outline' : 'document-text-outline'\"\n />\n </div>\n </ion-item>\n }\n } @else {\n <div class=\"dcf-padding-xsmall\">\n <ion-text>{{ locale + '.empty' | translate }}</ion-text>\n </div>\n }\n\n </ion-list>\n </div>\n }\n </ngx-decaf-card>\n</div>\n\n<!-- <ion-card-header>\n <ion-card-title>Upload de Imagem</ion-card-title>\n </ion-card-header>\n\n <ion-card-content>\n <div\n class=\"dcf-drop-area\"\n [class.dragging]=\"dragging\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n >\n <div class=\"dcf-drop-content\">\n <ion-icon name=\"cloud-upload-outline\" size=\"large\"></ion-icon>\n <p>Arraste e solte aqui ou</p>\n <ion-button size=\"small\" fill=\"outline\" (click)=\"triggerFileSelect()\">Selecionar arquivo</ion-button>\n </div>\n </div>\n\n <input\n #fileInput\n type=\"file\"\n [attr.accept]=\"accept\"\n [attr.multiple]=\"multiple ? true : null\"\n (change)=\"onFileSelected($event)\"\n hidden\n />\n\n <div *ngIf=\"previewUrl\" class=\"dcf-preview\">\n <ion-item>\n <div slot=\"start\">\n <ion-img [src]=\"previewUrl\"></ion-img>\n </div>\n <ion-label>\n <h3>Pr\u00E9-visualiza\u00E7\u00E3o</h3>\n <p *ngIf=\"files.length\">{{ files[0].name }}</p>\n </ion-label>\n </ion-item>\n </div>\n\n <ion-list *ngIf=\"files.length\">\n <ion-list-header>\n <ion-label>Arquivos selecionados</ion-label>\n </ion-list-header>\n <ion-item *ngFor=\"let f of files; let i = index\">\n <ion-label>{{ f.name }}</ion-label>\n <ion-note slot=\"end\">{{ (f.size / 1024 / 1024) | number:'1.1-1' }} MB</ion-note>\n <ion-button fill=\"clear\" slot=\"end\" (click)=\"removeFile(i)\">\n <ion-icon slot=\"icon-only\" name=\"close-circle\"></ion-icon>\n </ion-button>\n </ion-item>\n </ion-list>\n\n <div *ngIf=\"errors.length\">\n <ion-list>\n <ion-item *ngFor=\"let err of errors\">\n <ion-icon name=\"alert-circle\" slot=\"start\" color=\"danger\"></ion-icon>\n <ion-label color=\"danger\">{{ err }}</ion-label>\n </ion-item>\n </ion-list>\n </div>\n\n <ion-row class=\"dcf-actions\">\n <ion-col>\n <ion-button expand=\"block\" (click)=\"triggerFileSelect()\">Selecionar</ion-button>\n </ion-col>\n <ion-col>\n <ion-button expand=\"block\" color=\"danger\" fill=\"outline\" (click)=\"clear()\">Limpar</ion-button>\n </ion-col>\n </ion-row>\n </ion-card-content> -->\n", styles: [".decaf-file-component.dcf-palette-dark .dcf-button-select{--background: rgb(var(--dcf-color-light-rgb), .1) !important;--background-hover: rgb(var(--dcf-color-light-rgb), .75) !important;--background-activated: rgb(var(--dcf-color-light-rgb), .4) !important;--background-focused: rgb(var(--dcf-color-light-rgb), .4) !important;--color: var(--dcf-color-light) !important}.decaf-file-component.dcf-palette-dark .dcf-has-files{border-style:solid;border-color:var(--dcf-color-gray-6)!important}.decaf-file-component .dcf-upload-icon{--box-shadow: none !important}.decaf-file-component .dcf-upload-icon ion-icon{width:1.5rem!important}.decaf-file-component ion-button.dcf-button-select{--background: rgb(var(--dcf-color-primary-rgb), .1);--background-hover: rgb(var(--dcf-color-primary-rgb), .75);--background-activated: rgb(var(--dcf-color-primary-rgb), .4);--background-focused: rgb(var(--dcf-color-primary-rgb), .4);--color: var(--dcf-color-primary-shade);--border-radius: var(--dcf-border-radius-small);--box-shadow: none;--padding-top: var(--dcf-padding-xsmall);--padding-bottom: var(--dcf-padding-xsmall);--padding-start: var(--dcf-padding-small);--padding-end: var(--dcf-padding-small);font-weight:500;text-transform:none;margin-top:var(--dcf-margin-small)!important}.decaf-file-component .dcf-error{color:var(--dcf-color-danger)!important;font-size:.8rem!important;font-weight:500!important;line-height:1.1rem;z-index:9999;animation-duration:.05s;animation-timing-function:ease-in;animation-fill-mode:both;animation-name:fadeBottomSmallAnimation}.decaf-file-component .dcf-error .ti,.decaf-file-component .dcf-error ion-icon{position:relative;top:2px!important;min-width:20px;font-size:1rem!important;text-align:left}.decaf-file-component ion-card-content{width:100%}.decaf-file-component .dcf-error-message{color:var(--dcf-color-danger);font-size:.875rem}.decaf-file-component .dcf-drag-description{font-size:1rem;line-height:1.5rem;font-weight:500;margin-bottom:var(--dcf-margin-small)}.decaf-file-component .dcf-drop-area{display:flex;align-items:center;border:1.5px dashed var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-small)!important;transition:border-style .15s ease,border-color .15s ease;background:transparent}.decaf-file-component .dcf-drop-area.dcf-large{min-height:180px}.decaf-file-component .dcf-drop-area>div{width:100%}.decaf-file-component .dcf-drop-area.dcf-has-files{border-style:solid;border-color:var(--dcf-color-primary-shade);transition:border-style .15s ease,border-color .15s ease;padding:var(--dcf-spacement) var(--dcf-spacement-small)!important}.decaf-file-component .dcf-drop-area:not(.dcf-has-files){border-style:dashed;padding:var(--dcf-spacement) var(--dcf-spacement-medium)}.decaf-file-component .dcf-drop-area.dcf-dragging{background:#00000008;border-color:var(--ion-color-primary);box-shadow:0 2px 8px #0000000f}.decaf-file-component .dcf-preview .dcf-preview-image{border:1px solid var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-xsmall);max-width:320px;padding:.5rem;box-sizing:border-box;height:160px;position:relative;cursor:pointer;overflow:hidden}.decaf-file-component .dcf-preview .dcf-preview-image ion-img{height:140px!important;display:block;width:100%}.decaf-file-component .dcf-preview .dcf-preview-image:hover .dcf-overlay{opacity:1}.decaf-file-component .dcf-preview .dcf-preview-image .dcf-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:#0009;display:flex;justify-content:center;align-items:center;opacity:0;transition:opacity .3s ease}.decaf-file-component .dcf-preview .description{text-align:left;padding:1rem;font-size:.75rem}.decaf-file-component .dcf-preview .description .dcf-title{font-size:1rem;font-weight:500}.decaf-file-component .dcf-preview .description ion-button{margin-top:var(--dcf-margin-small)!important}.decaf-file-component .dcf-preview-list-container{max-height:150px;overflow-y:auto}.decaf-file-component .dcf-preview-list-container ion-list{padding:0!important;margin:0!important}@media (max-width: 767px){.decaf-file-component .dcf-preview-list-container ion-list{width:100%;min-width:576px;overflow-x:auto}}.decaf-file-component .dcf-preview-list-container:not(:hover){scrollbar-color:rgba(var(--dcf-color-medium-rgb),.125) transparent!important}.decaf-file-component .dcf-preview-list-container ion-item{font-size:.875rem!important}.decaf-file-component .dcf-preview-list-container ion-item.dcf-error-item{--background: rgba(var(--dcf-color-danger-rgb), .02) !important;--border-color: rgba(var(--dcf-color-danger-rgb), .2) !important}.decaf-file-component .dcf-preview-list-container ion-item ion-item{--padding-top: .25rem;--padding-bottom: 0rem;--inner-padding-start: 0rem;--padding-start: var(--dcf-padding-xsmall) !important;--padding-end: 0rem;--inner-padding-end: var(--dcf-padding-xsmall) !important;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8);--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}\n"] }]
11615
11863
  }], ctorParameters: () => [], propDecorators: { component: [{
11616
11864
  type: ViewChild,
11617
11865
  args: ['component', { static: true }]
@@ -11641,6 +11889,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
11641
11889
  type: Input
11642
11890
  }], enableDirectoryMode: [{
11643
11891
  type: Input
11892
+ }], previewHandler: [{
11893
+ type: Input
11644
11894
  }], maxFileSize: [{
11645
11895
  type: Input
11646
11896
  }], changeEvent: [{
@@ -11771,15 +12021,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
11771
12021
  class DynamicModule {
11772
12022
  }
11773
12023
 
11774
- /**
11775
- * @module module:lib/engine/NgxEventHandler
11776
- * @description Event handler base class used by Decaf components.
11777
- * @summary Defines NgxEventHandler which standardizes event handling logic and provides
11778
- * logging support for handlers that process custom events emitted by components.
11779
- *
11780
- * @link {@link NgxEventHandler}
11781
- */
11782
- class NgxEventHandler extends LoggedClass {
12024
+ class NgxEventHandler extends DecafEventHandler {
12025
+ // eslint-disable-next-line @typescript-eslint/no-useless-constructor
12026
+ constructor() {
12027
+ super();
12028
+ }
12029
+ async refresh(args) {
12030
+ this.log.for(this.refresh).debug(`Refresh called with args: ${args}`);
12031
+ }
12032
+ async preview(args) {
12033
+ this.log.for(this.refresh).debug(`Refresh called with args: ${args}`);
12034
+ }
11783
12035
  }
11784
12036
 
11785
12037
  /**
@@ -11869,7 +12121,6 @@ class NgxPageDirective extends NgxComponentDirective {
11869
12121
  this.hasMenu = true;
11870
12122
  this.hasMenu = hasMenu;
11871
12123
  // subscribe to media service color scheme changes
11872
- this.mediaService.colorScheme$.subscribe();
11873
12124
  }
11874
12125
  get pageTitle() {
11875
12126
  if (this.title)
@@ -11885,7 +12136,6 @@ class NgxPageDirective extends NgxComponentDirective {
11885
12136
  this.mediaService.colorSchemeObserver(this.component);
11886
12137
  this.currentRoute = this.router.url.replace('/', '');
11887
12138
  this.setPageTitle(this.currentRoute);
11888
- this.initialized = true;
11889
12139
  }
11890
12140
  /**
11891
12141
  * @description Ionic lifecycle hook called when the page is about to enter view.
@@ -11975,17 +12225,20 @@ class NgxModelPageDirective extends NgxPageDirective {
11975
12225
  * @default [OperationKeys.CREATE, OperationKeys.READ]
11976
12226
  * @memberOf ModelPage
11977
12227
  */
11978
- this.allowedOperations = [OperationKeys.CREATE, OperationKeys.READ];
11979
- /**
11980
- * @description Current model data loaded from the repository.
11981
- * @summary Stores the raw data object representing the current model instance retrieved
11982
- * from the repository. This property holds the actual data values for the model being
11983
- * displayed or edited, and is set to undefined when no data is available or when an
11984
- * error occurs during data loading.
11985
- * @type {KeyValue | undefined}
11986
- * @default undefined
11987
- * @memberOf NgxModelPageDirective
11988
- */
12228
+ this.allowedOperations = [
12229
+ OperationKeys.CREATE,
12230
+ OperationKeys.READ,
12231
+ ];
12232
+ /**
12233
+ * @description Current model data loaded from the repository.
12234
+ * @summary Stores the raw data object representing the current model instance retrieved
12235
+ * from the repository. This property holds the actual data values for the model being
12236
+ * displayed or edited, and is set to undefined when no data is available or when an
12237
+ * error occurs during data loading.
12238
+ * @type {KeyValue | undefined}
12239
+ * @default undefined
12240
+ * @memberOf NgxModelPageDirective
12241
+ */
11989
12242
  this.modelData = undefined;
11990
12243
  /**
11991
12244
  * @description Error message from failed operations.
@@ -12003,12 +12256,12 @@ class NgxModelPageDirective extends NgxPageDirective {
12003
12256
  // }
12004
12257
  get pageTitle() {
12005
12258
  if (!this.modelName && this.model instanceof Model)
12006
- this.modelName = this.model?.constructor?.name || "";
12259
+ this.modelName = this.model?.constructor?.name || '';
12007
12260
  if (!this.operation)
12008
12261
  return this.title ? this.title : `Listing ${this.modelName}`;
12009
- const operation = this.operation.charAt(0).toUpperCase() + this.operation.slice(1).toLowerCase();
12010
- return this.modelName ?
12011
- `${operation} ${this.modelName}` : this.title;
12262
+ const operation = this.operation.charAt(0).toUpperCase() +
12263
+ this.operation.slice(1).toLowerCase();
12264
+ return this.modelName ? `${operation} ${this.modelName}` : this.title;
12012
12265
  }
12013
12266
  /**
12014
12267
  * @description Lazy-initialized repository getter with model resolution.
@@ -12029,7 +12282,7 @@ class NgxModelPageDirective extends NgxPageDirective {
12029
12282
  throw new InternalError('Cannot find model. was it registered with @model?');
12030
12283
  this._repository = Repository.forModel(constructor);
12031
12284
  if (!this.pk)
12032
- this.pk = this._repository.pk;
12285
+ this.pk = Model.pk(constructor);
12033
12286
  this.model = new constructor();
12034
12287
  }
12035
12288
  }
@@ -12049,7 +12302,10 @@ class NgxModelPageDirective extends NgxPageDirective {
12049
12302
  async ionViewWillEnter() {
12050
12303
  // await super.ionViewWillEnter();
12051
12304
  if (this.modelId)
12052
- this.allowedOperations = this.allowedOperations.concat([OperationKeys.UPDATE, OperationKeys.DELETE]);
12305
+ this.allowedOperations = this.allowedOperations.concat([
12306
+ OperationKeys.UPDATE,
12307
+ OperationKeys.DELETE,
12308
+ ]);
12053
12309
  this.getLocale(this.modelName);
12054
12310
  await this.refresh(this.modelId);
12055
12311
  this.initialized = true;
@@ -12066,29 +12322,37 @@ class NgxModelPageDirective extends NgxPageDirective {
12066
12322
  async refresh(uid) {
12067
12323
  if (!uid)
12068
12324
  uid = this.modelId;
12069
- this._repository = this.repository;
12070
- switch (this.operation) {
12071
- case OperationKeys.READ:
12072
- case OperationKeys.UPDATE:
12073
- case OperationKeys.DELETE:
12074
- this.model = await this.handleGet(uid || this.modelId, this._repository, this.modelName);
12075
- break;
12325
+ try {
12326
+ this._repository = this.repository;
12327
+ switch (this.operation) {
12328
+ case OperationKeys.READ:
12329
+ case OperationKeys.UPDATE:
12330
+ case OperationKeys.DELETE:
12331
+ this.model = (await this.handleGet(uid || this.modelId));
12332
+ break;
12333
+ }
12334
+ }
12335
+ catch (error) {
12336
+ if (error instanceof NotFoundError) {
12337
+ this.errorMessage = error.message;
12338
+ }
12339
+ this.log.error(error);
12076
12340
  }
12077
12341
  }
12078
12342
  /**
12079
12343
  * @description Generic event handler for component events.
12080
12344
  * @summary Processes incoming events from child components and routes them to appropriate
12081
12345
  * handlers based on the event name. Currently handles SUBMIT events by delegating to
12082
- * the handleSubmit method. This centralized event handling approach allows for easy
12346
+ * the submit method. This centralized event handling approach allows for easy
12083
12347
  * extension and consistent event processing.
12084
12348
  *
12085
12349
  * @param {IBaseCustomEvent} event - The event object containing event data and metadata
12086
12350
  */
12087
- async handleEvent(event) {
12351
+ async handleEvent(event, repository) {
12088
12352
  const { name } = event;
12089
12353
  switch (name) {
12090
12354
  case ComponentEventNames.SUBMIT:
12091
- await this.handleSubmit(event);
12355
+ await this.submit(event, repository);
12092
12356
  break;
12093
12357
  }
12094
12358
  }
@@ -12103,35 +12367,54 @@ class NgxModelPageDirective extends NgxPageDirective {
12103
12367
  * @param {IBaseCustomEvent} event - The submit event containing form data
12104
12368
  * @return {Promise<IModelPageCustomEvent|void>} Promise that resolves on success or throws on error
12105
12369
  */
12106
- async handleSubmit(event, redirect = false) {
12370
+ async submit(event, repository, redirect = false) {
12107
12371
  try {
12108
- const repo = this._repository;
12109
- const operation = this.operation === OperationKeys.READ ? 'delete' : this.operation.toLowerCase();
12110
- const data = this.parseData(event.data, operation);
12111
- const result = this.operation === OperationKeys.CREATE ?
12112
- await repo.create(data) : this.operation === OperationKeys.UPDATE ?
12113
- await repo.update(data) : repo.delete(data);
12114
- const message = await this.translate(`operations.${operation}.${result ? 'success' : 'error'}`, {
12115
- "0": this.pk,
12116
- "1": this.modelId || result[this.pk],
12117
- });
12118
- if (result) {
12119
- repo.refresh(this.modelName, this.operation, this.modelId);
12120
- if (redirect)
12121
- this.location.back();
12372
+ if (!repository)
12373
+ repository = this._repository;
12374
+ // const pk = this.pk || Model.pk(repository.class as Constructor<Model>);
12375
+ const operation = this.operation;
12376
+ const { data } = event;
12377
+ if (data) {
12378
+ const model = this.parseData(data || {}, operation, repository);
12379
+ let result;
12380
+ switch (operation) {
12381
+ case OperationKeys.CREATE:
12382
+ result = await (!Array.isArray(model)
12383
+ ? repository.create(model)
12384
+ : repository.createAll(model));
12385
+ break;
12386
+ case OperationKeys.UPDATE:
12387
+ result = await (!Array.isArray(model)
12388
+ ? repository.update(model)
12389
+ : repository.updateAll(model));
12390
+ break;
12391
+ case OperationKeys.DELETE:
12392
+ result = await (!Array.isArray(model)
12393
+ ? repository.delete(model)
12394
+ : repository.deleteAll(model));
12395
+ break;
12396
+ }
12397
+ const message = await this.translate(!Array.isArray(result)
12398
+ ? `operations.${operation}.${result ? 'success' : 'error'}`
12399
+ : `operations.multiple`);
12400
+ if (result) {
12401
+ // repository.refresh(this.modelName, this.operation, this.modelId as EventIds);
12402
+ if (redirect)
12403
+ this.location.back();
12404
+ }
12405
+ return {
12406
+ ...event,
12407
+ success: result ? true : false,
12408
+ message,
12409
+ };
12122
12410
  }
12123
- return {
12124
- ...event,
12125
- success: result ? true : false,
12126
- message
12127
- };
12128
12411
  }
12129
12412
  catch (error) {
12130
- this.log.error(error);
12413
+ this.log.for(this.submit).error(`Error during ${this.operation} operation: ${error instanceof Error ? error.message : error}`);
12131
12414
  return {
12132
12415
  ...event,
12133
12416
  success: false,
12134
- message: error instanceof Error ? error.message : error
12417
+ message: error instanceof Error ? error.message : error,
12135
12418
  };
12136
12419
  }
12137
12420
  }
@@ -12151,14 +12434,15 @@ class NgxModelPageDirective extends NgxPageDirective {
12151
12434
  this.location.back();
12152
12435
  return undefined;
12153
12436
  }
12437
+ if (!modelName)
12438
+ modelName = this.modelName;
12154
12439
  const getRepository = async (modelName, parent, model) => {
12155
12440
  if (this._repository)
12156
12441
  return this._repository;
12157
12442
  const constructor = Model.get(modelName);
12158
12443
  if (constructor) {
12159
12444
  const properties = Metadata.properties(constructor);
12160
- if (!model)
12161
- model = {};
12445
+ // if (!model) model = {} as KeyValue;
12162
12446
  for (const prop of properties) {
12163
12447
  const type = Metadata.type(constructor, prop).name;
12164
12448
  const context = getModelAndRepository(type);
@@ -12169,23 +12453,31 @@ class NgxModelPageDirective extends NgxPageDirective {
12169
12453
  const data = await this.handleGet(uid, repository, modelName);
12170
12454
  this.model = Model.build({ [prop]: data }, modelName);
12171
12455
  }
12172
- else {
12173
- model[prop] = Model.build({}, type);
12174
- }
12456
+ // else {
12457
+ // model[prop as string] = Model.build({}, type);
12458
+ // }
12175
12459
  }
12176
- this.model[parent] = Model.build(model, modelName);
12460
+ // (this.model as KeyValue)[parent as string] = Model.build(
12461
+ // model,
12462
+ // modelName
12463
+ // );
12177
12464
  }
12178
12465
  };
12179
- repository = (repository || await getRepository(modelName));
12466
+ repository = (repository ||
12467
+ (await getRepository(modelName)));
12180
12468
  if (!repository)
12181
12469
  return this.model;
12182
- const type = Metadata.type(repository.class, repository.pk).name;
12470
+ const type = Metadata.type(repository.class, Model.pk(repository.class)).name;
12183
12471
  try {
12184
- const result = await repository.read(([Primitives.NUMBER, Primitives.BIGINT].includes(type.toLowerCase()) ? Number(uid) : uid));
12472
+ const result = await (repository).read(([Primitives.NUMBER, Primitives.BIGINT].includes(type.toLowerCase())
12473
+ ? Number(uid)
12474
+ : uid));
12185
12475
  return result;
12186
12476
  }
12187
12477
  catch (error) {
12188
- this.log.for(this.handleGet).info(`Error getting model instance with id ${uid}: ${error.message}`);
12478
+ this.log
12479
+ .for(this.handleGet)
12480
+ .info(`Error getting model instance with id ${uid}: ${error.message}`);
12189
12481
  return undefined;
12190
12482
  }
12191
12483
  }
@@ -12200,13 +12492,22 @@ class NgxModelPageDirective extends NgxPageDirective {
12200
12492
  * @return {Model | string | number} Processed data ready for repository operations
12201
12493
  * @private
12202
12494
  */
12203
- parseData(data, operation) {
12204
- const repo = this._repository;
12495
+ parseData(data, operation, repository) {
12496
+ operation = (operation === OperationKeys.READ
12497
+ ? OperationKeys.DELETE
12498
+ : operation.toLowerCase());
12499
+ if (Array.isArray(data)) {
12500
+ data = data.map((item) => this.parseData(item, operation, repository));
12501
+ return data;
12502
+ }
12205
12503
  let uid = this.modelId;
12206
- if (repo.pk === 'id')
12207
- uid = Number(uid);
12504
+ const pk = Model.pk(repository.class);
12505
+ const type = Metadata.type(repository.class, pk).name;
12506
+ uid = [Primitives.NUMBER, Primitives.BIGINT].includes(type.toLowerCase())
12507
+ ? Number(uid)
12508
+ : uid;
12208
12509
  if (operation !== OperationKeys.DELETE)
12209
- return Model.build(this.modelId ? Object.assign(data, { [repo.pk]: uid }) : data, this.modelName);
12510
+ return Model.build(this.modelId ? Object.assign(data, { [pk]: uid }) : data, repository.class.name);
12210
12511
  return uid;
12211
12512
  }
12212
12513
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgxModelPageDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
@@ -12253,5 +12554,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
12253
12554
  * Generated bundle index. Do not edit.
12254
12555
  */
12255
12556
 
12256
- export { ActionRoles, AngularEngineKeys, BaseComponentProps, CPTKN, CardComponent, ComponentEventNames, ComponentRendererComponent, ComponentsTagNames, CrudFieldComponent, CrudFormComponent, CssClasses, DB_ADAPTER_PROVIDER, DB_ADAPTER_PROVIDER_TOKEN, DecafFakerRepository, DefaultFormReactiveOptions, DefaultListEmptyOptions, DefaultModalOptions, Dynamic, DynamicModule, ElementPositions, ElementSizes, EmptyStateComponent, FieldsetComponent, FileUploadComponent, FilterComponent, ForAngularCommonModule, ForAngularComponentsModule, FormConstants, I18N_CONFIG_TOKEN, I18nLoader, I18nLoaderFactory, I18nParser, IconComponent, LOCALE_ROOT_TOKEN, LayoutComponent, LayoutGridGaps, ListComponent, ListComponentsTypes, ListItemComponent, ListItemPositions, LoggerLevels, ModalComponent, ModelRendererComponent, NgxComponentDirective, NgxEventHandler, NgxFormDirective, NgxFormFieldDirective, NgxFormService, NgxMediaService, NgxModelPageDirective, NgxPageDirective, NgxParentComponentDirective, NgxRenderingEngine, NgxSvgDirective, PaginationComponent, RouteDirections, SearchbarComponent, SteppedFormComponent, WindowColorSchemes, cleanSpaces, dataMapper, filterString, formatDate, generateRandomValue, getFakerData, getInjectablesRegistry, getLocaleContext, getLocaleContextByKey, getLocaleFromClassName, getLocaleLanguage, getLogger, getModelAndRepository, getNgxModalComponent, getNgxSelectOptionsModal, getOnWindow, getOnWindowDocument, getWindow, getWindowDocument, getWindowWidth, isDarkMode, isDevelopmentMode, isNotUndefined, isValidDate, itemMapper, parseToValidDate, presentNgxLightBoxModal, provideDbAdapter, provideDynamicComponents, provideI18n, provideI18nLoader, removeFocusTrap, setOnWindow, stringToBoolean, windowEventEmitter };
12557
+ export { ActionRoles, AngularEngineKeys, BaseComponentProps, CPTKN, CardComponent, ComponentEventNames, ComponentRendererComponent, ComponentsTagNames, CrudFieldComponent, CrudFormComponent, CssClasses, DB_ADAPTER_PROVIDER, DB_ADAPTER_PROVIDER_TOKEN, DecafFakerRepository, DefaultFormReactiveOptions, DefaultListEmptyOptions, DefaultModalOptions, Dynamic, DynamicModule, ElementPositions, ElementSizes, EmptyStateComponent, FieldsetComponent, FileUploadComponent, FilterComponent, ForAngularCommonModule, ForAngularComponentsModule, FormConstants, I18N_CONFIG_TOKEN, I18nLoader, I18nLoaderFactory, I18nParser, IconComponent, LOCALE_ROOT_TOKEN, LayoutComponent, LayoutGridGaps, ListComponent, ListComponentsTypes, ListItemComponent, ListItemPositions, LoggerLevels, ModalComponent, ModelRendererComponent, NgxComponentDirective, NgxEventHandler, NgxFormDirective, NgxFormFieldDirective, NgxFormService, NgxMediaService, NgxModelPageDirective, NgxPageDirective, NgxParentComponentDirective, NgxRenderingEngine, NgxSvgDirective, PaginationComponent, RouteDirections, SearchbarComponent, SteppedFormComponent, WindowColorSchemes, cleanSpaces, dataMapper, filterString, formatDate, generateRandomValue, getFakerData, getInjectablesRegistry, getLocaleContext, getLocaleContextByKey, getLocaleFromClassName, getLocaleLanguage, getLogger, getModelAndRepository, getNgxModalComponent, getNgxSelectOptionsModal, getOnWindow, getOnWindowDocument, getWindow, getWindowDocument, getWindowWidth, isDarkMode, isDevelopmentMode, isNotUndefined, isValidDate, itemMapper, parseToValidDate, presentNgxInlineModal, presentNgxLightBoxModal, provideDbAdapter, provideDynamicComponents, provideI18n, provideI18nLoader, removeFocusTrap, setOnWindow, stringToBoolean, windowEventEmitter };
12257
12558
  //# sourceMappingURL=decaf-ts-for-angular.mjs.map