@decaf-ts/for-angular 0.0.79 → 0.0.81

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,31 +1,30 @@
1
- import { HTML5InputTypes, parseValueByType, HTML5CheckTypes, escapeHtml, parseToNumber, RenderingEngine, DecafComponent, UIKeys, RenderingError, UIMediaBreakPoints, DecafEventHandler } from '@decaf-ts/ui-decorators';
1
+ import { HTML5InputTypes, parseValueByType, HTML5CheckTypes, escapeHtml, parseToNumber, RenderingEngine, DecafComponent, ComponentEventNames, UIKeys, RenderingError, UIMediaBreakPoints, LayoutGridGaps, ElementSizes, DecafEventHandler } from '@decaf-ts/ui-decorators';
2
2
  import * as i0 from '@angular/core';
3
3
  import { InjectionToken, provideEnvironmentInitializer, isDevMode, reflectComponentType, Injector, createEnvironmentInjector, runInInjectionContext, createComponent, inject, NgZone, Injectable, Input, Directive, signal, ChangeDetectorRef, EnvironmentInjector, Renderer2, EventEmitter, ElementRef, Output, ViewChild, Inject, ViewContainerRef, TemplateRef, Component, ViewEncapsulation, HostListener, NgModule } from '@angular/core';
4
4
  import * as i1$1 from '@angular/common';
5
5
  import { Location, NgComponentOutlet, CommonModule } from '@angular/common';
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';
6
+ import { VALIDATION_PARENT_KEY, ValidationKeys, DEFAULT_PATTERNS, Validation, Primitives, ComparisonValidationKeys, PathProxyEngine, Model, ModelKeys, isValidDate as isValidDate$1, parseDate, sf as sf$1, ReservedModels } from '@decaf-ts/decorator-validation';
7
7
  import { OperationKeys, InternalError, NotFoundError } from '@decaf-ts/db-decorators';
8
8
  import * as i1 from '@angular/forms';
9
9
  import { FormGroup, FormControl, FormArray, AbstractControl, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
10
10
  import { InjectableRegistryImp } from '@decaf-ts/injectable-decorators';
11
- import { Logging, LoggedClass } from '@decaf-ts/logging';
11
+ import { Logging, LoggedClass, sf } from '@decaf-ts/logging';
12
12
  import { Repository, OrderDirection, Condition } from '@decaf-ts/core';
13
13
  import { uses, Metadata, apply, metadata } from '@decaf-ts/decoration';
14
14
  import { AnimationController, provideIonicAngular, LoadingController, IonIcon, IonButton, IonModal, IonSpinner, IonButtons, IonContent, IonHeader, IonTitle, IonToolbar, IonInput, IonItem, IonCheckbox, IonRadioGroup, IonRadio, IonSelect, IonSelectOption, IonLabel, IonBadge, IonText, IonTextarea, IonCard, IonCardHeader, IonCardContent, IonCardTitle, IonCardSubtitle, IonList, IonReorder, IonReorderGroup, IonSearchbar, IonChip, IonRefresher, IonThumbnail, IonSkeletonText, IonRefresherContent, IonInfiniteScroll, IonInfiniteScrollContent, IonListHeader, IonItemSliding, IonItemOptions, IonItemOption, IonPopover, NavController } from '@ionic/angular/standalone';
15
15
  import { faker } from '@faker-js/faker';
16
- import { forkJoin, Subject, BehaviorSubject, fromEvent, of, merge, Observable, timer, firstValueFrom, takeUntil as takeUntil$1, shareReplay as shareReplay$1, debounceTime } from 'rxjs';
17
- import { Router, NavigationEnd, NavigationStart, ActivatedRoute } from '@angular/router';
16
+ import { forkJoin, Subject, BehaviorSubject, fromEvent, of, merge, Observable, timer, shareReplay as shareReplay$1, takeUntil as takeUntil$1, firstValueFrom, debounceTime } from 'rxjs';
17
+ import { Title, DomSanitizer } from '@angular/platform-browser';
18
+ import { Router, NavigationStart, NavigationEnd, ActivatedRoute } from '@angular/router';
19
+ import { MenuController } from '@ionic/angular';
18
20
  import { TranslateParser, provideTranslateService, TranslateLoader, provideTranslateParser, TranslateService, TranslatePipe, TranslateModule } from '@ngx-translate/core';
19
21
  import { provideHttpClient, HttpClient } from '@angular/common/http';
20
22
  import { map, distinctUntilChanged, takeUntil, shareReplay, tap, switchMap } from 'rxjs/operators';
21
- import { Title, DomSanitizer } from '@angular/platform-browser';
22
- import { MenuController } from '@ionic/angular';
23
23
  import { __decorate, __metadata } from 'tslib';
24
24
  import { addIcons } from 'ionicons';
25
25
  import * as allIcons from 'ionicons/icons';
26
26
  import { chevronUpOutline, chevronDownOutline, createOutline, trashOutline, addOutline, alertCircleOutline, arrowUpOutline, arrowDownOutline, searchOutline, closeOutline, chevronForwardOutline, chevronBackOutline, arrowBackOutline, arrowForwardOutline } from 'ionicons/icons';
27
27
  import { modalController } from '@ionic/core';
28
- import { getModelAndRepository as getModelAndRepository$1, ActionRoles as ActionRoles$1, ComponentEventNames as ComponentEventNames$1 } from 'src/lib/engine';
29
28
 
30
29
  const DB_ADAPTER_FLAVOUR_TOKEN = 'DbAdapterFlavour';
31
30
  /**
@@ -128,32 +127,6 @@ const WindowColorSchemes = {
128
127
  dark: 'dark',
129
128
  undefined: 'undefined',
130
129
  };
131
- const ElementSizes = {
132
- xsmall: 'xsmall',
133
- small: 'small',
134
- medium: 'medium',
135
- default: 'default',
136
- large: 'large',
137
- xLarge: 'xlarge',
138
- '2xLarge': '2xlarge',
139
- auto: 'auto',
140
- expand: 'expand',
141
- block: 'block',
142
- };
143
- const ElementPositions = {
144
- left: 'left',
145
- center: 'center',
146
- right: 'right',
147
- top: 'top',
148
- bottom: 'bottom',
149
- };
150
- const LayoutGridGaps = {
151
- small: 'small',
152
- medium: 'medium',
153
- large: 'large',
154
- collapse: 'collapse',
155
- none: '',
156
- };
157
130
  const ListItemPositions = {
158
131
  uid: 'uid',
159
132
  title: 'title',
@@ -203,84 +176,6 @@ const AngularEngineKeys = {
203
176
  LOADED: 'engineLoaded',
204
177
  DARK_PALETTE_CLASS: 'dcf-palette-dark',
205
178
  };
206
- /**
207
- * @description Form validation state constants.
208
- * @summary Contains constants representing the possible validation states of a form.
209
- * These are used to check and handle form validation throughout the application.
210
- * The VALID state indicates all form controls pass validation, while INVALID
211
- * indicates one or more validation errors exist.
212
- * @typedef {Object} FormConstants
213
- * @property {string} VALID - Constant representing a valid form state
214
- * @property {string} INVALID - Constant representing an invalid form state
215
- * @const FormConstants
216
- * @memberOf module:lib/engine/constants
217
- */
218
- const FormConstants = {
219
- VALID: 'VALID',
220
- INVALID: 'INVALID',
221
- };
222
- /**
223
- * @description Event name constants.
224
- * @summary Contains constants for standardized event names used throughout the application.
225
- * These constants ensure consistent event naming across components and make it easier to
226
- * track and handle events. Each constant represents a specific application event type.
227
- * @typedef {Object} ComponentEventNames
228
- * @property {string} BackButtonClickEvent - Event fired when back button navigation ends
229
- * @property {string} Render - Event after component initialize action occurs
230
- * @property {string} Refresh - Event fired when a refresh action occurs
231
- * @property {string} Click - Event fired when a click action occurs
232
- * @property {string} Change - Event fired when a change action occurs
233
- * @property {string} Submit - Event fired when a form submission occurs
234
- * @property {string} ValidationError - Event fired when a validation error occurs
235
- * @property {string} ThemeChange - Event fired when a theme change occurs
236
- * @property {string} FormGroupLoaded - Event fired when a reactve form group is loaded
237
- * @const ComponentEventNames
238
- * @memberOf module:lib/engine/constants
239
- */
240
- const ComponentEventNames = {
241
- Render: 'render',
242
- BackButtonClickEvent: 'backButtonNavigationEndEvent',
243
- Refresh: 'RefreshEvent',
244
- Click: 'ClickEvent',
245
- Change: 'ChangeEvent',
246
- Submit: 'SubmitEvent',
247
- ValidationError: 'validationErrorEvent',
248
- ThemeChange: 'themeChangeEvent',
249
- FormGroupLoaded: 'formGroupLoadedEvent',
250
- };
251
- const TransactionHooks = {
252
- BeforeCreate: 'beforeCreate',
253
- AfterCreate: 'afterCreate',
254
- BeforeUpdate: 'beforeUpdate',
255
- AfterUpdate: 'afterUpdate',
256
- BeforeDelete: 'beforeDelete',
257
- AfterDelete: 'afterDelete',
258
- };
259
- /**
260
- * @description Logger level constants.
261
- * @summary Defines the logging levels used in the application's logging system.
262
- * Lower numeric values represent more verbose logging, while higher values represent
263
- * more critical logs. These levels control which log messages are output based on
264
- * the configured logging threshold.
265
- * @enum {number}
266
- * @readonly
267
- * @property {number} ALL - Log everything (most verbose)
268
- * @property {number} DEBUG - Log debug information
269
- * @property {number} INFO - Log informational messages
270
- * @property {number} WARN - Log warnings
271
- * @property {number} ERROR - Log errors
272
- * @property {number} CRITICAL - Log critical errors (least verbose)
273
- * @memberOf module:lib/engine/constants
274
- */
275
- var LoggerLevels;
276
- (function (LoggerLevels) {
277
- LoggerLevels[LoggerLevels["ALL"] = 0] = "ALL";
278
- LoggerLevels[LoggerLevels["DEBUG"] = 1] = "DEBUG";
279
- LoggerLevels[LoggerLevels["INFO"] = 2] = "INFO";
280
- LoggerLevels[LoggerLevels["WARN"] = 3] = "WARN";
281
- LoggerLevels[LoggerLevels["ERROR"] = 4] = "ERROR";
282
- LoggerLevels[LoggerLevels["CRITICAL"] = 5] = "CRITICAL";
283
- })(LoggerLevels || (LoggerLevels = {}));
284
179
  /**
285
180
  * @description Route direction constants.
286
181
  * @summary Defines the possible navigation directions in the application.
@@ -347,6 +242,8 @@ var ComponentsTagNames;
347
242
  */
348
243
  var BaseComponentProps;
349
244
  (function (BaseComponentProps) {
245
+ BaseComponentProps["MODEL_ID"] = "modelId";
246
+ BaseComponentProps["MODEL"] = "model";
350
247
  BaseComponentProps["HANDLERS"] = "handlers";
351
248
  BaseComponentProps["LOCALE"] = "locale";
352
249
  BaseComponentProps["LOCALE_ROOT"] = "locale_root";
@@ -551,7 +448,6 @@ class ValidatorFactory {
551
448
  function getDbAdapterFlavour() {
552
449
  return (getOnWindow(DB_ADAPTER_FLAVOUR_TOKEN) || '');
553
450
  }
554
- ;
555
451
  /**
556
452
  * @description Provides an array of component types for dynamic rendering.
557
453
  * @summary Helper function to package component constructors for registration with the
@@ -590,9 +486,7 @@ function provideDecafDynamicComponents(...components) {
590
486
  */
591
487
  function getModelAndRepository(model, clazz) {
592
488
  try {
593
- const modelName = (typeof model === Primitives.STRING
594
- ? model
595
- : model.constructor.name);
489
+ const modelName = (typeof model === Primitives.STRING ? model : model.constructor.name);
596
490
  const constructor = Model.get((modelName.charAt(0).toUpperCase() + modelName.slice(1)));
597
491
  if (!constructor)
598
492
  return undefined;
@@ -686,10 +580,9 @@ const decafPageTransition = (baseEl, opts) => {
686
580
  };
687
581
  function provideDecafPageTransition() {
688
582
  return provideIonicAngular({
689
- navAnimation: decafPageTransition
583
+ navAnimation: decafPageTransition,
690
584
  });
691
585
  }
692
- ;
693
586
  function provideDecafDarkMode() {
694
587
  return provideEnvironmentInitializer(() => {
695
588
  const doc = getWindowDocument();
@@ -766,13 +659,13 @@ function getInjectablesRegistry() {
766
659
  * @function isDevelopmentMode
767
660
  * @memberOf module:for-angular
768
661
  */
769
- function isDevelopmentMode(context = "localhost") {
662
+ function isDevelopmentMode(context = 'localhost') {
770
663
  if (!context)
771
664
  return isDevMode();
772
665
  const win = getWindow();
773
666
  return (isDevMode() ||
774
- win?.["env"]?.["CONTEXT"].toLowerCase() !== context.toLowerCase() ||
775
- win?.["location"]?.hostname?.includes(context));
667
+ win?.['env']?.['CONTEXT'].toLowerCase() !== context.toLowerCase() ||
668
+ win?.['location']?.hostname?.includes(context));
776
669
  }
777
670
  /**
778
671
  * @description Dispatches a custom event to the document window
@@ -812,9 +705,7 @@ function windowEventEmitter(name, detail, props) {
812
705
  */
813
706
  function getOnWindowDocument(key) {
814
707
  const doc = getWindowDocument();
815
- return doc instanceof Document
816
- ? doc?.[key] || undefined
817
- : undefined;
708
+ return doc instanceof Document ? doc?.[key] || undefined : undefined;
818
709
  }
819
710
  /**
820
711
  * @description Retrieves the document object from the window
@@ -828,7 +719,7 @@ function getOnWindowDocument(key) {
828
719
  * @memberOf module:for-angular
829
720
  */
830
721
  function getWindowDocument() {
831
- return getOnWindow("document");
722
+ return getOnWindow('document');
832
723
  }
833
724
  /**
834
725
  * @description Retrieves a property from the window object
@@ -876,7 +767,7 @@ function setOnWindow(key, value) {
876
767
  * @memberOf module:for-angular
877
768
  */
878
769
  function getWindow() {
879
- return globalThis?.["window"];
770
+ return globalThis?.['window'];
880
771
  }
881
772
  /**
882
773
  * @description Retrieves the width of the browser window
@@ -890,7 +781,7 @@ function getWindow() {
890
781
  * @memberOf module:for-angular
891
782
  */
892
783
  function getWindowWidth() {
893
- return getOnWindow("innerWidth") || 0;
784
+ return getOnWindow('innerWidth') || 0;
894
785
  }
895
786
  /**
896
787
  * @description Checks if a value is not undefined
@@ -925,25 +816,23 @@ function isNotUndefined(prop) {
925
816
  */
926
817
  function getLocaleFromClassName(instance, suffix) {
927
818
  if (typeof instance !== Primitives.STRING)
928
- instance =
929
- instance.name ||
930
- instance?.constructor?.name;
819
+ instance = instance.name || instance?.constructor?.name;
931
820
  let name = instance;
932
821
  if (suffix)
933
822
  name = `${instance}${suffix.charAt(0).toUpperCase() + suffix.slice(1)}`;
934
823
  name = name
935
- .replace(/_|-/g, "")
824
+ .replace(/_|-/g, '')
936
825
  .replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
937
826
  if (index > 1)
938
- word = "." + word;
827
+ word = '.' + word;
939
828
  return word.toLowerCase();
940
829
  })
941
- .split(".");
830
+ .split('.');
942
831
  if (name.length < 3)
943
- return name.reverse().join(".");
832
+ return name.reverse().join('.');
944
833
  const preffix = name[name.length - 1];
945
834
  name.pop();
946
- name = name.join("_");
835
+ name = name.join('_');
947
836
  return `${preffix}.${name}`;
948
837
  }
949
838
  /**
@@ -959,7 +848,7 @@ function getLocaleFromClassName(instance, suffix) {
959
848
  */
960
849
  function getLocaleLanguage() {
961
850
  const win = getWindow();
962
- return win.navigator.language || "en";
851
+ return win.navigator.language || 'en';
963
852
  // return win?.[WINDOW_KEYS.LANGUAGE_SELECTED] || (win.navigator.language || '').split('-')[0] || "en";
964
853
  }
965
854
  /**
@@ -978,9 +867,9 @@ function getLocaleLanguage() {
978
867
  */
979
868
  function generateRandomValue(length = 8, onlyNumbers = false) {
980
869
  const chars = onlyNumbers
981
- ? "0123456789"
982
- : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
983
- let result = "";
870
+ ? '0123456789'
871
+ : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
872
+ let result = '';
984
873
  for (let i = 0; i < length; i++)
985
874
  result += chars.charAt(Math.floor(Math.random() * chars.length));
986
875
  return result;
@@ -999,8 +888,9 @@ function generateRandomValue(length = 8, onlyNumbers = false) {
999
888
  * @memberOf module:lib/helpers/utils
1000
889
  */
1001
890
  function stringToBoolean(prop) {
1002
- if (typeof prop === "string")
1003
- prop = prop.toLowerCase() === "true" ? true : false;
891
+ if (typeof prop === Primitives.STRING) {
892
+ prop = String(prop).toLowerCase() === 'true' ? true : false;
893
+ }
1004
894
  return prop;
1005
895
  }
1006
896
  /**
@@ -1022,10 +912,9 @@ function isValidDate(date) {
1022
912
  return ((date instanceof Date && !isNaN(date)) ||
1023
913
  (() => {
1024
914
  const testRegex = new RegExp(/^\d{4}-\d{2}-\d{2}$/).test(date);
1025
- if (typeof date !== Primitives.STRING ||
1026
- (!date?.includes("T") && !testRegex))
915
+ if (typeof date !== Primitives.STRING || (!date?.includes('T') && !testRegex))
1027
916
  return false;
1028
- date = date.split("T")[0];
917
+ date = date.split('T')[0];
1029
918
  if (!new RegExp(/^\d{4}-\d{2}-\d{2}$/).test(date))
1030
919
  return false;
1031
920
  return !!new Date(date);
@@ -1056,51 +945,18 @@ function isValidDate(date) {
1056
945
  function formatDate(date, locale) {
1057
946
  if (!locale)
1058
947
  locale = getLocaleLanguage();
1059
- if (typeof date === "string" || typeof date === "number")
1060
- date = new Date(typeof date === "string" ? date.replace(/\//g, "-") : date);
1061
- if (!isValidDate(date))
1062
- return `${date}`;
1063
- const r = date.toLocaleString(locale, {
1064
- year: "numeric",
1065
- day: "2-digit",
1066
- month: "2-digit",
1067
- });
1068
- return r;
948
+ if (typeof date === Primitives.STRING || typeof date === 'number') {
949
+ date = new Date(typeof date === Primitives.STRING ? `${date}`.replace(/\//g, '-') : date);
950
+ }
951
+ return !isValidDate(date)
952
+ ? `${date}`
953
+ : date.toLocaleString(locale, {
954
+ year: 'numeric',
955
+ day: '2-digit',
956
+ month: '2-digit',
957
+ });
1069
958
  }
1070
959
  /**
1071
- * @description Attempts to parse a date string, Date object, or number into a valid Date object.
1072
- * @summary This function provides robust date parsing functionality that handles the specific
1073
- * format "DD/MM/YYYY HH:MM:SS:MS". It first validates the input date, and if already valid,
1074
- * returns it as-is. For string inputs, it parses the date and time components separately,
1075
- * extracts numeric values, and constructs a new Date object. The function includes validation
1076
- * to ensure the resulting Date object is valid and logs a warning if parsing fails.
1077
- * Returns null for invalid or unsupported date formats.
1078
- *
1079
- * @param {string | Date | number} date - The date to parse. Can be a Date object, a timestamp number,
1080
- * or a date string in the format "DD/MM/YYYY HH:MM:SS:MS"
1081
- * @returns {Date | null} A valid Date object if parsing is successful, or null if the date is invalid
1082
- * or doesn't match the expected format
1083
- *
1084
- * @function parseToValidDate
1085
- * @memberOf module:lib/helpers/utils
1086
- */
1087
- function parseToValidDate(date) {
1088
- if (isValidDate(date))
1089
- return date;
1090
- if (!`${date}`.includes("/"))
1091
- return null;
1092
- const [dateString, timeString] = date.split(" ");
1093
- const [day, month, year] = dateString.split("/").map(Number);
1094
- const [hours, minutes, seconds, milliseconds] = timeString
1095
- .split(":")
1096
- .map(Number);
1097
- date = new Date(year, month - 1, day, hours, minutes, seconds, milliseconds);
1098
- if (!isValidDate(date)) {
1099
- console.warn("parseToValidDate - Invalid date format", date);
1100
- return null;
1101
- }
1102
- return date;
1103
- }
1104
960
  /**
1105
961
  * @description Maps an item object using a provided mapper object and optional additional properties.
1106
962
  * @summary This function transforms a source object into a new object based on mapping rules defined
@@ -1121,8 +977,8 @@ function parseToValidDate(date) {
1121
977
  */
1122
978
  function itemMapper(item, mapper, props) {
1123
979
  return Object.entries(mapper).reduce((accum, [key, prop]) => {
1124
- const arrayValue = (prop || "").split(".");
1125
- let value = item?.[prop] || "";
980
+ const arrayValue = (prop || '').split('.');
981
+ let value = item?.[prop] || '';
1126
982
  if (!prop) {
1127
983
  accum[key] = prop;
1128
984
  }
@@ -1135,7 +991,7 @@ function itemMapper(item, mapper, props) {
1135
991
  for (const propValue of arrayValue)
1136
992
  value = !value
1137
993
  ? item[propValue]
1138
- : (typeof value === "string" ? JSON.parse(value) : value)[propValue];
994
+ : (typeof value === 'string' ? JSON.parse(value) : value)[propValue];
1139
995
  if (isValidDate(new Date(value)))
1140
996
  value = `${formatDate(value)}`;
1141
997
  accum[key] = value === null || value === undefined ? prop : value;
@@ -1168,8 +1024,7 @@ function dataMapper(data, mapper, props) {
1168
1024
  return [];
1169
1025
  return data.reduce((accum, curr) => {
1170
1026
  const item = itemMapper(curr, mapper, props);
1171
- const hasValues = [...new Set(Object.values(item))].filter((value) => value).length >
1172
- 0;
1027
+ const hasValues = [...new Set(Object.values(item))].filter((value) => value).length > 0;
1173
1028
  accum.push(hasValues ? item : curr);
1174
1029
  return accum;
1175
1030
  }, []);
@@ -1206,8 +1061,8 @@ function removeFocusTrap() {
1206
1061
  * @function cleanSpaces
1207
1062
  * @memberOf module:for-angular
1208
1063
  */
1209
- function cleanSpaces(value = "", lowercase = false) {
1210
- value = `${value}`.trim().replace(/\s+/g, " ");
1064
+ function cleanSpaces(value = '', lowercase = false) {
1065
+ value = `${value}`.trim().replace(/\s+/g, ' ');
1211
1066
  return lowercase ? value.toLowerCase() : value;
1212
1067
  }
1213
1068
  /**
@@ -1223,7 +1078,7 @@ function cleanSpaces(value = "", lowercase = false) {
1223
1078
  * @memberOf module:for-angular
1224
1079
  */
1225
1080
  async function isDarkMode() {
1226
- const { matches } = getWindow().matchMedia("(prefers-color-scheme: dark)");
1081
+ const { matches } = getWindow().matchMedia('(prefers-color-scheme: dark)');
1227
1082
  return matches;
1228
1083
  }
1229
1084
  /**
@@ -1241,8 +1096,8 @@ async function isDarkMode() {
1241
1096
  */
1242
1097
  function filterString(original, value, contain = true) {
1243
1098
  if (typeof original === Primitives.STRING)
1244
- original = original.split(" ");
1245
- return (original.filter((str) => contain ? str.includes(value) : !str.includes(value)) || []).join(" ");
1099
+ original = original.split(' ');
1100
+ return (original.filter((str) => contain ? str.includes(value) : !str.includes(value)) || []).join(' ');
1246
1101
  }
1247
1102
  /**
1248
1103
  * @summary Retrieves the icon associated with a menu item based on its label.
@@ -1253,11 +1108,8 @@ function filterString(original, value, contain = true) {
1253
1108
  */
1254
1109
  function getMenuIcon(label, menu) {
1255
1110
  const item = menu.find((m) => m.label?.toLowerCase() === label.toLowerCase());
1256
- return item?.icon || "";
1111
+ return item?.icon || '';
1257
1112
  }
1258
- const isClassConstructor = (value) => {
1259
- return typeof value === "function" && /^class\s/.test(String(value));
1260
- };
1261
1113
 
1262
1114
  /**
1263
1115
  * @module lib/engine/NgxFormService
@@ -2044,7 +1896,13 @@ class NgxFormService {
2044
1896
  if (!parentProps.required) {
2045
1897
  parent.setErrors(null);
2046
1898
  parent.updateValueAndValidity({ emitEvent: true });
2047
- childControl.disable();
1899
+ const hasValue = parentProps.isMultiple &&
1900
+ Object.keys(childControl.value).some((key) => childControl.value[key] !== null &&
1901
+ childControl.value[key] !== undefined &&
1902
+ childControl.value[key] !== '');
1903
+ if (!hasValue) {
1904
+ childControl.disable();
1905
+ }
2048
1906
  }
2049
1907
  else {
2050
1908
  this.validateFields(childControl);
@@ -2263,8 +2121,10 @@ class DecafFakerRepository extends LoggedClass {
2263
2121
  }
2264
2122
  get repository() {
2265
2123
  if (!this._repository) {
2266
- const modelName = typeof this.model === 'string' ? this.model : this.model.constructor.name;
2267
- const constructor = Model.get(modelName);
2124
+ const modelName = typeof this.model === Primitives.STRING
2125
+ ? this.model
2126
+ : this.model.constructor.name;
2127
+ const constructor = Model.get(String(modelName));
2268
2128
  if (!constructor)
2269
2129
  throw new InternalError(`Cannot find model ${modelName}. was it registered with @model?`);
2270
2130
  try {
@@ -2302,7 +2162,7 @@ class DecafFakerRepository extends LoggedClass {
2302
2162
  }
2303
2163
  dataFunctions[prop] = this.getPropValueFn(prop, key);
2304
2164
  }
2305
- const data = getFakerData(limit, dataFunctions, typeof this.model === 'string' ? this.model : this.model?.constructor.name);
2165
+ const data = getFakerData(limit, dataFunctions, typeof this.model === Primitives.STRING ? String(this.model) : this.model?.constructor.name);
2306
2166
  if (!values)
2307
2167
  return data;
2308
2168
  const _values = Object.values(values);
@@ -2745,7 +2605,7 @@ class NgxRenderingEngine extends RenderingEngine {
2745
2605
  NgxRenderingEngine._injector = injector;
2746
2606
  try {
2747
2607
  this._model = model;
2748
- const formId = Date.now().toString(36).toUpperCase();
2608
+ const formId = `${Date.now()}`.toUpperCase();
2749
2609
  const fieldDef = this.toFieldDefinition(model, globalProps);
2750
2610
  const props = fieldDef.props;
2751
2611
  if (!NgxRenderingEngine._operation)
@@ -3155,7 +3015,7 @@ class I18nLoader {
3155
3015
  */
3156
3016
  getTranslation(lang) {
3157
3017
  const libKeys = libLanguage[lang] || libLanguage['en'] || {};
3158
- const httpRequests$ = forkJoin(this.resources.map(config => this.http.get(`${config.prefix}${lang}${this.getSuffix(config.suffix || '.json')}`)));
3018
+ const httpRequests$ = forkJoin(this.resources.map((config) => this.http.get(`${config.prefix}${lang}${this.getSuffix(config.suffix || '.json')}`)));
3159
3019
  /**
3160
3020
  * @description Recursively merges two translation objects.
3161
3021
  * @summary Combines the properties of the source object into the target object.
@@ -3177,14 +3037,17 @@ class I18nLoader {
3177
3037
  }
3178
3038
  return target;
3179
3039
  }
3180
- return httpRequests$.pipe(map(res => {
3040
+ return httpRequests$.pipe(map((res) => {
3181
3041
  const merged = {
3182
3042
  ...libKeys,
3183
3043
  ...res.reduce((acc, current) => {
3184
3044
  for (const key in current) {
3185
3045
  let value = current[key] || {};
3186
3046
  if (libKeys[key]) {
3187
- value = { ...libKeys[key], ...recursiveMerge(libKeys[key], current[key]) };
3047
+ value = {
3048
+ ...libKeys[key],
3049
+ ...recursiveMerge(libKeys[key], current[key]),
3050
+ };
3188
3051
  }
3189
3052
  acc[key] = value;
3190
3053
  }
@@ -3209,10 +3072,7 @@ class I18nParser extends TranslateParser {
3209
3072
  * @returns {string} - The interpolated translation string.
3210
3073
  */
3211
3074
  interpolate(value, params = {}) {
3212
- if (typeof params === Primitives.STRING) {
3213
- params = { '0': params };
3214
- }
3215
- return sf(value, ...Object.values(params)).replace(/undefined/g, "");
3075
+ return sf(value, params === Primitives.STRING ? { '0': params } : params).replace(/undefined/g, '');
3216
3076
  }
3217
3077
  }
3218
3078
  /**
@@ -3621,6 +3481,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
3621
3481
  class NgxRepositoryDirective extends DecafComponent {
3622
3482
  constructor() {
3623
3483
  super(...arguments);
3484
+ /**
3485
+ * @description Store query results for the component.
3486
+ * @summary Holds an array of `Model` instances returned from repository queries.
3487
+ * This is used internally to cache query results that child components may bind to.
3488
+ * @type {M[]}
3489
+ */
3490
+ this._query = [];
3491
+ /**
3492
+ * @description Backing model data supplied to the component.
3493
+ * @summary Holds the raw `Model` instance or a generic key-value payload that child
3494
+ * components may bind to. When provided, it represents the contextual data the
3495
+ * component should render or mutate.
3496
+ * @type {M | M[] | KeyValue | KeyValue[] | undefined}
3497
+ */
3498
+ this._data = {};
3499
+ /**
3500
+ * @description Primary key value of the current model instance.
3501
+ * @summary Specifies the primary key value for the current model record being displayed or
3502
+ * manipulated by the component. This identifier is used for CRUD operations that target
3503
+ * specific records, such as read, update, and delete operations. The value corresponds to
3504
+ * the field designated as the primary key in the model definition.
3505
+ * @type {PrimaryKeyType}
3506
+ * @memberOf module:lib/engine/NgxRepositoryDirective
3507
+ */
3508
+ this.modelId = '';
3624
3509
  /**
3625
3510
  * @description The starting index for data fetching.
3626
3511
  * @summary Specifies the index from which to start fetching data. This is used
@@ -3659,17 +3544,33 @@ class NgxRepositoryDirective extends DecafComponent {
3659
3544
  */
3660
3545
  this.indexes = [];
3661
3546
  /**
3662
- * @description Backing model data supplied to the component.
3663
- * @summary Holds the raw `Model` instance or a generic key-value payload that child
3664
- * components may bind to. When provided, it represents the contextual data the
3665
- * component should render or mutate.
3666
- * @type {M | M[] | KeyValue | KeyValue[] | undefined}
3547
+ * @description Subject for debouncing repository observation events.
3548
+ * @summary RxJS Subject that collects repository change events and emits them after
3549
+ * a debounce period. This prevents multiple rapid repository changes from triggering
3550
+ * multiple list refresh operations, improving performance and user experience.
3551
+ *
3552
+ * @private
3553
+ * @type {Subject<any>}
3667
3554
  */
3668
- this._data = {};
3555
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3556
+ this.repositoryObserverSubject = new Subject();
3669
3557
  }
3670
3558
  async initialize() {
3671
- if (this.repository && this.filter) {
3672
- this._data = await this.query(this.filter.eq(this.modelId));
3559
+ if (this.repository) {
3560
+ if (this.filter) {
3561
+ this._data = await this.query(this.filter.eq(this.modelId));
3562
+ if (this._data) {
3563
+ await this.refresh();
3564
+ }
3565
+ }
3566
+ else {
3567
+ // if (String(this.modelName) === this.model?.constructor.name) {
3568
+ // const model = await this.repository.read(this.modelId as PrimaryKeyType);
3569
+ // if (model) {
3570
+ // await this.refresh(model);
3571
+ // }
3572
+ // }
3573
+ }
3673
3574
  }
3674
3575
  }
3675
3576
  set context(context) {
@@ -3685,6 +3586,12 @@ class NgxRepositoryDirective extends DecafComponent {
3685
3586
  }
3686
3587
  return this._context;
3687
3588
  }
3589
+ async refresh(model) {
3590
+ if (model && Model.isModel(model)) {
3591
+ this.model = Model.build(model, this.modelName);
3592
+ this._data = model;
3593
+ }
3594
+ }
3688
3595
  buildCondition(attr) {
3689
3596
  if (!attr) {
3690
3597
  attr = (this.filterBy || this.pk);
@@ -3692,7 +3599,7 @@ class NgxRepositoryDirective extends DecafComponent {
3692
3599
  const condtion = this.filter || Condition.attribute(attr);
3693
3600
  const type = this.getModelPropertyType(this.repository.class, attr);
3694
3601
  if (this.modelId) {
3695
- return condtion.eq([Primitives.NUMBER, Primitives.BIGINT].includes(this.pkType)
3602
+ return condtion.eq([Primitives.NUMBER, Primitives.BIGINT].includes(type)
3696
3603
  ? Number(this.modelId)
3697
3604
  : this.modelId);
3698
3605
  }
@@ -3732,13 +3639,40 @@ class NgxRepositoryDirective extends DecafComponent {
3732
3639
  .paginate(limit);
3733
3640
  }
3734
3641
  async transactionBegin(data, repository, operation) {
3735
- const hook = `before${operation.charAt(0).toUpperCase() + operation.slice(1)}`;
3736
- const handler = this.handlers?.[hook] || undefined;
3737
- const model = this.buildTransactionModel(data || {}, repository, operation);
3738
- if (handler && typeof handler === 'function') {
3739
- (await handler.bind(this)(model, repository, this.modelId));
3642
+ try {
3643
+ const hook = `before${operation.charAt(0).toUpperCase() + operation.slice(1)}`;
3644
+ const handler = this.handlers?.[hook] || undefined;
3645
+ const model = this.buildTransactionModel(data || {}, repository, operation);
3646
+ if (handler && typeof handler === 'function') {
3647
+ const result = (await handler.bind(this)(model, repository, this.modelId));
3648
+ if (result === false) {
3649
+ return undefined;
3650
+ }
3651
+ }
3652
+ return model;
3653
+ }
3654
+ catch (error) {
3655
+ this.log.for(this).error(error?.message || String(error));
3656
+ return undefined;
3657
+ }
3658
+ }
3659
+ async transactionEnd(model, repository, operation) {
3660
+ try {
3661
+ const hook = `after${operation.charAt(0).toUpperCase() + operation.slice(1)}`;
3662
+ const handler = this.handlers?.[hook] || undefined;
3663
+ if (handler && typeof handler === 'function') {
3664
+ const result = (await handler.bind(this)(model, repository, this.modelId));
3665
+ if (result === false) {
3666
+ return undefined;
3667
+ }
3668
+ return result;
3669
+ }
3670
+ return model;
3671
+ }
3672
+ catch (error) {
3673
+ this.log.for(this).error(error?.message || String(error));
3674
+ return undefined;
3740
3675
  }
3741
- return model;
3742
3676
  }
3743
3677
  /**
3744
3678
  * @description Parses and transforms form data for repository operations.
@@ -3763,8 +3697,9 @@ class NgxRepositoryDirective extends DecafComponent {
3763
3697
  const pk = Model.pk(repository.class);
3764
3698
  const pkType = Metadata.type(repository.class, pk).name;
3765
3699
  const modelId = (this.modelId || data[pk]);
3766
- if (!this.modelId)
3700
+ if (!this.modelId) {
3767
3701
  this.modelId = modelId;
3702
+ }
3768
3703
  const uid = this.parsePkValue(operation === OperationKeys.DELETE ? data[pk] : modelId, pkType);
3769
3704
  if (operation !== OperationKeys.DELETE) {
3770
3705
  const properties = Metadata.properties(repository.class);
@@ -3773,6 +3708,9 @@ class NgxRepositoryDirective extends DecafComponent {
3773
3708
  : properties.includes(this.pk) && !data[this.pk]
3774
3709
  ? { [this.pk]: modelId }
3775
3710
  : {};
3711
+ if (!String(data?.[pk] || '').trim().length) {
3712
+ data[pk] = undefined;
3713
+ }
3776
3714
  return Model.build(Object.assign(data || {}, relation, modelId && !data[this.pk] ? { [this.pk]: modelId } : {}), repository.class.name);
3777
3715
  }
3778
3716
  return uid;
@@ -3798,12 +3736,40 @@ class NgxRepositoryDirective extends DecafComponent {
3798
3736
  getModelPkType(clazz) {
3799
3737
  return this.getModelPropertyType(clazz, Model.pk(clazz));
3800
3738
  }
3739
+ /**
3740
+ * @description Handles repository observation events with debouncing.
3741
+ * @summary Processes repository change notifications and routes them appropriately.
3742
+ * For CREATE events with a UID, handles them immediately. For other events,
3743
+ * passes them to the debounced observer subject to prevent excessive updates.
3744
+ *
3745
+ * @param {...unknown[]} args - The repository event arguments including table, event type, and UID
3746
+ * @returns {Promise<void>}
3747
+ */
3748
+ async handleRepositoryRefresh(...args) {
3749
+ const [modelInstance, event, uid] = args;
3750
+ if ([OperationKeys.CREATE, OperationKeys.DELETE].includes(event))
3751
+ return this.handleObserveEvent(modelInstance, event, uid);
3752
+ return this.repositoryObserverSubject.next(args);
3753
+ }
3754
+ async handleObserveEvent(...args) {
3755
+ this.log.for(this.handleObserveEvent).info(`Repository change observed with args: ${args}`);
3756
+ }
3801
3757
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NgxRepositoryDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
3802
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: NgxRepositoryDirective, isStandalone: true, inputs: { pk: "pk", filter: "filter", filterBy: "filterBy", start: "start", limit: "limit", sortDirection: "sortDirection", sortBy: "sortBy", indexes: "indexes", _data: "_data" }, usesInheritance: true, ngImport: i0 }); }
3758
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: NgxRepositoryDirective, isStandalone: true, inputs: { _query: "_query", _data: "_data", model: "model", modelId: "modelId", modelName: "modelName", pk: "pk", filter: "filter", filterBy: "filterBy", start: "start", limit: "limit", sortDirection: "sortDirection", sortBy: "sortBy", indexes: "indexes" }, usesInheritance: true, ngImport: i0 }); }
3803
3759
  }
3804
3760
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NgxRepositoryDirective, decorators: [{
3805
3761
  type: Directive
3806
- }], propDecorators: { pk: [{
3762
+ }], propDecorators: { _query: [{
3763
+ type: Input
3764
+ }], _data: [{
3765
+ type: Input
3766
+ }], model: [{
3767
+ type: Input
3768
+ }], modelId: [{
3769
+ type: Input
3770
+ }], modelName: [{
3771
+ type: Input
3772
+ }], pk: [{
3807
3773
  type: Input
3808
3774
  }], filter: [{
3809
3775
  type: Input
@@ -3819,8 +3785,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
3819
3785
  type: Input
3820
3786
  }], indexes: [{
3821
3787
  type: Input
3822
- }], _data: [{
3823
- type: Input
3824
3788
  }] } });
3825
3789
 
3826
3790
  /**
@@ -4188,19 +4152,8 @@ class NgxComponentDirective extends NgxRepositoryDirective {
4188
4152
  */
4189
4153
  this.colorSchema = WindowColorSchemes.light;
4190
4154
  this.destroySubscriptions$ = new Subject();
4191
- /**
4192
- * @description Subject for debouncing repository observation events.
4193
- * @summary RxJS Subject that collects repository change events and emits them after
4194
- * a debounce period. This prevents multiple rapid repository changes from triggering
4195
- * multiple list refresh operations, improving performance and user experience.
4196
- *
4197
- * @private
4198
- * @type {Subject<any>}
4199
- */
4200
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
4201
- this.repositoryObserverSubject = new Subject();
4202
4155
  this.value = undefined;
4203
- this.componentName = componentName || 'NgxComponentDirective';
4156
+ this.componentName = componentName || this.constructor.name || 'NgxComponentDirective';
4204
4157
  this.localeRoot = localeRoot;
4205
4158
  if (!this.localeRoot && this.componentName)
4206
4159
  this.localeRoot = this.componentName;
@@ -4214,23 +4167,22 @@ class NgxComponentDirective extends NgxRepositoryDirective {
4214
4167
  }
4215
4168
  });
4216
4169
  }
4217
- /**
4218
- * @description Cleanup lifecycle hook invoked when the directive is destroyed.
4219
- * @summary Ensures any resources allocated by the directive's media service are
4220
- * released (DOM listeners, timers, subscriptions, etc.). Implementations should
4221
- * keep `mediaService.destroy()` idempotent; calling it here prevents leaks when
4222
- * components are torn down.
4223
- * @returns {Promise<void>}
4224
- */
4225
- async ngOnDestroy() {
4226
- this.mediaService.destroy();
4227
- this.destroySubscriptions$.next();
4228
- this.destroySubscriptions$.complete();
4229
- }
4230
4170
  async initialize() {
4231
4171
  this.mediaService.darkModeEnabled();
4232
4172
  // connect component to media service for color scheme toggling
4233
4173
  this.mediaService.colorSchemeObserver(this.component);
4174
+ if (!this.initialized && Object.keys(this.props || {}).length) {
4175
+ this.parseProps(this);
4176
+ }
4177
+ this.router.events
4178
+ .pipe(shareReplay$1(1), takeUntil$1(this.destroySubscriptions$))
4179
+ .subscribe(async (event) => {
4180
+ if (event instanceof NavigationStart) {
4181
+ if (this.value) {
4182
+ await this.ngOnDestroy();
4183
+ }
4184
+ }
4185
+ });
4234
4186
  this.route = this.router.url.replace('/', '');
4235
4187
  const instance = this;
4236
4188
  if (this.propsMapperFn) {
@@ -4243,12 +4195,12 @@ class NgxComponentDirective extends NgxRepositoryDirective {
4243
4195
  if (!this.initialized) {
4244
4196
  const handler = this.handlers?.[ComponentEventNames.Render] || undefined;
4245
4197
  if (handler && typeof handler === 'function') {
4246
- await handler.bind(this)(instance);
4198
+ await handler.bind(instance)(instance, this.name, this.value);
4247
4199
  }
4248
4200
  // search for event to render event
4249
4201
  const event = this.events?.[ComponentEventNames.Render] || undefined;
4250
4202
  if (event && typeof event === 'function') {
4251
- await event.bind(this)(instance);
4203
+ await event.bind(instance)(instance, this.name, this.value);
4252
4204
  }
4253
4205
  }
4254
4206
  await super.initialize();
@@ -4257,6 +4209,22 @@ class NgxComponentDirective extends NgxRepositoryDirective {
4257
4209
  this.changeDetectorRef.detectChanges();
4258
4210
  }
4259
4211
  }
4212
+ /**
4213
+ * @description Cleanup lifecycle hook invoked when the directive is destroyed.
4214
+ * @summary Ensures any resources allocated by the directive's media service are
4215
+ * released (DOM listeners, timers, subscriptions, etc.). Implementations should
4216
+ * keep `mediaService.destroy()` idempotent; calling it here prevents leaks when
4217
+ * components are torn down.
4218
+ * @returns {Promise<void>}
4219
+ */
4220
+ async ngOnDestroy() {
4221
+ this.value = undefined;
4222
+ this.mediaService.destroy();
4223
+ if (this.destroySubscriptions$) {
4224
+ this.destroySubscriptions$.next();
4225
+ this.destroySubscriptions$.complete();
4226
+ }
4227
+ }
4260
4228
  /**
4261
4229
  * @description Getter for the current locale context identifier.
4262
4230
  * @summary Returns the current locale identifier by calling the getLocale method.
@@ -4313,8 +4281,9 @@ class NgxComponentDirective extends NgxRepositoryDirective {
4313
4281
  async ngOnChanges(changes) {
4314
4282
  if (changes[ModelKeys.MODEL]) {
4315
4283
  const { currentValue } = changes[ModelKeys.MODEL];
4316
- if (currentValue)
4284
+ if (currentValue) {
4317
4285
  this.getModel(currentValue);
4286
+ }
4318
4287
  this.locale = this.localeContext;
4319
4288
  }
4320
4289
  // if (changes[UIKeys.HANDLERS]) {
@@ -4333,7 +4302,7 @@ class NgxComponentDirective extends NgxRepositoryDirective {
4333
4302
  if (changes[BaseComponentProps.HANDLERS]) {
4334
4303
  const { currentValue, previousValue } = changes[BaseComponentProps.HANDLERS];
4335
4304
  if (currentValue && currentValue !== previousValue)
4336
- this.parseHandlers(currentValue);
4305
+ this.parseHandlers(currentValue, this);
4337
4306
  }
4338
4307
  if (changes[UIKeys.EVENTS]) {
4339
4308
  const { currentValue, previousValue } = changes[UIKeys.EVENTS];
@@ -4341,7 +4310,7 @@ class NgxComponentDirective extends NgxRepositoryDirective {
4341
4310
  if (!this._repository) {
4342
4311
  this._repository = this.repository;
4343
4312
  }
4344
- this.parseEvents(currentValue);
4313
+ this.parseEvents(currentValue, this);
4345
4314
  // for (const key in currentValue) {
4346
4315
  // const event = currentValue[key]();
4347
4316
  // if (event && typeof event === 'function') {
@@ -4393,42 +4362,19 @@ class NgxComponentDirective extends NgxRepositoryDirective {
4393
4362
  this.mediaService.toggleClass([this.component], AngularEngineKeys.DARK_PALETTE_CLASS, this.isDarkMode);
4394
4363
  });
4395
4364
  }
4396
- /**
4397
- * @description Handles repository observation events with debouncing.
4398
- * @summary Processes repository change notifications and routes them appropriately.
4399
- * For CREATE events with a UID, handles them immediately. For other events,
4400
- * passes them to the debounced observer subject to prevent excessive updates.
4401
- *
4402
- * @param {...unknown[]} args - The repository event arguments including table, event type, and UID
4403
- * @returns {Promise<void>}
4404
- * @memberOf ListComponent
4405
- */
4406
- async handleRepositoryRefresh(...args) {
4407
- const [modelInstance, event, uid] = args;
4408
- if ([OperationKeys.CREATE, OperationKeys.DELETE].includes(event))
4409
- return this.handleObserveEvent(modelInstance, event, uid);
4410
- return this.repositoryObserverSubject.next(args);
4411
- }
4412
- async handleObserveEvent(...args) {
4413
- this.log.for(this.handleObserveEvent).info(`Repository change observed with args: ${args}`);
4414
- }
4415
- parseHandlers(handlers) {
4416
- // function isClass(value: UIFunctionLike | Constructor<NgxEventHandler>): boolean {
4417
- // return typeof value === 'function' && /^class\s/.test(String(value));
4418
- // }
4419
- Object.entries(handlers).forEach(([key, fn]) => {
4420
- if (isClassConstructor(fn)) {
4421
- const clazz = new fn();
4422
- this.handlers[key] = key in clazz ? clazz[key] : clazz.handle;
4423
- // !(Object.values(TransactionHooks).includes(key as keyof typeof TransactionHooks))
4424
- // ? clazz.handle
4425
- // : clazz[key as keyof NgxEventHandler];
4426
- }
4427
- else {
4428
- this.handlers[key] = fn;
4429
- }
4430
- });
4431
- }
4365
+ // parseHandlers(handlers: Record<string, UIFunctionLike>): void {
4366
+ // // function isClass(value: UIFunctionLike | Constructor<NgxEventHandler>): boolean {
4367
+ // // return typeof value === 'function' && /^class\s/.test(String(value));
4368
+ // // }
4369
+ // Object.entries(handlers).forEach(([key, fn]) => {
4370
+ // if (isClassConstructor<NgxEventHandler>(fn)) {
4371
+ // const clazz = new fn() as NgxEventHandler;
4372
+ // this.handlers[key] = key in clazz ? clazz[key as keyof NgxEventHandler] : clazz.handle;
4373
+ // } else {
4374
+ // this.handlers[key] = fn as UIFunctionLike;
4375
+ // }
4376
+ // });
4377
+ // }
4432
4378
  // for (const key in currentValue) {
4433
4379
  // const event = currentValue[key]();
4434
4380
  // if (event && typeof event === 'function') {
@@ -4449,17 +4395,25 @@ class NgxComponentDirective extends NgxRepositoryDirective {
4449
4395
  // }
4450
4396
  // }
4451
4397
  // }
4452
- parseEvents(events) {
4453
- Object.entries(events).forEach(([key, fn]) => {
4454
- const event = fn();
4455
- if (isClassConstructor(event)) {
4456
- this.events[key] = new event()[key] || undefined;
4457
- }
4458
- else {
4459
- this.events[key] = fn;
4460
- }
4461
- });
4462
- }
4398
+ // parseEvents<T extends DecafComponent<Model>>(
4399
+ // events: Record<string, UIFunctionLike>,
4400
+ // ): UIEventProperty {
4401
+ // const result: UIEventProperty = {};
4402
+ // Object.entries(events).forEach(([key, fn]) => {
4403
+ // const event = (fn as UIFunctionLike)();
4404
+ // if (isClassConstructor<DecafComponent<Model>>(event)) {
4405
+ // const fn = new event()[key as keyof DecafComponent<Model>] || undefined;
4406
+ // if (fn) {
4407
+ // this.events[key] = fn;
4408
+ // result[key] = fn;
4409
+ // }
4410
+ // } else {
4411
+ // this.events[key] = fn as UIFunctionLike;
4412
+ // result[key] = fn;
4413
+ // }
4414
+ // });
4415
+ // return result;
4416
+ // }
4463
4417
  /**
4464
4418
  * @description Retrieves or sets the locale context for the component.
4465
4419
  * @summary Gets the locale identifier from the locale context system. If a locale parameter
@@ -4576,11 +4530,17 @@ class NgxComponentDirective extends NgxRepositoryDirective {
4576
4530
  * @protected
4577
4531
  * @memberOf module:lib/engine/NgxComponentDirective
4578
4532
  */
4579
- parseProps(instance, skip = []) {
4533
+ parseProps(instance, skip = [AngularEngineKeys.CHILDREN]) {
4580
4534
  const props = this.props;
4581
4535
  Object.keys(instance).forEach((key) => {
4582
4536
  if (Object.keys(this.props).includes(key) && !skip.includes(key)) {
4583
4537
  this[key] = props[key];
4538
+ if (key === BaseComponentProps.HANDLERS) {
4539
+ this.parseHandlers(props[key], this);
4540
+ }
4541
+ if (key === UIKeys.EVENTS) {
4542
+ this.parseEvents(props[key], this);
4543
+ }
4584
4544
  delete props[key];
4585
4545
  }
4586
4546
  });
@@ -4745,7 +4705,7 @@ class NgxComponentDirective extends NgxRepositoryDirective {
4745
4705
  await this.initialize();
4746
4706
  }
4747
4707
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NgxComponentDirective, deps: [{ token: CPTKN }, { token: CPTKN }], target: i0.ɵɵFactoryTarget.Directive }); }
4748
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: NgxComponentDirective, isStandalone: true, inputs: { enableDarkMode: "enableDarkMode", isDarkMode: "isDarkMode", name: "name", childOf: "childOf", uid: "uid", model: "model", modelName: "modelName", modelId: "modelId", formGroup: "formGroup", value: "value", mapper: "mapper", operations: "operations", operation: "operation", row: "row", col: "col", className: "className", translatable: "translatable", locale: "locale", item: "item", props: "props", route: "route", borders: "borders", isModalChild: "isModalChild", handlers: "handlers", events: "events", propsMapperFn: "propsMapperFn" }, 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 }); }
4708
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: NgxComponentDirective, isStandalone: true, inputs: { enableDarkMode: "enableDarkMode", isDarkMode: "isDarkMode", name: "name", childOf: "childOf", uid: "uid", label: "label", formGroup: "formGroup", value: "value", mapper: "mapper", operations: "operations", operation: "operation", row: "row", col: "col", className: "className", translatable: "translatable", locale: "locale", item: "item", props: "props", route: "route", borders: "borders", isModalChild: "isModalChild", handlers: "handlers", events: "events", propsMapperFn: "propsMapperFn" }, 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 }); }
4749
4709
  }
4750
4710
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NgxComponentDirective, decorators: [{
4751
4711
  type: Directive,
@@ -4769,11 +4729,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
4769
4729
  type: Input
4770
4730
  }], uid: [{
4771
4731
  type: Input
4772
- }], model: [{
4773
- type: Input
4774
- }], modelName: [{
4775
- type: Input
4776
- }], modelId: [{
4732
+ }], label: [{
4777
4733
  type: Input
4778
4734
  }], formGroup: [{
4779
4735
  type: Input
@@ -4844,7 +4800,11 @@ class NgxPageDirective extends NgxComponentDirective {
4844
4800
  * @param {boolean} [hasMenu=true] - Whether this page should display the menu
4845
4801
  * @memberOf module:lib/engine/NgxPageDirective
4846
4802
  */
4847
- constructor(localeRoot = "NgxPageDirective", hasMenu = true) {
4803
+ constructor(
4804
+ // eslint-disable-next-line @angular-eslint/prefer-inject
4805
+ localeRoot = 'NgxPageDirective',
4806
+ // eslint-disable-next-line @angular-eslint/prefer-inject
4807
+ hasMenu = true) {
4848
4808
  super(localeRoot);
4849
4809
  /**
4850
4810
  * @description Page title text for the current view.
@@ -4855,7 +4815,7 @@ class NgxPageDirective extends NgxComponentDirective {
4855
4815
  * @default ''
4856
4816
  * @memberOf module:lib/engine/NgxPageDirective
4857
4817
  */
4858
- this.title = "";
4818
+ this.title = '';
4859
4819
  /**
4860
4820
  * @description Ionic menu controller service for menu management.
4861
4821
  * @summary Injected service that provides programmatic control over Ionic menu components.
@@ -4917,7 +4877,7 @@ class NgxPageDirective extends NgxComponentDirective {
4917
4877
  async initialize() {
4918
4878
  await super.initialize();
4919
4879
  // connect component to media service for color scheme toggling
4920
- this.currentRoute = this.router.url.replace("/", "");
4880
+ this.currentRoute = this.router.url.replace('/', '');
4921
4881
  if (!this.route)
4922
4882
  this.route = this.currentRoute;
4923
4883
  this.setPageTitle(this.currentRoute);
@@ -4936,23 +4896,23 @@ class NgxPageDirective extends NgxComponentDirective {
4936
4896
  .pipe(takeUntil$1(this.destroySubscriptions$), shareReplay$1(1))
4937
4897
  .subscribe(async (event) => {
4938
4898
  if (event instanceof NavigationEnd) {
4939
- const url = (event?.url || "").replace("/", "");
4899
+ const url = (event?.url || '').replace('/', '');
4940
4900
  this.currentRoute = url;
4941
4901
  if (this.hasMenu)
4942
- this.hasMenu = url !== "login" && url !== "";
4902
+ this.hasMenu = url !== 'login' && url !== '';
4943
4903
  this.title = this.pageTitle;
4944
4904
  await this.setPageTitle(url);
4945
4905
  this.changeDetectorRef.detectChanges();
4946
4906
  }
4947
4907
  if (event instanceof NavigationStart) {
4948
- const url = (event?.url || "").replace("/", "");
4908
+ const url = (event?.url || '').replace('/', '');
4949
4909
  if (this.hasMenu)
4950
- this.hasMenu = url !== "login" && url !== "";
4910
+ this.hasMenu = url !== 'login' && url !== '';
4951
4911
  removeFocusTrap();
4952
4912
  }
4953
4913
  });
4954
4914
  if (!this.route)
4955
- this.route = this.router.url.replace("/", "");
4915
+ this.route = this.router.url.replace('/', '');
4956
4916
  await this.menuController.enable(this.hasMenu);
4957
4917
  }
4958
4918
  /**
@@ -4970,13 +4930,13 @@ class NgxPageDirective extends NgxComponentDirective {
4970
4930
  */
4971
4931
  async setPageTitle(route, menu) {
4972
4932
  if (!route)
4973
- route = this.router.url.replace("/", "");
4933
+ route = this.router.url.replace('/', '');
4974
4934
  if (!menu)
4975
4935
  menu = this.menu;
4976
4936
  const activeMenu = menu.find((item) => item?.url?.includes(route));
4977
4937
  if (activeMenu) {
4978
- const label = `${(activeMenu?.title || activeMenu?.label || "").toLowerCase()}`;
4979
- const title = `${await this.translate(label ? "menu." + label : label)} ${this.appName ? `- ${this.appName}` : ""}`;
4938
+ const label = `${(activeMenu?.title || activeMenu?.label || '').toLowerCase()}`;
4939
+ const title = `${await this.translate(label ? 'menu.' + label : label)} ${this.appName ? `- ${this.appName}` : ''}`;
4980
4940
  this.titleService.setTitle(title);
4981
4941
  if (!this.title)
4982
4942
  this.title = title;
@@ -5058,8 +5018,7 @@ class NgxModelPageDirective extends NgxPageDirective {
5058
5018
  async initialize() {
5059
5019
  await super.initialize();
5060
5020
  await this.refresh(this.modelId);
5061
- if (!this.modelId && this.operations?.length)
5062
- this.operations = this.operations.filter((o) => [OperationKeys.UPDATE, OperationKeys.DELETE].includes(o));
5021
+ this.changeDetectorRef.detectChanges();
5063
5022
  this.getLocale(this.modelName);
5064
5023
  }
5065
5024
  // /**
@@ -5081,8 +5040,9 @@ class NgxModelPageDirective extends NgxPageDirective {
5081
5040
  * @param {string} [uid] - The unique identifier of the model to load; defaults to modelId
5082
5041
  */
5083
5042
  async refresh(uid) {
5084
- if (!uid)
5043
+ if (!uid) {
5085
5044
  uid = this.modelId;
5045
+ }
5086
5046
  try {
5087
5047
  this._repository = this.repository;
5088
5048
  switch (this.operation) {
@@ -5238,7 +5198,7 @@ class NgxModelPageDirective extends NgxPageDirective {
5238
5198
  * @param {string} uid - The unique identifier of the model instance to retrieve
5239
5199
  * @return {Promise<Model | undefined>} Promise resolving to the model instance or undefined
5240
5200
  */
5241
- async handleRead(uid, repository, modelName, pk) {
5201
+ async handleRead(uid, repository, modelName) {
5242
5202
  if (!uid) {
5243
5203
  this.log.info('No key passed to model page read operation, backing to last page');
5244
5204
  return undefined;
@@ -5248,7 +5208,7 @@ class NgxModelPageDirective extends NgxPageDirective {
5248
5208
  if (!modelName && this.model?.constructor)
5249
5209
  this.modelName = modelName = this.model.constructor.name;
5250
5210
  }
5251
- const getRepository = async (modelName, model = {}, parent = '') => {
5211
+ const getRepository = async (modelName, acc = {}, parent = '') => {
5252
5212
  if (this._repository)
5253
5213
  return this._repository;
5254
5214
  const constructor = Model.get(modelName);
@@ -5258,10 +5218,10 @@ class NgxModelPageDirective extends NgxPageDirective {
5258
5218
  const type = this.getModelPropertyType(constructor, prop);
5259
5219
  const context = getModelAndRepository(type);
5260
5220
  if (!context) {
5261
- model[prop] = {};
5262
- return getRepository(type, model, prop);
5221
+ acc[prop] = {};
5222
+ return getRepository(type, acc, prop);
5263
5223
  }
5264
- const { repository, pk, pkType } = context;
5224
+ const { repository, model, pk, pkType } = context;
5265
5225
  if (!this.pk) {
5266
5226
  this.pk = pk;
5267
5227
  this.pkType = pkType;
@@ -5273,41 +5233,18 @@ class NgxModelPageDirective extends NgxPageDirective {
5273
5233
  .select()
5274
5234
  .where(Condition.attribute(this.pk).eq(uid))
5275
5235
  .execute();
5276
- const data = query?.length ? (query?.length === 1 ? query[0] : query) : undefined;
5277
5236
  if (modelName === this.modelName) {
5278
5237
  const data = query?.length ? (query?.length === 1 ? query[0] : query) : undefined;
5279
- model[prop] = data;
5280
- this.model = Model.build({ [prop]: data }, modelName);
5238
+ acc[prop] = data;
5239
+ const model = await this.transactionEnd(data, repository, OperationKeys.READ);
5240
+ this.model = Model.build({ [prop]: model ? model : data }, modelName);
5281
5241
  }
5282
5242
  else {
5283
- model[parent] = {
5284
- ...model[parent],
5285
- [prop]: data,
5286
- };
5243
+ // model[parent] = {
5244
+ // ...model[parent],
5245
+ // [prop]: data,
5246
+ // };
5287
5247
  }
5288
- // if (data) {
5289
- // if (modelName === this.modelName) {
5290
- // model[prop] = data;
5291
- // this.model = Model.build({ [prop]: data }, modelName);
5292
- // } else {
5293
- // model[parent] = {
5294
- // ...model[parent],
5295
- // [prop]: data,
5296
- // };
5297
- // }
5298
- // }
5299
- // const data = query?.length ? (query?.length === 1 ? query[0] : query) : undefined;
5300
- // if (data) {
5301
- // if (modelName === this.modelName) {
5302
- // model[prop] = data;
5303
- // this.model = Model.build({ [prop]: data }, modelName);
5304
- // } else {
5305
- // model[parent] = {
5306
- // ...model[parent],
5307
- // [prop]: data,
5308
- // };
5309
- // }
5310
- // }
5311
5248
  }
5312
5249
  // this._data = model;
5313
5250
  // this.changeDetectorRef.detectChanges();
@@ -5422,6 +5359,14 @@ class NgxModelPageDirective extends NgxPageDirective {
5422
5359
  if (!this.modelId)
5423
5360
  this.modelId = data[pk];
5424
5361
  const model = await this.transactionBegin(data, repository, operation);
5362
+ if (!model) {
5363
+ return {
5364
+ success: false,
5365
+ aborted: true,
5366
+ model: null,
5367
+ message: 'Operation aborted by before hook',
5368
+ };
5369
+ }
5425
5370
  switch (operation) {
5426
5371
  case OperationKeys.CREATE:
5427
5372
  result = await (!Array.isArray(model)
@@ -5463,11 +5408,11 @@ class NgxModelPageDirective extends NgxPageDirective {
5463
5408
  .error(`Error during ${this.operation} operation: ${error instanceof Error ? error.message : error}`);
5464
5409
  message = error instanceof Error ? error.message : error;
5465
5410
  }
5466
- return { ...event, success, message, model: result };
5411
+ return { ...event, success, message, model: result, aborted: false };
5467
5412
  }
5468
5413
  async batchOperation(context, redirect = false) {
5469
- const { data, repository, pk } = context.context;
5470
- return data;
5414
+ // const { data, repository, pk } = context.context;
5415
+ // return data;
5471
5416
  // return await this.submit({data}, false, repository, pk);
5472
5417
  // const result: boolean[] = [];
5473
5418
  // let resultMessage = '';
@@ -5485,13 +5430,11 @@ class NgxModelPageDirective extends NgxPageDirective {
5485
5430
  // return {...{data: models}, success, message: resultMessage};
5486
5431
  }
5487
5432
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NgxModelPageDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
5488
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: NgxModelPageDirective, isStandalone: true, inputs: { modelId: "modelId", operation: "operation" }, usesInheritance: true, ngImport: i0 }); }
5433
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: NgxModelPageDirective, isStandalone: true, inputs: { operation: "operation" }, usesInheritance: true, ngImport: i0 }); }
5489
5434
  }
5490
5435
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NgxModelPageDirective, decorators: [{
5491
5436
  type: Directive
5492
- }], propDecorators: { modelId: [{
5493
- type: Input
5494
- }], operation: [{
5437
+ }], propDecorators: { operation: [{
5495
5438
  type: Input
5496
5439
  }] } });
5497
5440
 
@@ -5707,6 +5650,7 @@ class ComponentRendererComponent extends NgxRenderableComponentDirective {
5707
5650
  super(...arguments);
5708
5651
  this.children = [];
5709
5652
  this.projectable = true;
5653
+ this.pk = '';
5710
5654
  this.parent = undefined;
5711
5655
  }
5712
5656
  /**
@@ -5770,8 +5714,7 @@ class ComponentRendererComponent extends NgxRenderableComponentDirective {
5770
5714
  * @memberOf ComponentRendererComponent
5771
5715
  */
5772
5716
  createComponent(tag, globals = {}) {
5773
- const component = NgxRenderingEngine.components(tag)
5774
- ?.constructor;
5717
+ const component = NgxRenderingEngine.components(tag)?.constructor;
5775
5718
  const metadata = reflectComponentType(component);
5776
5719
  const componentInputs = metadata.inputs;
5777
5720
  const props = globals?.['item'] || globals?.['props'] || {};
@@ -5800,23 +5743,26 @@ class ComponentRendererComponent extends NgxRenderableComponentDirective {
5800
5743
  const hasRootForm = hasProperty(BaseComponentProps.PARENT_FORM);
5801
5744
  if (hasRootForm && this.parentForm)
5802
5745
  props[BaseComponentProps.PARENT_FORM] = this.parentForm;
5803
- props['className'] = (props['className'] ?
5804
- props['className'] + ' ' + this.className : this.className || "");
5746
+ props['className'] = props['className']
5747
+ ? props['className'] + ' ' + this.className
5748
+ : this.className || '';
5805
5749
  this.vcr.clear();
5806
5750
  // const projectable = (this.children?.length && this.projectable);
5807
5751
  // const template = projectable ? this.vcr.createEmbeddedView(this.inner as TemplateRef<unknown>, this.injector).rootNodes : [];
5808
- this.instance = NgxRenderingEngine.createComponent(component, props, this.injector, metadata, this.vcr, []);
5752
+ this.instance = NgxRenderingEngine.createComponent(component, { ...props, ...{ modelId: props?.modelId || this.modelId, pk: props?.pk || this.pk } }, this.injector, metadata, this.vcr, []);
5809
5753
  this.subscribeEvents(component);
5810
5754
  }
5811
5755
  createParentComponent() {
5812
5756
  const { component, inputs } = this.parent;
5813
5757
  const metadata = reflectComponentType(component);
5814
- const template = this.projectable ? this.vcr.createEmbeddedView(this.inner, this.injector).rootNodes : [];
5758
+ const template = this.projectable
5759
+ ? this.vcr.createEmbeddedView(this.inner, this.injector).rootNodes
5760
+ : [];
5815
5761
  this.instance = NgxRenderingEngine.createComponent(component, inputs, this.injector, metadata, this.vcr, template);
5816
5762
  this.subscribeEvents(component);
5817
5763
  }
5818
5764
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ComponentRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
5819
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ComponentRendererComponent, isStandalone: true, selector: "ngx-decaf-component-renderer", inputs: { tag: "tag", children: "children", projectable: "projectable", parent: "parent" }, host: { properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "<!-- Keep to avoid id conflicts -->\n\n<ng-template #componentOuter></ng-template>\n\n<ng-template #componentInner>\n @if (parent?.children?.length) {\n @for(child of parent.children; track child) {\n @if (!child.children?.length) {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n } @else {\n <ngx-decaf-component-renderer [parent]=\"child\"> </ngx-decaf-component-renderer>\n }\n }\n }\n @if (projectable) {\n @if (children?.length) {\n @for(child of children; track child) {\n @if (child.children?.length) {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n } @else {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n }\n }\n\n</ng-template>\n\n", styles: [""], dependencies: [{ kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] }); }
5765
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ComponentRendererComponent, isStandalone: true, selector: "ngx-decaf-component-renderer", inputs: { tag: "tag", children: "children", projectable: "projectable", pk: "pk", parent: "parent" }, host: { properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "<!-- Keep to avoid id conflicts -->\n\n<ng-template #componentOuter></ng-template>\n\n<ng-template #componentInner>\n @if (parent?.children?.length) {\n @for(child of parent.children; track child) {\n @if (!child.children?.length) {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n } @else {\n <ngx-decaf-component-renderer [parent]=\"child\"> </ngx-decaf-component-renderer>\n }\n }\n }\n @if (projectable) {\n @if (children?.length) {\n @for(child of children; track child) {\n @if (child.children?.length) {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n } @else {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n }\n }\n\n</ng-template>\n\n", styles: [""], dependencies: [{ kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "pk", "parent"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] }); }
5820
5766
  }
5821
5767
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ComponentRendererComponent, decorators: [{
5822
5768
  type: Component,
@@ -5828,6 +5774,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
5828
5774
  type: Input
5829
5775
  }], projectable: [{
5830
5776
  type: Input
5777
+ }], pk: [{
5778
+ type: Input
5831
5779
  }], parent: [{
5832
5780
  type: Input
5833
5781
  }] } });
@@ -5896,7 +5844,7 @@ class NgxFormFieldDirective extends NgxComponentDirective {
5896
5844
  this.checked = false;
5897
5845
  /**
5898
5846
  * @description Flag tracking if validation error event has been dispatched.
5899
- * @summary Prevents duplicate validation error events from being dispatched.
5847
+ * @summary Proverride duplicate validation error override from being dispatched.
5900
5848
  * @type {boolean}
5901
5849
  * @private
5902
5850
  */
@@ -5919,7 +5867,7 @@ class NgxFormFieldDirective extends NgxComponentDirective {
5919
5867
  * @type {function(string, ...string): string}
5920
5868
  * @public
5921
5869
  */
5922
- this.sf = sf;
5870
+ this.sf = sf$1;
5923
5871
  /**
5924
5872
  * @description Callback function invoked when the field value changes.
5925
5873
  * @summary Function registered by Angular's forms system through registerOnChange.
@@ -6047,8 +5995,9 @@ class NgxFormFieldDirective extends NgxComponentDirective {
6047
5995
  * @public
6048
5996
  */
6049
5997
  async ngOnChanges(changes) {
6050
- if (!this.initialized)
5998
+ if (!this.initialized) {
6051
5999
  await super.ngOnChanges(changes);
6000
+ }
6052
6001
  if (changes['activeFormGroupIndex'] &&
6053
6002
  this.multiple &&
6054
6003
  !changes['activeFormGroupIndex'].isFirstChange() &&
@@ -6091,7 +6040,7 @@ class NgxFormFieldDirective extends NgxComponentDirective {
6091
6040
  }
6092
6041
  /**
6093
6042
  * @description Clears the current form control value as a response to a UI interact
6094
- * @summary Set field value as undefined and prevents event propagation.
6043
+ * @summary Set field value as undefined and proverride event propagation.
6095
6044
  * @param {Event} event - The value to set
6096
6045
  * @return {void}
6097
6046
  * @public
@@ -6102,7 +6051,7 @@ class NgxFormFieldDirective extends NgxComponentDirective {
6102
6051
  this.setValue(undefined);
6103
6052
  }
6104
6053
  /**
6105
- * @description Handles IonSelect change events emitted from modal child components.
6054
+ * @description Handles IonSelect change override emitted from modal child components.
6106
6055
  * @summary Forces change detection when rendered inside a modal and synchronizes the select value with the directive state.
6107
6056
  * @param {SelectCustomEvent<SelectChangeEventDetail>} event - IonSelect change event containing the selected value.
6108
6057
  * @return {void}
@@ -6289,17 +6238,18 @@ class ModelRendererComponent extends NgxRenderableComponentDirective {
6289
6238
  * @param {string | M} model - The model to be rendered
6290
6239
  */
6291
6240
  async render(model) {
6292
- model = typeof model === "string" ? Model.build({}, model) : model;
6241
+ model = typeof model === Primitives.STRING ? Model.build({}, String(model)) : model;
6293
6242
  if (model) {
6294
6243
  this.output = model.render(this.globals || {}, this.vcr, this.injector, this.inner, this.projectable);
6295
6244
  if (this.output?.inputs)
6296
- this.rendererId = sf(AngularEngineKeys.RENDERED_ID, this.output.inputs["rendererId"]);
6245
+ this.rendererId = sf$1(AngularEngineKeys.RENDERED_ID, this.output.inputs['rendererId']);
6297
6246
  this.instance = this.output?.component;
6298
- const { operation, handlers } = this.globals || {};
6247
+ const { operation } = this.globals || {};
6299
6248
  // const {inputs} = this.output;
6300
6249
  // await this.initProps(inputs || {});
6301
- if (operation)
6250
+ if (operation) {
6302
6251
  this.operation = operation;
6252
+ }
6303
6253
  this.subscribeEvents();
6304
6254
  }
6305
6255
  }
@@ -6308,7 +6258,7 @@ class ModelRendererComponent extends NgxRenderableComponentDirective {
6308
6258
  }
6309
6259
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ModelRendererComponent, decorators: [{
6310
6260
  type: Component,
6311
- args: [{ standalone: true, imports: [], selector: "ngx-decaf-model-renderer", host: { "[attr.id]": "uid" }, template: " <!-- Keep to avoid id conflicts -->\n <div class=\"dcf-hidden\" [id]=\"uid\"></div>\n\n <ng-template #componentOuter></ng-template>\n <!-- <ng-template #inner>\n <div class=\"dcf-grid dcf-grid-small dcf-model-renderer-component dcf-child-width-1-1\" [id]=\"rendererId || ''\">\n @for (child of output?.children; track child) {\n @if (child?.children?.length) {\n <ngx-decaf-component-renderer [parent]=\"child\" />\n } @else {\n <ng-container\n #childComponents\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n </div>\n </ng-template> -->\n" }]
6261
+ args: [{ standalone: true, imports: [], selector: 'ngx-decaf-model-renderer', host: { '[attr.id]': 'uid' }, template: " <!-- Keep to avoid id conflicts -->\n <div class=\"dcf-hidden\" [id]=\"uid\"></div>\n\n <ng-template #componentOuter></ng-template>\n <!-- <ng-template #inner>\n <div class=\"dcf-grid dcf-grid-small dcf-model-renderer-component dcf-child-width-1-1\" [id]=\"rendererId || ''\">\n @for (child of output?.children; track child) {\n @if (child?.children?.length) {\n <ngx-decaf-component-renderer [parent]=\"child\" />\n } @else {\n <ng-container\n #childComponents\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n </div>\n </ng-template> -->\n" }]
6312
6262
  }], propDecorators: { projectable: [{
6313
6263
  type: Input
6314
6264
  }] } });
@@ -6453,10 +6403,12 @@ class NgxParentComponentDirective extends NgxComponentDirective {
6453
6403
  }
6454
6404
  async initialize(model) {
6455
6405
  await super.initialize();
6456
- if (model)
6406
+ if (model) {
6457
6407
  this.model = model;
6458
- if (this.model && !this.repository)
6408
+ }
6409
+ if (this.model && !this.repository) {
6459
6410
  this._repository = this.repository;
6411
+ }
6460
6412
  }
6461
6413
  async ngOnDestroy() {
6462
6414
  await super.ngOnDestroy();
@@ -6713,9 +6665,8 @@ let ModalComponent = class ModalComponent extends NgxParentComponentDirective {
6713
6665
  * @returns {Promise<void>} - A promise that resolves when initialization is complete.
6714
6666
  */
6715
6667
  async ngOnInit() {
6716
- if (this.inlineContent && typeof this.inlineContent === Primitives.STRING)
6717
- this.inlineContent = this.domSanitizer.bypassSecurityTrustHtml(this.inlineContent);
6718
6668
  await super.initialize();
6669
+ this.parseInlineContent();
6719
6670
  }
6720
6671
  /**
6721
6672
  * @description Initializes the modal with the provided options.
@@ -6737,6 +6688,14 @@ let ModalComponent = class ModalComponent extends NgxParentComponentDirective {
6737
6688
  if (['primary', 'secondary', 'tertiary', 'danger', 'medium', 'dark'].includes(this.headerBackground))
6738
6689
  this.iconColor = 'light';
6739
6690
  }
6691
+ parseInlineContent() {
6692
+ if (this.inlineContent) {
6693
+ if (this.inlineContent instanceof HTMLElement) {
6694
+ this.inlineContent = this.inlineContent.outerHTML;
6695
+ }
6696
+ this.inlineContent = this.domSanitizer.bypassSecurityTrustHtml(this.inlineContent);
6697
+ }
6698
+ }
6740
6699
  /**
6741
6700
  * @description Creates and presents the modal.
6742
6701
  * @summary Initializes the modal with the provided properties and displays it.
@@ -6756,6 +6715,7 @@ let ModalComponent = class ModalComponent extends NgxParentComponentDirective {
6756
6715
  * @returns {Promise<void>} - A promise that resolves when the modal is presented.
6757
6716
  */
6758
6717
  async present() {
6718
+ this.parseInlineContent();
6759
6719
  this.isOpen = true;
6760
6720
  this.changeDetectorRef.detectChanges();
6761
6721
  }
@@ -6816,7 +6776,7 @@ let ModalComponent = class ModalComponent extends NgxParentComponentDirective {
6816
6776
  await modal.dismiss(event?.data || undefined, ActionRoles.confirm);
6817
6777
  }
6818
6778
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6819
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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", expandable: "expandable", lightBox: "lightBox", headerTransparent: "headerTransparent", headerBackground: "headerBackground", showHeader: "showHeader", showCloseButton: "showCloseButton" }, 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 [class]=\"'dcf-modal-component ' + className\"\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-fullscreen-expanded]=\"expanded\"\n [class.dcf-lightbox-modal]=\"lightBox\"\n [class.dcf-modal-no-header]=\"!showHeader\"\n [class.dcf-header-transparent]=\"headerTransparent\"\n [class.dcf-no-title]=\"!title?.length\"\n #component\n>\n <ng-template>\n <ion-header>\n <ion-toolbar [color]=\"headerBackground\">\n @if (title?.length) {\n <ion-title>{{ title | translate }}</ion-title>\n }\n <ion-buttons slot=\"end\">\n @if (expandable && !fullscreen) {\n <ion-button\n fill=\"clear\"\n size=\"small\"\n type=\"button\"\n class=\"dcf-button-expand\"\n (click)=\"handleExpandToggle()\"\n >\n <ngx-decaf-icon\n [color]=\"iconColor\"\n [name]=\"expanded ? 'ti-maximize-off' : 'ti-maximize'\"\n />\n </ion-button>\n }\n @if (showCloseButton) {\n <ion-button size=\"small\" type=\"button\" class=\"dcf-button-close\" (click)=\"cancel()\">\n <ngx-decaf-icon [color]=\"iconColor\" name=\"ti-x\" />\n </ion-button>\n }\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n\n <ion-content>\n <section class=\"dcf-modal-body\" [class.dcf-has-title]=\"title?.length\">\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 class=\"dcf-modal-content\" id=\"dcf-modal-content\" [innerHTML]=\"inlineContent\"></div>\n }\n @if (!tag && model) {\n <ngx-decaf-model-renderer\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"globals\"\n />\n } @else 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 class=\"dcf-modal-content\" id=\"dcf-modal-content\" [innerHTML]=\"inlineContent\"></div>\n }\n }\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".dcf-modal-component{--border-radius: var(--dcf-border-radius)}.dcf-modal-component.dcf-modal-confirm{top:-100px;--max-width: 320px;--max-height: 35vh}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-title{font-weight:500;font-size:1.125rem;line-height:1.75rem;color:var(--dcf-color-gray-8)}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-delete .dcf-title{color:var(--dcf-color-danger)}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-content{font-weight:400;font-size:.935rem;line-height:1.375rem;color:var(--dcf-color-gray-6);margin-top:1rem}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-buttons-grid{position:absolute;bottom:2rem;right:1rem}.dcf-modal-component ::ng-deep form .dcf-buttons-grid{align-content:center!important;justify-content:center;padding-top:1rem}.dcf-modal-component ion-header{box-shadow:none!important;border-bottom:1px solid var(--dcf-color-gray-2)}.dcf-modal-component ion-button.dcf-button-close{--background: var(--dcf-color-light) !important;--border-radius: var(--dcf-border-radius-small) !important}.dcf-modal-component.dcf-modal-no-header ion-header,.dcf-modal-component.dcf-no-title ion-header{box-shadow:none;border-color:transparent!important}@media (max-width: 768px){.dcf-modal-component .dcf-button-expand{display:none!important}}.dcf-modal-component.dcf-modal-select-interface{--min-width: 300px;--max-width: 500px;--max-height: 50%;--border-radius: var(--dcf-border-radius)}.dcf-modal-component.dcf-modal-select-interface .dcf-modal-body{--max-height: 60%;max-height:60%;padding:0px var(--dcf-padding-small)!important}.dcf-modal-component.dcf-modal-expand{--min-height: 50%;--min-width: 75%;--max-width: 100%}.dcf-modal-component.dcf-fullscreen-expanded,.dcf-modal-component.dcf-fullscreen-modal{--height: 100%;--width: 100%;--max-width: 100%;--border-radius: 0}.dcf-modal-component.dcf-fullscreen-expanded.dcf-header-transparent,.dcf-modal-component.dcf-fullscreen-modal.dcf-header-transparent{padding-left:2rem;padding-bottom:2rem;padding-right:1rem}.dcf-modal-component.dcf-fullscreen-expanded:not(.dcf-header-transparent).dcf-no-title ion-header ion-button,.dcf-modal-component.dcf-fullscreen-modal:not(.dcf-header-transparent).dcf-no-title ion-header ion-button{transform:translate(-5px,5px)}.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}.dcf-modal-component.dcf-lightbox-modal.dcf-fullscreen-modal{padding:var(--dcf-padding-small)}.dcf-modal-component.dcf-header-transparent ion-header{box-shadow:none!important;border-bottom:none!important}.dcf-modal-component.dcf-header-transparent ion-title{width:calc(100% + 10px);position:relative;top:1.25rem;background:#fff;height:50px!important}.dcf-modal-component.dcf-header-transparent ion-buttons ion-button:not(:last-of-type){position:relative;right:1px}.dcf-modal-component.dcf-header-transparent ion-content[part=background],.dcf-modal-component.dcf-header-transparent ion-content::part(background){border-radius:var(--dcf-border-radius)!important}.dcf-modal-component.dcf-header-transparent .dcf-modal-body.dcf-has-title{padding-top:2rem!important}.dcf-modal-component.dcf-header-transparent,.dcf-modal-component.dcf-lightbox-modal{--background: transparent;--box-shadow: none !important}@media (max-width: 767px){.dcf-modal-component.dcf-header-transparent,.dcf-modal-component.dcf-lightbox-modal{padding:var(--dcf-padding-xsmall)}}.dcf-modal-component.dcf-header-transparent ion-header,.dcf-modal-component.dcf-lightbox-modal ion-header{box-shadow:none!important;border-color:transparent!important;padding:unset!important;margin:unset!important;height:30px}.dcf-modal-component.dcf-header-transparent ion-header ion-buttons,.dcf-modal-component.dcf-lightbox-modal ion-header ion-buttons{background:var(--dcf-color-gray-2)!important;border-radius:var(--dcf-border-radius)!important;box-shadow:var(--dcf-box-shadow)!important}.dcf-modal-component.dcf-header-transparent ion-header ion-button,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button{--background: transparent !important;margin:0!important;width:35px!important;height:25px!important}.dcf-modal-component.dcf-header-transparent ion-header ion-button *,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button *{margin:-5px}.dcf-modal-component.dcf-header-transparent ion-header ion-button ngx-decaf-icon,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button ngx-decaf-icon{transform:translate(-1px)!important}.dcf-modal-component.dcf-header-transparent ion-header ion-button ion-icon,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button ion-icon{font-size:1.15rem!important;color:var(--dcf-color-gray-5)}.dcf-modal-component.dcf-header-transparent ion-header ion-toolbar,.dcf-modal-component.dcf-lightbox-modal ion-header ion-toolbar{--background: transparent !important;padding:unset!important;margin:unset!important}.dcf-modal-component.dcf-header-transparent ion-content,.dcf-modal-component.dcf-lightbox-modal ion-content{max-width:calc(100% - 10px)}.dcf-modal-component.dcf-header-transparent .dcf-modal-body,.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body{background:#fff!important;padding:2px 0 0;border-radius:var(--dcf-border-radius)}.dcf-modal-component.dcf-header-transparent .dcf-modal-body>div,.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body>div{border-radius:var(--dcf-border-radius)!important;max-width:calc(100% - 5px)}.dcf-modal-component:not(.dcf-lightbox-modal) .dcf-modal-body{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: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { 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" }] }); }
6779
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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", expandable: "expandable", lightBox: "lightBox", headerTransparent: "headerTransparent", headerBackground: "headerBackground", showHeader: "showHeader", showCloseButton: "showCloseButton" }, 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 [class]=\"'dcf-modal-component ' + className\"\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-fullscreen-expanded]=\"expanded\"\n [class.dcf-lightbox-modal]=\"lightBox\"\n [class.dcf-modal-no-header]=\"!showHeader\"\n [class.dcf-header-transparent]=\"headerTransparent\"\n [class.dcf-no-title]=\"!title?.length\"\n #component\n>\n <ng-template>\n <ion-header>\n <ion-toolbar [color]=\"headerBackground\">\n @if (title?.length) {\n <ion-title>{{ title | translate }}</ion-title>\n }\n <ion-buttons slot=\"end\">\n @if (expandable && !fullscreen) {\n <ion-button\n fill=\"clear\"\n size=\"small\"\n type=\"button\"\n class=\"dcf-button-expand\"\n (click)=\"handleExpandToggle()\"\n >\n <ngx-decaf-icon\n [color]=\"iconColor\"\n [name]=\"expanded ? 'ti-maximize-off' : 'ti-maximize'\"\n />\n </ion-button>\n }\n @if (showCloseButton) {\n <ion-button size=\"small\" type=\"button\" class=\"dcf-button-close\" (click)=\"cancel()\">\n <ngx-decaf-icon [color]=\"iconColor\" name=\"ti-x\" />\n </ion-button>\n }\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n\n <ion-content>\n <section class=\"dcf-modal-body\" [class.dcf-has-title]=\"title?.length\">\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 class=\"dcf-modal-content\" id=\"dcf-modal-content\" [innerHTML]=\"inlineContent\"></div>\n }\n @if (!tag && model) {\n <ngx-decaf-model-renderer\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"globals\"\n />\n } @else 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 class=\"dcf-modal-content\" id=\"dcf-modal-content\" [innerHTML]=\"inlineContent\"></div>\n }\n }\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".dcf-modal-component{--border-radius: var(--dcf-border-radius)}.dcf-modal-component.dcf-modal-confirm{top:-100px;--max-width: 320px;--max-height: 35vh}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-title{font-weight:500;font-size:1.125rem;line-height:1.75rem;color:var(--dcf-color-gray-8)}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-delete .dcf-title{color:var(--dcf-color-danger)}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-content{font-weight:400;font-size:.935rem;line-height:1.375rem;color:var(--dcf-color-gray-6);margin-top:1rem}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-buttons-grid{position:absolute;bottom:2rem;right:1rem}.dcf-modal-component ::ng-deep form .dcf-buttons-grid{align-content:center!important;justify-content:center;padding-top:1rem}.dcf-modal-component ion-header{box-shadow:none!important;border-bottom:1px solid var(--dcf-color-gray-2)}.dcf-modal-component ion-button.dcf-button-close{--background: var(--dcf-color-light) !important;--border-radius: var(--dcf-border-radius-small) !important}.dcf-modal-component.dcf-modal-no-header ion-header,.dcf-modal-component.dcf-no-title ion-header{box-shadow:none;border-color:transparent!important}.dcf-modal-component .dcf-modal-content ::ng-deep pre{border:1px solid var(--dcf-color-gray-2);white-space:pre-wrap;overflow-wrap:anywhere;background:rgba(var(--dcf-color-warning-rgb),.175)!important;padding:var(--dcf-padding);border-radius:var(--dcf-border-radius-small);font-size:.9rem!important;font-weight:500;margin-top:2rem}@media (max-width: 768px){.dcf-modal-component .dcf-button-expand{display:none!important}}.dcf-modal-component.dcf-modal-select-interface{--min-width: 300px;--max-width: 500px;--max-height: 50%;--border-radius: var(--dcf-border-radius)}.dcf-modal-component.dcf-modal-select-interface .dcf-modal-body{--max-height: 60%;max-height:60%;padding:0px var(--dcf-padding-small)!important}.dcf-modal-component.dcf-modal-expand{--min-height: 50%;--min-width: 75%;--max-width: 100%}.dcf-modal-component.dcf-fullscreen-expanded,.dcf-modal-component.dcf-fullscreen-modal{--height: 100%;--width: 100%;--max-width: 100%;--border-radius: 0}.dcf-modal-component.dcf-fullscreen-expanded.dcf-header-transparent,.dcf-modal-component.dcf-fullscreen-modal.dcf-header-transparent{padding-left:2rem;padding-bottom:2rem;padding-right:1rem}.dcf-modal-component.dcf-fullscreen-expanded:not(.dcf-header-transparent).dcf-no-title ion-header ion-button,.dcf-modal-component.dcf-fullscreen-modal:not(.dcf-header-transparent).dcf-no-title ion-header ion-button{transform:translate(-5px,5px)}.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}.dcf-modal-component.dcf-lightbox-modal.dcf-fullscreen-modal{padding:var(--dcf-padding-small)}.dcf-modal-component.dcf-header-transparent ion-header{box-shadow:none!important;border-bottom:none!important}.dcf-modal-component.dcf-header-transparent ion-title{width:calc(100% + 10px);position:relative;top:1.25rem;background:#fff;height:50px!important}.dcf-modal-component.dcf-header-transparent ion-buttons ion-button:not(:last-of-type){position:relative;right:1px}.dcf-modal-component.dcf-header-transparent ion-content[part=background],.dcf-modal-component.dcf-header-transparent ion-content::part(background){border-radius:var(--dcf-border-radius)!important}.dcf-modal-component.dcf-header-transparent .dcf-modal-body.dcf-has-title{padding-top:2rem!important}.dcf-modal-component.dcf-header-transparent,.dcf-modal-component.dcf-lightbox-modal{--background: transparent;--box-shadow: none !important}@media (max-width: 767px){.dcf-modal-component.dcf-header-transparent,.dcf-modal-component.dcf-lightbox-modal{padding:var(--dcf-padding-xsmall)}}.dcf-modal-component.dcf-header-transparent ion-header,.dcf-modal-component.dcf-lightbox-modal ion-header{box-shadow:none!important;border-color:transparent!important;padding:unset!important;margin:unset!important;height:30px}.dcf-modal-component.dcf-header-transparent ion-header ion-buttons,.dcf-modal-component.dcf-lightbox-modal ion-header ion-buttons{background:var(--dcf-color-gray-2)!important;border-radius:var(--dcf-border-radius)!important;box-shadow:var(--dcf-box-shadow)!important}.dcf-modal-component.dcf-header-transparent ion-header ion-button,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button{--background: transparent !important;margin:0!important;width:35px!important;height:25px!important}.dcf-modal-component.dcf-header-transparent ion-header ion-button *,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button *{margin:-5px}.dcf-modal-component.dcf-header-transparent ion-header ion-button ngx-decaf-icon,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button ngx-decaf-icon{transform:translate(-1px)!important}.dcf-modal-component.dcf-header-transparent ion-header ion-button ion-icon,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button ion-icon{font-size:1.15rem!important;color:var(--dcf-color-gray-5)}.dcf-modal-component.dcf-header-transparent ion-header ion-toolbar,.dcf-modal-component.dcf-lightbox-modal ion-header ion-toolbar{--background: transparent !important;padding:unset!important;margin:unset!important}.dcf-modal-component.dcf-header-transparent ion-content,.dcf-modal-component.dcf-lightbox-modal ion-content{max-width:calc(100% - 10px)}.dcf-modal-component.dcf-header-transparent .dcf-modal-body,.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body{background:#fff!important;padding:2px 0 0;border-radius:var(--dcf-border-radius)}.dcf-modal-component.dcf-header-transparent .dcf-modal-body>div,.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body>div{border-radius:var(--dcf-border-radius)!important;max-width:calc(100% - 5px)}.dcf-modal-component:not(.dcf-lightbox-modal) .dcf-modal-body{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", "pk", "parent"] }, { kind: "component", type: ModelRendererComponent, selector: "ngx-decaf-model-renderer", inputs: ["projectable"] }, { kind: "component", type: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { 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" }] }); }
6820
6780
  };
6821
6781
  ModalComponent = __decorate([
6822
6782
  Dynamic(),
@@ -6837,7 +6797,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
6837
6797
  IonHeader,
6838
6798
  IonTitle,
6839
6799
  IonToolbar,
6840
- ], host: { '[attr.id]': 'uid' }, template: "<ion-modal\n [id]=\"uid\"\n [class]=\"'dcf-modal-component ' + className\"\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-fullscreen-expanded]=\"expanded\"\n [class.dcf-lightbox-modal]=\"lightBox\"\n [class.dcf-modal-no-header]=\"!showHeader\"\n [class.dcf-header-transparent]=\"headerTransparent\"\n [class.dcf-no-title]=\"!title?.length\"\n #component\n>\n <ng-template>\n <ion-header>\n <ion-toolbar [color]=\"headerBackground\">\n @if (title?.length) {\n <ion-title>{{ title | translate }}</ion-title>\n }\n <ion-buttons slot=\"end\">\n @if (expandable && !fullscreen) {\n <ion-button\n fill=\"clear\"\n size=\"small\"\n type=\"button\"\n class=\"dcf-button-expand\"\n (click)=\"handleExpandToggle()\"\n >\n <ngx-decaf-icon\n [color]=\"iconColor\"\n [name]=\"expanded ? 'ti-maximize-off' : 'ti-maximize'\"\n />\n </ion-button>\n }\n @if (showCloseButton) {\n <ion-button size=\"small\" type=\"button\" class=\"dcf-button-close\" (click)=\"cancel()\">\n <ngx-decaf-icon [color]=\"iconColor\" name=\"ti-x\" />\n </ion-button>\n }\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n\n <ion-content>\n <section class=\"dcf-modal-body\" [class.dcf-has-title]=\"title?.length\">\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 class=\"dcf-modal-content\" id=\"dcf-modal-content\" [innerHTML]=\"inlineContent\"></div>\n }\n @if (!tag && model) {\n <ngx-decaf-model-renderer\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"globals\"\n />\n } @else 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 class=\"dcf-modal-content\" id=\"dcf-modal-content\" [innerHTML]=\"inlineContent\"></div>\n }\n }\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".dcf-modal-component{--border-radius: var(--dcf-border-radius)}.dcf-modal-component.dcf-modal-confirm{top:-100px;--max-width: 320px;--max-height: 35vh}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-title{font-weight:500;font-size:1.125rem;line-height:1.75rem;color:var(--dcf-color-gray-8)}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-delete .dcf-title{color:var(--dcf-color-danger)}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-content{font-weight:400;font-size:.935rem;line-height:1.375rem;color:var(--dcf-color-gray-6);margin-top:1rem}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-buttons-grid{position:absolute;bottom:2rem;right:1rem}.dcf-modal-component ::ng-deep form .dcf-buttons-grid{align-content:center!important;justify-content:center;padding-top:1rem}.dcf-modal-component ion-header{box-shadow:none!important;border-bottom:1px solid var(--dcf-color-gray-2)}.dcf-modal-component ion-button.dcf-button-close{--background: var(--dcf-color-light) !important;--border-radius: var(--dcf-border-radius-small) !important}.dcf-modal-component.dcf-modal-no-header ion-header,.dcf-modal-component.dcf-no-title ion-header{box-shadow:none;border-color:transparent!important}@media (max-width: 768px){.dcf-modal-component .dcf-button-expand{display:none!important}}.dcf-modal-component.dcf-modal-select-interface{--min-width: 300px;--max-width: 500px;--max-height: 50%;--border-radius: var(--dcf-border-radius)}.dcf-modal-component.dcf-modal-select-interface .dcf-modal-body{--max-height: 60%;max-height:60%;padding:0px var(--dcf-padding-small)!important}.dcf-modal-component.dcf-modal-expand{--min-height: 50%;--min-width: 75%;--max-width: 100%}.dcf-modal-component.dcf-fullscreen-expanded,.dcf-modal-component.dcf-fullscreen-modal{--height: 100%;--width: 100%;--max-width: 100%;--border-radius: 0}.dcf-modal-component.dcf-fullscreen-expanded.dcf-header-transparent,.dcf-modal-component.dcf-fullscreen-modal.dcf-header-transparent{padding-left:2rem;padding-bottom:2rem;padding-right:1rem}.dcf-modal-component.dcf-fullscreen-expanded:not(.dcf-header-transparent).dcf-no-title ion-header ion-button,.dcf-modal-component.dcf-fullscreen-modal:not(.dcf-header-transparent).dcf-no-title ion-header ion-button{transform:translate(-5px,5px)}.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}.dcf-modal-component.dcf-lightbox-modal.dcf-fullscreen-modal{padding:var(--dcf-padding-small)}.dcf-modal-component.dcf-header-transparent ion-header{box-shadow:none!important;border-bottom:none!important}.dcf-modal-component.dcf-header-transparent ion-title{width:calc(100% + 10px);position:relative;top:1.25rem;background:#fff;height:50px!important}.dcf-modal-component.dcf-header-transparent ion-buttons ion-button:not(:last-of-type){position:relative;right:1px}.dcf-modal-component.dcf-header-transparent ion-content[part=background],.dcf-modal-component.dcf-header-transparent ion-content::part(background){border-radius:var(--dcf-border-radius)!important}.dcf-modal-component.dcf-header-transparent .dcf-modal-body.dcf-has-title{padding-top:2rem!important}.dcf-modal-component.dcf-header-transparent,.dcf-modal-component.dcf-lightbox-modal{--background: transparent;--box-shadow: none !important}@media (max-width: 767px){.dcf-modal-component.dcf-header-transparent,.dcf-modal-component.dcf-lightbox-modal{padding:var(--dcf-padding-xsmall)}}.dcf-modal-component.dcf-header-transparent ion-header,.dcf-modal-component.dcf-lightbox-modal ion-header{box-shadow:none!important;border-color:transparent!important;padding:unset!important;margin:unset!important;height:30px}.dcf-modal-component.dcf-header-transparent ion-header ion-buttons,.dcf-modal-component.dcf-lightbox-modal ion-header ion-buttons{background:var(--dcf-color-gray-2)!important;border-radius:var(--dcf-border-radius)!important;box-shadow:var(--dcf-box-shadow)!important}.dcf-modal-component.dcf-header-transparent ion-header ion-button,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button{--background: transparent !important;margin:0!important;width:35px!important;height:25px!important}.dcf-modal-component.dcf-header-transparent ion-header ion-button *,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button *{margin:-5px}.dcf-modal-component.dcf-header-transparent ion-header ion-button ngx-decaf-icon,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button ngx-decaf-icon{transform:translate(-1px)!important}.dcf-modal-component.dcf-header-transparent ion-header ion-button ion-icon,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button ion-icon{font-size:1.15rem!important;color:var(--dcf-color-gray-5)}.dcf-modal-component.dcf-header-transparent ion-header ion-toolbar,.dcf-modal-component.dcf-lightbox-modal ion-header ion-toolbar{--background: transparent !important;padding:unset!important;margin:unset!important}.dcf-modal-component.dcf-header-transparent ion-content,.dcf-modal-component.dcf-lightbox-modal ion-content{max-width:calc(100% - 10px)}.dcf-modal-component.dcf-header-transparent .dcf-modal-body,.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body{background:#fff!important;padding:2px 0 0;border-radius:var(--dcf-border-radius)}.dcf-modal-component.dcf-header-transparent .dcf-modal-body>div,.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body>div{border-radius:var(--dcf-border-radius)!important;max-width:calc(100% - 5px)}.dcf-modal-component:not(.dcf-lightbox-modal) .dcf-modal-body{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"] }]
6800
+ ], host: { '[attr.id]': 'uid' }, template: "<ion-modal\n [id]=\"uid\"\n [class]=\"'dcf-modal-component ' + className\"\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-fullscreen-expanded]=\"expanded\"\n [class.dcf-lightbox-modal]=\"lightBox\"\n [class.dcf-modal-no-header]=\"!showHeader\"\n [class.dcf-header-transparent]=\"headerTransparent\"\n [class.dcf-no-title]=\"!title?.length\"\n #component\n>\n <ng-template>\n <ion-header>\n <ion-toolbar [color]=\"headerBackground\">\n @if (title?.length) {\n <ion-title>{{ title | translate }}</ion-title>\n }\n <ion-buttons slot=\"end\">\n @if (expandable && !fullscreen) {\n <ion-button\n fill=\"clear\"\n size=\"small\"\n type=\"button\"\n class=\"dcf-button-expand\"\n (click)=\"handleExpandToggle()\"\n >\n <ngx-decaf-icon\n [color]=\"iconColor\"\n [name]=\"expanded ? 'ti-maximize-off' : 'ti-maximize'\"\n />\n </ion-button>\n }\n @if (showCloseButton) {\n <ion-button size=\"small\" type=\"button\" class=\"dcf-button-close\" (click)=\"cancel()\">\n <ngx-decaf-icon [color]=\"iconColor\" name=\"ti-x\" />\n </ion-button>\n }\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n\n <ion-content>\n <section class=\"dcf-modal-body\" [class.dcf-has-title]=\"title?.length\">\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 class=\"dcf-modal-content\" id=\"dcf-modal-content\" [innerHTML]=\"inlineContent\"></div>\n }\n @if (!tag && model) {\n <ngx-decaf-model-renderer\n (onIonChange)=\"handleEvent($event)\"\n (listenEvent)=\"handleEvent($event)\"\n [model]=\"model\"\n [globals]=\"globals\"\n />\n } @else 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 class=\"dcf-modal-content\" id=\"dcf-modal-content\" [innerHTML]=\"inlineContent\"></div>\n }\n }\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".dcf-modal-component{--border-radius: var(--dcf-border-radius)}.dcf-modal-component.dcf-modal-confirm{top:-100px;--max-width: 320px;--max-height: 35vh}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-title{font-weight:500;font-size:1.125rem;line-height:1.75rem;color:var(--dcf-color-gray-8)}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-delete .dcf-title{color:var(--dcf-color-danger)}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-content{font-weight:400;font-size:.935rem;line-height:1.375rem;color:var(--dcf-color-gray-6);margin-top:1rem}.dcf-modal-component.dcf-modal-confirm ::ng-deep .dcf-buttons-grid{position:absolute;bottom:2rem;right:1rem}.dcf-modal-component ::ng-deep form .dcf-buttons-grid{align-content:center!important;justify-content:center;padding-top:1rem}.dcf-modal-component ion-header{box-shadow:none!important;border-bottom:1px solid var(--dcf-color-gray-2)}.dcf-modal-component ion-button.dcf-button-close{--background: var(--dcf-color-light) !important;--border-radius: var(--dcf-border-radius-small) !important}.dcf-modal-component.dcf-modal-no-header ion-header,.dcf-modal-component.dcf-no-title ion-header{box-shadow:none;border-color:transparent!important}.dcf-modal-component .dcf-modal-content ::ng-deep pre{border:1px solid var(--dcf-color-gray-2);white-space:pre-wrap;overflow-wrap:anywhere;background:rgba(var(--dcf-color-warning-rgb),.175)!important;padding:var(--dcf-padding);border-radius:var(--dcf-border-radius-small);font-size:.9rem!important;font-weight:500;margin-top:2rem}@media (max-width: 768px){.dcf-modal-component .dcf-button-expand{display:none!important}}.dcf-modal-component.dcf-modal-select-interface{--min-width: 300px;--max-width: 500px;--max-height: 50%;--border-radius: var(--dcf-border-radius)}.dcf-modal-component.dcf-modal-select-interface .dcf-modal-body{--max-height: 60%;max-height:60%;padding:0px var(--dcf-padding-small)!important}.dcf-modal-component.dcf-modal-expand{--min-height: 50%;--min-width: 75%;--max-width: 100%}.dcf-modal-component.dcf-fullscreen-expanded,.dcf-modal-component.dcf-fullscreen-modal{--height: 100%;--width: 100%;--max-width: 100%;--border-radius: 0}.dcf-modal-component.dcf-fullscreen-expanded.dcf-header-transparent,.dcf-modal-component.dcf-fullscreen-modal.dcf-header-transparent{padding-left:2rem;padding-bottom:2rem;padding-right:1rem}.dcf-modal-component.dcf-fullscreen-expanded:not(.dcf-header-transparent).dcf-no-title ion-header ion-button,.dcf-modal-component.dcf-fullscreen-modal:not(.dcf-header-transparent).dcf-no-title ion-header ion-button{transform:translate(-5px,5px)}.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}.dcf-modal-component.dcf-lightbox-modal.dcf-fullscreen-modal{padding:var(--dcf-padding-small)}.dcf-modal-component.dcf-header-transparent ion-header{box-shadow:none!important;border-bottom:none!important}.dcf-modal-component.dcf-header-transparent ion-title{width:calc(100% + 10px);position:relative;top:1.25rem;background:#fff;height:50px!important}.dcf-modal-component.dcf-header-transparent ion-buttons ion-button:not(:last-of-type){position:relative;right:1px}.dcf-modal-component.dcf-header-transparent ion-content[part=background],.dcf-modal-component.dcf-header-transparent ion-content::part(background){border-radius:var(--dcf-border-radius)!important}.dcf-modal-component.dcf-header-transparent .dcf-modal-body.dcf-has-title{padding-top:2rem!important}.dcf-modal-component.dcf-header-transparent,.dcf-modal-component.dcf-lightbox-modal{--background: transparent;--box-shadow: none !important}@media (max-width: 767px){.dcf-modal-component.dcf-header-transparent,.dcf-modal-component.dcf-lightbox-modal{padding:var(--dcf-padding-xsmall)}}.dcf-modal-component.dcf-header-transparent ion-header,.dcf-modal-component.dcf-lightbox-modal ion-header{box-shadow:none!important;border-color:transparent!important;padding:unset!important;margin:unset!important;height:30px}.dcf-modal-component.dcf-header-transparent ion-header ion-buttons,.dcf-modal-component.dcf-lightbox-modal ion-header ion-buttons{background:var(--dcf-color-gray-2)!important;border-radius:var(--dcf-border-radius)!important;box-shadow:var(--dcf-box-shadow)!important}.dcf-modal-component.dcf-header-transparent ion-header ion-button,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button{--background: transparent !important;margin:0!important;width:35px!important;height:25px!important}.dcf-modal-component.dcf-header-transparent ion-header ion-button *,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button *{margin:-5px}.dcf-modal-component.dcf-header-transparent ion-header ion-button ngx-decaf-icon,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button ngx-decaf-icon{transform:translate(-1px)!important}.dcf-modal-component.dcf-header-transparent ion-header ion-button ion-icon,.dcf-modal-component.dcf-lightbox-modal ion-header ion-button ion-icon{font-size:1.15rem!important;color:var(--dcf-color-gray-5)}.dcf-modal-component.dcf-header-transparent ion-header ion-toolbar,.dcf-modal-component.dcf-lightbox-modal ion-header ion-toolbar{--background: transparent !important;padding:unset!important;margin:unset!important}.dcf-modal-component.dcf-header-transparent ion-content,.dcf-modal-component.dcf-lightbox-modal ion-content{max-width:calc(100% - 10px)}.dcf-modal-component.dcf-header-transparent .dcf-modal-body,.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body{background:#fff!important;padding:2px 0 0;border-radius:var(--dcf-border-radius)}.dcf-modal-component.dcf-header-transparent .dcf-modal-body>div,.dcf-modal-component.dcf-lightbox-modal .dcf-modal-body>div{border-radius:var(--dcf-border-radius)!important;max-width:calc(100% - 5px)}.dcf-modal-component:not(.dcf-lightbox-modal) .dcf-modal-body{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"] }]
6841
6801
  }], ctorParameters: () => [], propDecorators: { modal: [{
6842
6802
  type: ViewChild,
6843
6803
  args: ['component']
@@ -6882,7 +6842,6 @@ let ModalConfirmComponent = class ModalConfirmComponent extends ModalComponent {
6882
6842
  });
6883
6843
  this.translatable = false;
6884
6844
  }
6885
- console.log(this.title);
6886
6845
  if (!this.message) {
6887
6846
  this.message = await this.translate(`${this.locale}.confirm.operations.${role}.message`, {
6888
6847
  '0': uid,
@@ -6995,7 +6954,7 @@ async function getNgxInlineModal(inlineContent, props = {}, injector) {
6995
6954
  props,
6996
6955
  ...{
6997
6956
  inlineContent: inlineContent ?? '<div></div>',
6998
- className: `${props?.className ?? ''} dcf-modal dcf-modal-expand`,
6957
+ className: `${props?.className ?? ''} dcf-modal`,
6999
6958
  },
7000
6959
  }, {}, injector || undefined);
7001
6960
  }
@@ -7276,6 +7235,19 @@ let CrudFieldComponent = class CrudFieldComponent extends NgxFormFieldDirective
7276
7235
  }
7277
7236
  await super.initialize();
7278
7237
  }
7238
+ /**
7239
+ * @description Component after view initialization lifecycle method.
7240
+ * @summary Calls the parent afterViewInit method for READ and DELETE operations.
7241
+ * This ensures proper initialization of read-only fields that don't require
7242
+ * form functionality but still need view setup.
7243
+ *
7244
+ * @returns {Promise<void>}
7245
+ * @memberOf CrudFieldComponent
7246
+ */
7247
+ async ngAfterViewInit() {
7248
+ if (this.type === HTML5InputTypes.RADIO && !this.value)
7249
+ this.setValue(this.options[0].value); // TODO: migrate to RenderingEngine
7250
+ }
7279
7251
  /**
7280
7252
  * Returns a list of options for select or radio inputs, with their `text` property
7281
7253
  * localized if it does not already include the word 'options'. The localization key
@@ -7371,19 +7343,6 @@ let CrudFieldComponent = class CrudFieldComponent extends NgxFormFieldDirective
7371
7343
  }
7372
7344
  }
7373
7345
  }
7374
- /**
7375
- * @description Component after view initialization lifecycle method.
7376
- * @summary Calls the parent afterViewInit method for READ and DELETE operations.
7377
- * This ensures proper initialization of read-only fields that don't require
7378
- * form functionality but still need view setup.
7379
- *
7380
- * @returns {Promise<void>}
7381
- * @memberOf CrudFieldComponent
7382
- */
7383
- async ngAfterViewInit() {
7384
- if (this.type === HTML5InputTypes.RADIO && !this.value)
7385
- this.setValue(this.options[0].value); // TODO: migrate to RenderingEngine
7386
- }
7387
7346
  /**
7388
7347
  * @description Component cleanup lifecycle method.
7389
7348
  * @summary Performs cleanup operations for READ and DELETE operations by calling
@@ -7545,6 +7504,16 @@ class NgxFormDirective extends NgxParentComponentDirective {
7545
7504
  constructor() {
7546
7505
  super(...arguments);
7547
7506
  this.deepMerge = false;
7507
+ this.path = '';
7508
+ /**
7509
+ * @description Enables multiple item management within the fieldset.
7510
+ * @summary Boolean flag that determines if the fieldset supports adding multiple values.
7511
+ * When true, displays a reorderable list of items with add/remove functionality.
7512
+ *
7513
+ * @type {boolean}
7514
+ * @default false
7515
+ */
7516
+ this.multiple = false;
7548
7517
  /**
7549
7518
  * @description Field update trigger mode for form validation.
7550
7519
  * @summary Determines when form field validation should be triggered. Options include
@@ -7665,6 +7634,15 @@ class NgxFormDirective extends NgxParentComponentDirective {
7665
7634
  this.formGroup = undefined;
7666
7635
  }
7667
7636
  }
7637
+ async ngOnChanges(changes) {
7638
+ await super.ngOnChanges(changes);
7639
+ // if (changes[BaseComponentProps.MODEL_ID]) {
7640
+ // const { previousValue, currentValue } = changes[BaseComponentProps.MODEL_ID];
7641
+ // if (!previousValue && currentValue) {
7642
+ // await this.refresh(this.operation);
7643
+ // }
7644
+ // }
7645
+ }
7668
7646
  async ngAfterViewInit() {
7669
7647
  //TODO: ver se isso é necessário
7670
7648
  // if (this.formGroup)
@@ -7742,8 +7720,8 @@ class NgxFormDirective extends NgxParentComponentDirective {
7742
7720
  event.preventDefault();
7743
7721
  event.stopImmediatePropagation();
7744
7722
  }
7745
- this.changeDetectorRef.detectChanges();
7746
7723
  const formGroup = this.formGroup;
7724
+ this.changeDetectorRef.detectChanges();
7747
7725
  const isValid = NgxFormService.validateFields(formGroup);
7748
7726
  if (!isValid) {
7749
7727
  NgxFormService.enableAllGroupControls(formGroup);
@@ -7801,7 +7779,7 @@ class NgxFormDirective extends NgxParentComponentDirective {
7801
7779
  return undefined;
7802
7780
  }
7803
7781
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NgxFormDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
7804
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: NgxFormDirective, isStandalone: true, inputs: { parentFormId: "parentFormId", deepMerge: "deepMerge", updateOn: "updateOn", target: "target", method: "method", options: "options", action: "action", operation: "operation", handlers: "handlers", rendererId: "rendererId", allowClear: "allowClear", match: "match" }, outputs: { submitEvent: "submitEvent", formGroupLoadedEvent: "formGroupLoadedEvent" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0 }); }
7782
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: NgxFormDirective, isStandalone: true, inputs: { parentFormId: "parentFormId", deepMerge: "deepMerge", path: "path", multiple: "multiple", updateOn: "updateOn", target: "target", method: "method", options: "options", action: "action", operation: "operation", handlers: "handlers", rendererId: "rendererId", allowClear: "allowClear", match: "match" }, outputs: { submitEvent: "submitEvent", formGroupLoadedEvent: "formGroupLoadedEvent" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); }
7805
7783
  }
7806
7784
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NgxFormDirective, decorators: [{
7807
7785
  type: Directive
@@ -7809,6 +7787,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
7809
7787
  type: Input
7810
7788
  }], deepMerge: [{
7811
7789
  type: Input
7790
+ }], path: [{
7791
+ type: Input
7792
+ }], multiple: [{
7793
+ type: Input
7812
7794
  }], component: [{
7813
7795
  type: ViewChild,
7814
7796
  args: ['component', { static: false, read: ElementRef }]
@@ -8219,7 +8201,8 @@ let LayoutComponent = class LayoutComponent extends NgxParentComponentDirective
8219
8201
  * @memberOf LayoutComponent
8220
8202
  */
8221
8203
  async ngOnInit() {
8222
- super.parseProps(this);
8204
+ // must always parse props first, parse children case of layout depends on it
8205
+ super.parseProps(this, !this.children.length ? [] : ['children']);
8223
8206
  if (this.breakpoint)
8224
8207
  this.breakpoint =
8225
8208
  `${this.breakpoint.startsWith('x') ? this.breakpoint.substring(0, 2) : this.breakpoint.substring(0, 1)}`.toLowerCase();
@@ -8228,7 +8211,7 @@ let LayoutComponent = class LayoutComponent extends NgxParentComponentDirective
8228
8211
  await super.initialize();
8229
8212
  }
8230
8213
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: LayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8231
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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 ? 'dcf-layout-row ' : '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 (child of row.cols; track trackItemFn($index, child.col); let colIndex = $index) {\n <div\n [class]=\"'dcf-grid-col ' + child.colClass\"\n [class.dcf-first-column]=\"$index === 0\"\n [class.dcf-hidden]=\"child.props?.hidden?.includes(operation)\"\n >\n <div>\n @if (child.tag === 'ngx-decaf-crud-form') {\n <ngx-decaf-card\n [className]=\"(match ? 'dcf-height-1-1 dcf-card-layout' : '') + className\"\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 <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n [className]=\"(match ? 'dcf-height-1-1 dcf-card-layout' : '') + className\"\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:first-of-type .dcf-grid .dcf-first-column{padding-top:.25rem!important}.dcf-grid:first-of-type .dcf-grid .dcf-first-column+div{padding-top:.5rem!important}.dcf-grid:first-of-type .dcf-grid .dcf-first-column+div~div{padding-top:.25rem!important}.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:last-child{margin-bottom:0}.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" }] }); }
8214
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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 ? 'dcf-layout-row ' : '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 (child of row.cols; track trackItemFn($index, child.col); let colIndex = $index) {\n <div\n [class]=\"'dcf-grid-col ' + child.colClass\"\n [class.dcf-first-column]=\"$index === 0\"\n [class.dcf-hidden]=\"child.props?.hidden?.includes(operation)\"\n >\n <div>\n @if (child.tag === 'ngx-decaf-crud-form') {\n <ngx-decaf-card\n [className]=\"(match ? 'dcf-height-1-1 dcf-card-layout' : '') + className\"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n [pk]=\"pk\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ngx-decaf-card>\n } @else {\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n [pk]=\"pk\"\n [className]=\"(match ? 'dcf-height-1-1 dcf-card-layout' : '') + className\"\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:first-of-type .dcf-grid .dcf-first-column{padding-top:.25rem!important}.dcf-grid:first-of-type .dcf-grid .dcf-first-column+div{padding-top:.5rem!important}.dcf-grid:first-of-type .dcf-grid .dcf-first-column+div~div{padding-top:.25rem!important}.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:last-child{margin-bottom:0}.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", "pk", "parent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
8232
8215
  };
8233
8216
  LayoutComponent = __decorate([
8234
8217
  Dynamic(),
@@ -8236,7 +8219,7 @@ LayoutComponent = __decorate([
8236
8219
  ], LayoutComponent);
8237
8220
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: LayoutComponent, decorators: [{
8238
8221
  type: Component,
8239
- 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 ? 'dcf-layout-row ' : '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 (child of row.cols; track trackItemFn($index, child.col); let colIndex = $index) {\n <div\n [class]=\"'dcf-grid-col ' + child.colClass\"\n [class.dcf-first-column]=\"$index === 0\"\n [class.dcf-hidden]=\"child.props?.hidden?.includes(operation)\"\n >\n <div>\n @if (child.tag === 'ngx-decaf-crud-form') {\n <ngx-decaf-card\n [className]=\"(match ? 'dcf-height-1-1 dcf-card-layout' : '') + className\"\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 <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n [className]=\"(match ? 'dcf-height-1-1 dcf-card-layout' : '') + className\"\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:first-of-type .dcf-grid .dcf-first-column{padding-top:.25rem!important}.dcf-grid:first-of-type .dcf-grid .dcf-first-column+div{padding-top:.5rem!important}.dcf-grid:first-of-type .dcf-grid .dcf-first-column+div~div{padding-top:.25rem!important}.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:last-child{margin-bottom:0}.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"] }]
8222
+ 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 ? 'dcf-layout-row ' : '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 (child of row.cols; track trackItemFn($index, child.col); let colIndex = $index) {\n <div\n [class]=\"'dcf-grid-col ' + child.colClass\"\n [class.dcf-first-column]=\"$index === 0\"\n [class.dcf-hidden]=\"child.props?.hidden?.includes(operation)\"\n >\n <div>\n @if (child.tag === 'ngx-decaf-crud-form') {\n <ngx-decaf-card\n [className]=\"(match ? 'dcf-height-1-1 dcf-card-layout' : '') + className\"\n [body]=\"cardBody\"\n [type]=\"cardType\"\n >\n <ngx-decaf-model-renderer\n [model]=\"child.props.name\"\n [pk]=\"pk\"\n (listenEvent)=\"handleEvent($event)\"\n />\n </ngx-decaf-card>\n } @else {\n <ngx-decaf-component-renderer\n [tag]=\"child.tag\"\n [pk]=\"pk\"\n [className]=\"(match ? 'dcf-height-1-1 dcf-card-layout' : '') + className\"\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:first-of-type .dcf-grid .dcf-first-column{padding-top:.25rem!important}.dcf-grid:first-of-type .dcf-grid .dcf-first-column+div{padding-top:.5rem!important}.dcf-grid:first-of-type .dcf-grid .dcf-first-column+div~div{padding-top:.25rem!important}.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:last-child{margin-bottom:0}.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"] }]
8240
8223
  }], ctorParameters: () => [], propDecorators: { gap: [{
8241
8224
  type: Input
8242
8225
  }], grid: [{
@@ -8265,13 +8248,13 @@ let CrudFormComponent = class CrudFormComponent extends NgxFormDirective {
8265
8248
  */
8266
8249
  async ngOnInit() {
8267
8250
  this.options = Object.assign({}, DefaultFormReactiveOptions, { buttons: { submit: { text: this.operation.toLowerCase() } } }, this.options || {});
8268
- await super.initialize();
8269
8251
  if (!this.pk && this.modelName) {
8270
- const repo = getModelAndRepository$1(this.modelName);
8252
+ const repo = getModelAndRepository(this.modelName);
8271
8253
  if (repo) {
8272
8254
  this.pk = repo.pk;
8273
8255
  }
8274
8256
  }
8257
+ await super.initialize();
8275
8258
  }
8276
8259
  /**
8277
8260
  * @description Handles delete operations by emitting delete events.
@@ -8287,7 +8270,7 @@ let CrudFormComponent = class CrudFormComponent extends NgxFormDirective {
8287
8270
  super.submitEventEmit(this.model, 'CrudFormComponent', ComponentEventNames.Submit, this.handlers, OperationKeys.DELETE);
8288
8271
  }
8289
8272
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CrudFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8290
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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 (listenEvent)=\"handleEvent($event)\"\n [parentForm]=\"formGroup || parentForm\"\n [operation]=\"operation\"\n [cardType]=\"cardType ?? 'blank'\"\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-right\">\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 {{ locale + '.' + (allowClear ? options.buttons.clear?.text : 'back') | translate }}\n </ion-button>\n </div>\n }\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 : (locale + '.' + options.buttons.submit.text) | translate }}\n </ion-button>\n </div>\n\n </div>\n }\n\n </form>\n} @else {\n <section #component [id]=\"uid\">\n <ngx-decaf-layout\n [className]=\"''\"\n [children]=\"children || []\"\n [operation]=\"operation\"\n [cardType]=\"cardType ?? 'blank'\"\n [match]=\"match ?? false\"\n [gap]=\"'small'\"\n (listenEvent)=\"handleEvent($event)\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [cols]=\"cols\" />\n </section>\n\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 {{locale + '.delete' | translate}}\n </ion-button>\n </div>\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n <div>\n <ion-button\n type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{ action ? action : (locale + '.' + options.buttons.submit.text) | translate }}\n </ion-button>\n </div>\n }\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) ? (locale + '.back' | translate) : options.buttons.clear?.text}}\n </ion-button>\n </div>\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.read,.dcf-buttons-grid.dcf-flex.delete{flex-direction:row-reverse}}@media (max-width: 576px){.dcf-buttons-grid.dcf-flex{flex-direction:column-reverse}.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: 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: "pipe", type: TranslatePipe, name: "translate" }] }); }
8273
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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\"\n #component\n [id]=\"rendererId\"\n [formGroup]=\"formGroup\"\n (ngSubmit)=\"submit($event)\"\n novalidate\n [target]=\"target\"\n >\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 [pk]=\"pk\"\n [modelId]=\"modelId\"\n (listenEvent)=\"handleEvent($event)\"\n [parentForm]=\"formGroup || parentForm\"\n [operation]=\"operation\"\n [modelId]=\"modelId\"\n [cardType]=\"cardType ?? 'blank'\"\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 }\n @if (initialized) {\n <div class=\"dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-right\">\n @if (!action) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"options.buttons.clear?.iconSlot\"\n [name]=\"options.buttons.clear?.icon\"\n ></ion-icon>\n }\n {{ locale + '.' + (allowClear ? options.buttons.clear?.text : 'back') | translate }}\n </ion-button>\n </div>\n }\n <div>\n <ion-button type=\"submit\" [expand]=\"action ? 'block' : 'default'\">\n @if (options.buttons.submit.icon) {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"options.buttons.submit.iconSlot\"\n [name]=\"options.buttons.submit.icon\"\n ></ion-icon>\n }\n {{ action ? action : (locale + '.' + options.buttons.submit.text | translate) }}\n </ion-button>\n </div>\n </div>\n }\n </form>\n} @else {\n <section #component [id]=\"uid\">\n <ngx-decaf-layout\n [className]=\"''\"\n [pk]=\"pk\"\n [modelId]=\"modelId\"\n [children]=\"children || []\"\n [operation]=\"operation\"\n [cardType]=\"cardType ?? 'blank'\"\n [modelId]=\"modelId\"\n [match]=\"match ?? false\"\n [gap]=\"'small'\"\n (listenEvent)=\"handleEvent($event)\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [cols]=\"cols\"\n />\n </section>\n\n <section\n [class]=\"'dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left ' + operation\"\n [id]=\"uid\"\n >\n @if ([OperationKeys.READ, OperationKeys.DELETE].includes(operation) && modelId) {\n <div>\n <ion-button (click)=\"handleDelete()\" color=\"danger\" type=\"button\">\n @if (options.buttons.submit.icon) {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"options.buttons.submit.iconSlot\"\n [name]=\"options.buttons.submit.icon\"\n ></ion-icon>\n }\n {{ locale + '.delete' | translate }}\n </ion-button>\n </div>\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n <div>\n <ion-button type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"options.buttons.submit.iconSlot\"\n [name]=\"options.buttons.submit.icon\"\n ></ion-icon>\n }\n {{ action ? action : (locale + '.' + options.buttons.submit.text | translate) }}\n </ion-button>\n </div>\n }\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"options.buttons.clear?.iconSlot\"\n [name]=\"options.buttons.clear?.icon\"\n ></ion-icon>\n }\n {{\n [OperationKeys.DELETE, OperationKeys.READ, OperationKeys.UPDATE].includes(operation)\n ? (locale + '.back' | translate)\n : options.buttons.clear?.text\n }}\n </ion-button>\n </div>\n </section>\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.read,.dcf-buttons-grid.dcf-flex.delete{flex-direction:row-reverse}}@media (max-width: 576px){.dcf-buttons-grid.dcf-flex{flex-direction:column-reverse}.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: 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: "pipe", type: TranslatePipe, name: "translate" }] }); }
8291
8274
  };
8292
8275
  CrudFormComponent = __decorate([
8293
8276
  Dynamic(),
@@ -8295,7 +8278,7 @@ CrudFormComponent = __decorate([
8295
8278
  ], CrudFormComponent);
8296
8279
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CrudFormComponent, decorators: [{
8297
8280
  type: Component,
8298
- args: [{ standalone: true, selector: 'ngx-decaf-crud-form', imports: [TranslatePipe, ReactiveFormsModule, LayoutComponent, 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 (listenEvent)=\"handleEvent($event)\"\n [parentForm]=\"formGroup || parentForm\"\n [operation]=\"operation\"\n [cardType]=\"cardType ?? 'blank'\"\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-right\">\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 {{ locale + '.' + (allowClear ? options.buttons.clear?.text : 'back') | translate }}\n </ion-button>\n </div>\n }\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 : (locale + '.' + options.buttons.submit.text) | translate }}\n </ion-button>\n </div>\n\n </div>\n }\n\n </form>\n} @else {\n <section #component [id]=\"uid\">\n <ngx-decaf-layout\n [className]=\"''\"\n [children]=\"children || []\"\n [operation]=\"operation\"\n [cardType]=\"cardType ?? 'blank'\"\n [match]=\"match ?? false\"\n [gap]=\"'small'\"\n (listenEvent)=\"handleEvent($event)\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [cols]=\"cols\" />\n </section>\n\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 {{locale + '.delete' | translate}}\n </ion-button>\n </div>\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n <div>\n <ion-button\n type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon aria-hidden=\"true\" [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{ action ? action : (locale + '.' + options.buttons.submit.text) | translate }}\n </ion-button>\n </div>\n }\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) ? (locale + '.back' | translate) : options.buttons.clear?.text}}\n </ion-button>\n </div>\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.read,.dcf-buttons-grid.dcf-flex.delete{flex-direction:row-reverse}}@media (max-width: 576px){.dcf-buttons-grid.dcf-flex{flex-direction:column-reverse}.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"] }]
8281
+ args: [{ standalone: true, selector: 'ngx-decaf-crud-form', imports: [TranslatePipe, ReactiveFormsModule, LayoutComponent, IonButton, IonIcon], host: { '[attr.id]': 'uid' }, template: "@if (operation !== 'read' && operation !== 'delete') {\n <form\n [class]=\"'dcf-form-grid ' + operation\"\n #component\n [id]=\"rendererId\"\n [formGroup]=\"formGroup\"\n (ngSubmit)=\"submit($event)\"\n novalidate\n [target]=\"target\"\n >\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 [pk]=\"pk\"\n [modelId]=\"modelId\"\n (listenEvent)=\"handleEvent($event)\"\n [parentForm]=\"formGroup || parentForm\"\n [operation]=\"operation\"\n [modelId]=\"modelId\"\n [cardType]=\"cardType ?? 'blank'\"\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 }\n @if (initialized) {\n <div class=\"dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-right\">\n @if (!action) {\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"options.buttons.clear?.iconSlot\"\n [name]=\"options.buttons.clear?.icon\"\n ></ion-icon>\n }\n {{ locale + '.' + (allowClear ? options.buttons.clear?.text : 'back') | translate }}\n </ion-button>\n </div>\n }\n <div>\n <ion-button type=\"submit\" [expand]=\"action ? 'block' : 'default'\">\n @if (options.buttons.submit.icon) {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"options.buttons.submit.iconSlot\"\n [name]=\"options.buttons.submit.icon\"\n ></ion-icon>\n }\n {{ action ? action : (locale + '.' + options.buttons.submit.text | translate) }}\n </ion-button>\n </div>\n </div>\n }\n </form>\n} @else {\n <section #component [id]=\"uid\">\n <ngx-decaf-layout\n [className]=\"''\"\n [pk]=\"pk\"\n [modelId]=\"modelId\"\n [children]=\"children || []\"\n [operation]=\"operation\"\n [cardType]=\"cardType ?? 'blank'\"\n [modelId]=\"modelId\"\n [match]=\"match ?? false\"\n [gap]=\"'small'\"\n (listenEvent)=\"handleEvent($event)\"\n [flexMode]=\"props.flexMode || false\"\n [rows]=\"rows\"\n [borders]=\"borders ?? false\"\n [breakpoint]=\"breakpoint ?? 'large'\"\n [cols]=\"cols\"\n />\n </section>\n\n <section\n [class]=\"'dcf-buttons-grid dcf-grid dcf-grid-small dcf-flex dcf-flex-left ' + operation\"\n [id]=\"uid\"\n >\n @if ([OperationKeys.READ, OperationKeys.DELETE].includes(operation) && modelId) {\n <div>\n <ion-button (click)=\"handleDelete()\" color=\"danger\" type=\"button\">\n @if (options.buttons.submit.icon) {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"options.buttons.submit.iconSlot\"\n [name]=\"options.buttons.submit.icon\"\n ></ion-icon>\n }\n {{ locale + '.delete' | translate }}\n </ion-button>\n </div>\n }\n @if (operation === OperationKeys.CREATE || operation === OperationKeys.UPDATE) {\n <div>\n <ion-button type=\"submit\">\n @if (options.buttons.submit.icon) {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"options.buttons.submit.iconSlot\"\n [name]=\"options.buttons.submit.icon\"\n ></ion-icon>\n }\n {{ action ? action : (locale + '.' + options.buttons.submit.text | translate) }}\n </ion-button>\n </div>\n }\n <div>\n <ion-button fill=\"clear\" (click)=\"handleReset()\">\n @if (options.buttons.clear?.icon) {\n <ion-icon\n aria-hidden=\"true\"\n [slot]=\"options.buttons.clear?.iconSlot\"\n [name]=\"options.buttons.clear?.icon\"\n ></ion-icon>\n }\n {{\n [OperationKeys.DELETE, OperationKeys.READ, OperationKeys.UPDATE].includes(operation)\n ? (locale + '.back' | translate)\n : options.buttons.clear?.text\n }}\n </ion-button>\n </div>\n </section>\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.read,.dcf-buttons-grid.dcf-flex.delete{flex-direction:row-reverse}}@media (max-width: 576px){.dcf-buttons-grid.dcf-flex{flex-direction:column-reverse}.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"] }]
8299
8282
  }], ctorParameters: () => [] });
8300
8283
 
8301
8284
  /**
@@ -8872,7 +8855,12 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
8872
8855
  else {
8873
8856
  this.activePage = this.getActivePage();
8874
8857
  }
8875
- this.mapper = Object.assign(this.mapper, { [this.pk]: this.pk });
8858
+ if (this.pk) {
8859
+ this.mapper = Object.assign(this.mapper || {}, { [this.pk]: this.pk });
8860
+ }
8861
+ await this.initialize();
8862
+ }
8863
+ async initialize() {
8876
8864
  await super.initialize();
8877
8865
  await this.refresh();
8878
8866
  }
@@ -8907,26 +8895,6 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
8907
8895
  */
8908
8896
  async ngAfterViewInit() {
8909
8897
  await super.ngAfterViewInit();
8910
- // console.log(this);
8911
- // if (!this.collapsable)
8912
- // this.isOpen = true;
8913
- // if (this.operation === OperationKeys.READ || this.operation === OperationKeys.DELETE) {
8914
- // this.isOpen = true;
8915
- // // hidden remove button
8916
- // const accordionElement = this.component?.nativeElement.querySelector('ion-accordion-group');
8917
- // if (accordionElement)
8918
- // this.renderer.setAttribute(accordionElement, 'value', 'open');
8919
- // } else {
8920
- // const inputs = this.component?.nativeElement.querySelectorAll('.dcf-field-required');
8921
- // this.isRequired = inputs?.length > 0;
8922
- // if (this.isRequired) {
8923
- // this.accordionComponent.value = 'open';
8924
- // this.handleAccordionToggle();
8925
- // }
8926
- // }
8927
- // if (!(this.formGroup instanceof FormArray))
8928
- // this.formGroup = (this.formGroup as FormGroup)
8929
- // this.changeDetectorRef.detectChanges();
8930
8898
  }
8931
8899
  async refresh(operation) {
8932
8900
  if (operation) {
@@ -8942,8 +8910,9 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
8942
8910
  return false;
8943
8911
  }, obj);
8944
8912
  }
8945
- if (!Array.isArray(this._data))
8913
+ if (!Array.isArray(this._data)) {
8946
8914
  this._data = resolvePath(this._data, this.childOf);
8915
+ }
8947
8916
  if (this._data) {
8948
8917
  const data = this._data || [];
8949
8918
  if ([OperationKeys.READ, OperationKeys.DELETE].includes(this.operation)) {
@@ -8965,7 +8934,30 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
8965
8934
  ];
8966
8935
  }
8967
8936
  else {
8968
- this.getItems(data);
8937
+ if (Array.isArray(data)) {
8938
+ this.value = [];
8939
+ data.map((v) => {
8940
+ const formGroup = this.activeFormGroup;
8941
+ if (data.length > formGroup.parent.length)
8942
+ NgxFormService.addGroupToParent(formGroup.parent);
8943
+ if (!Object.keys(this.mapper).length)
8944
+ this.mapper = this.getMapper(v);
8945
+ Object.entries(v).forEach(([key, value]) => {
8946
+ if (key === this.pk)
8947
+ formGroup.addControl(key, new FormControl({ value: value, disabled: false }));
8948
+ const control = formGroup.get(key);
8949
+ if (control instanceof FormControl) {
8950
+ control.setValue(value);
8951
+ control.updateValueAndValidity();
8952
+ formGroup.updateValueAndValidity();
8953
+ }
8954
+ });
8955
+ this.activeFormGroupIndex = formGroup.parent.length - 1;
8956
+ });
8957
+ this.setValue();
8958
+ // this.changeDetectorRef.detectChanges();
8959
+ }
8960
+ // this.getItems(data as []);
8969
8961
  }
8970
8962
  }
8971
8963
  }
@@ -9150,10 +9142,10 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
9150
9142
  pk: this.pk,
9151
9143
  uid: value[this.pk],
9152
9144
  },
9153
- }, ActionRoles$1.delete, this.injector);
9145
+ }, ActionRoles.delete, this.injector);
9154
9146
  await modal.present();
9155
9147
  const { role } = await modal.onDidDismiss();
9156
- if (role === ActionRoles$1.confirm)
9148
+ if (role === ActionRoles.confirm)
9157
9149
  return this.handleRemoveItem(index, true, value);
9158
9150
  return;
9159
9151
  }
@@ -9249,10 +9241,10 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
9249
9241
  this.operation === OperationKeys.UPDATE &&
9250
9242
  value[this.pk] !== undefined) {
9251
9243
  this.listenEvent.emit({
9252
- name: ComponentEventNames$1.Submit,
9244
+ name: ComponentEventNames.Submit,
9253
9245
  role: operation,
9254
9246
  component: this.componentName,
9255
- handler: this.handlers[ComponentEventNames$1.Submit] || undefined,
9247
+ handler: this.handlers[ComponentEventNames.Submit] || undefined,
9256
9248
  data: value,
9257
9249
  context: {
9258
9250
  repository: this._repository,
@@ -9310,12 +9302,14 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
9310
9302
  */
9311
9303
  setValue() {
9312
9304
  const formGroup = this.formGroup;
9313
- const value = formGroup.controls.map(({ value }) => value).filter((v) => this.hasValue(v));
9314
- this.value = value;
9315
- this.getItems(value, this.items);
9305
+ if (formGroup?.length) {
9306
+ const value = formGroup.controls.map(({ value }) => value).filter((v) => this.hasValue(v));
9307
+ this.value = value;
9308
+ this.getItems(value);
9309
+ }
9316
9310
  this.updatingItem = undefined;
9317
9311
  }
9318
- getItems(value, items = []) {
9312
+ getItems(value) {
9319
9313
  if (value) {
9320
9314
  if (!Array.isArray(value)) {
9321
9315
  value = [value];
@@ -9340,7 +9334,6 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
9340
9334
  index: v.index > 1 ? v.index : index + 1,
9341
9335
  };
9342
9336
  }),
9343
- ...(this.operation === OperationKeys.UPDATE ? items : []),
9344
9337
  ];
9345
9338
  }
9346
9339
  }
@@ -9375,7 +9368,7 @@ let FieldsetComponent = class FieldsetComponent extends NgxFormDirective {
9375
9368
  return this.mapper;
9376
9369
  }
9377
9370
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FieldsetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9378
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FieldsetComponent, isStandalone: true, selector: "ngx-decaf-fieldset", inputs: { formControl: "formControl", customTypes: "customTypes", title: "title", description: "description", multiple: "multiple", value: "value", borders: "borders", max: "max", required: "required", ordenable: "ordenable", editable: "editable" }, usesInheritance: true, ngImport: i0, template: "@if (['create', 'update'].includes(operation) || !multiple) {\n <div\n [attr.role]=\"['create', 'update'].includes(operation) ? 'group' : 'region'\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.dcf-empty]=\"!items?.length\"\n [class.dcf-open]=\"isOpen\"\n #component\n >\n <div class=\"dcf-width-1-1\">\n <div>\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) && multiple) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button\n fill=\"clear\"\n size=\"small\"\n (click)=\"handleClear($event)\"\n [class.dcf-invisible]=\"!isOpen\"\n [attr.aria-label]=\"\n (items?.length ? locale + '.clear_items' : locale + '.hidden_form') | translate\n \"\n >\n <ngx-decaf-icon\n slot=\"icon-only\"\n [name]=\"'ti-' + (items?.length ? 'trash' : 'eye-off')\"\n />\n </ion-button>\n </div>\n }\n </div>\n </div>\n\n <div\n class=\"dcf-fieldset-content\"\n [class.dcf-empty]=\"!items?.length && !isOpen\"\n slot=\"content\"\n >\n @if (activePage) {\n <div\n class=\"dcf-animation dcf-animation-slide-top-small dcf-animation-fast\"\n [class.dcf-disabled]=\"!activePage\"\n >\n <ngx-decaf-layout\n [className]=\"''\"\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\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group\n [formGroup]=\"formGroup.parent\"\n [disabled]=\"updatingItem\"\n (ionItemReorder)=\"handleReorderItems($any($event))\"\n #accordionComponent\n >\n @for (item of items; track item.index) {\n <ion-item\n [class.not-unique]=\"item.title === isUniqueError\"\n [class.updating]=\"updatingItem?.['index'] === item.index - 1\"\n lines=\"full\"\n [button]=\"false\"\n >\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\n aria-hidden=\"true\"\n class=\"dcf-reorder-disabled\"\n size=\"small\"\n name=\"swap-vertical-outline\"\n disabled\n ></ion-icon>\n </div>\n }\n }\n\n <ion-label\n [color]=\"\n item.title === isUniqueError && !updatingItem?.[pk] === item.title\n ? 'danger'\n : ''\n \"\n >\n @if (ordenable) {\n {{ item.index }}.{{ item.title }}\n } @else {\n @if (item[pk]) {\n {{ pk }}: {{ item[pk] }} -\n }\n {{ item.title }}\n }\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{ item.description }}</ion-text>\n }\n </ion-label>\n @if (item.info?.length || item.subinfo?.length) {\n <ion-note slot=\"end\">\n @if (item.info?.length) {\n {{ item.info }}\n <br />\n }\n @if (item.subinfo) {\n {{ item.subinfo }}\n }\n </ion-note>\n }\n <div slot=\"end\">\n @if (editable) {\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button\n fill=\"clear\"\n size=\"small\"\n (click)=\"handleUpdateItem($index)\"\n [attr.aria-label]=\"locale + '.edit_item' | translate\"\n >\n <ngx-decaf-icon\n slot=\"icon-only\"\n size=\"small\"\n name=\"ti-cash-edit\"\n [color]=\"!isDarkMode ? 'dark' : 'light'\"\n ></ngx-decaf-icon>\n </ion-button>\n }\n }\n @if (!updatingItem) {\n <ion-button\n fill=\"clear\"\n size=\"small\"\n color=\"danger\"\n (click)=\"handleRemoveItem($index)\"\n [attr.aria-label]=\"locale + '.remove_item' | translate\"\n >\n <ngx-decaf-icon\n slot=\"icon-only\"\n size=\"small\"\n name=\"ti-row-remove\"\n [color]=\"!isDarkMode ? 'dark' : 'light'\"\n />\n </ion-button>\n }\n </div>\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (isUniqueError) {\n <div\n class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\"\n >\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\">\n {{ locale + '.not_unique' | translate: { value: isUniqueError } }}\n </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\n class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{\n locale + (items.length !== max ? '.max_items' : '.max_items_reached')\n | translate: { '0': max }\n }}\n </ion-text>\n </div>\n }\n\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\">\n @if (updatingItem) {\n <div>\n <ion-button\n size=\"small\"\n fill=\"clear\"\n color=\"danger\"\n (click)=\"handleCancelUpdateItem()\"\n [attr.aria-label]=\"locale + '.cancel_update' | translate\"\n >\n {{ locale + '.cancel' | translate }}\n </ion-button>\n </div>\n <div>\n <ion-button\n size=\"small\"\n fill=\"clear\"\n (click)=\"handleCreateItem()\"\n [attr.aria-label]=\"locale + '.update_item' | translate\"\n >\n <ion-icon aria-hidden=\"true\" name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update_item' | translate }}\n </ion-button>\n </div>\n } @else {\n @if (items.length < max || !max) {\n <div>\n <ion-button\n size=\"small\"\n fill=\"clear\"\n class=\"dcf-button-add\"\n [color]=\"isDarkMode ? 'light' : 'dark'\"\n (click)=\"handleCreateItem()\"\n [attr.aria-label]=\"locale + '.create_item' | translate\"\n >\n <!-- <ion-icon aria-hidden=\"true\" name=\"add-outline\" slot=\"start\"></ion-icon> -->\n <ngx-decaf-icon slot=\"icon-only\" name=\"ti-code-plus\" slot=\"start\" />\n {{\n locale +\n (required\n ? items.length\n ? '.add'\n : '.add_first'\n : items.length\n ? '.add'\n : isOpen\n ? '.add_first'\n : '.show_form') | translate\n }}\n </ion-button>\n </div>\n }\n }\n </div>\n }\n </div>\n </div>\n </div>\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 <legend>{{ (title ? title : name) | translate }}</legend>\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-read-item\">\n <div>\n <ngx-decaf-layout\n [className]=\"operation\"\n [operation]=\"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", styles: ["fieldset{margin:0;padding:0;min-inline-size:auto}.dcf-loading-container{height:50%;display:flex;justify-content:center;align-items:center}.dcf-loading-container ion-spinner{width:30px;height:30px}.dcf-fieldset-read-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)!important}.dcf-fieldset-component{border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-3);padding:var(--dcf-padding-small)}.dcf-fieldset-component.create ::ng-deep .dcf-item-readonly{display:none!important}.dcf-fieldset-component.dcf-open.dcf-empty .dcf-button-add{margin-top:1rem!important;margin-bottom:.15rem!important}.dcf-fieldset-component.dcf-blank{border-color:transparent;padding:var(--dcf-padding-xsmall) .25rem}.dcf-fieldset-component:not(.dcf-blank):not(.read):not(.delete){padding:var(--dcf-padding)}.dcf-fieldset-component *{overflow-x:hidden!important}.dcf-max-message-container{padding:0 .125rem;margin-bottom:var(--dcf-margin-xsmall)}legend,.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-content{margin-top:.25rem}.dcf-fieldset-content:not(.dcf-empty){padding:var(--dcf-padding-small) .25rem!important;margin-top:var(--dcf-margin-xsmall)}.dcf-fields-list{margin-top:var(--dcf-margin-small);padding-bottom:var(--dcf-padding)!important;max-height:200px}.dcf-fields-list ion-item{--min-height: 30px;--padding-top: 0rem;--padding-bottom: 0rem;--padding-start: .75rem;--padding-end: .5rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--border-color: transparent;--background: rgba(var(--dcf-color-primary-rgb), .025) !important;border:1px solid var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-small);box-sizing:border-box}.dcf-fields-list ion-item:not(:last-child){margin-bottom:var(--dcf-margin-small)}.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-6)}\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: 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: "component", type: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
9371
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FieldsetComponent, isStandalone: true, selector: "ngx-decaf-fieldset", inputs: { formControl: "formControl", customTypes: "customTypes", title: "title", description: "description", multiple: "multiple", value: "value", borders: "borders", max: "max", required: "required", ordenable: "ordenable", editable: "editable" }, usesInheritance: true, ngImport: i0, template: "@if (['create', 'update'].includes(operation) || !multiple) {\n <div\n [attr.role]=\"['create', 'update'].includes(operation) ? 'group' : 'region'\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.dcf-empty]=\"!items?.length\"\n [class.dcf-open]=\"isOpen\"\n #component\n >\n <div class=\"dcf-width-1-1\">\n <div>\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) && multiple) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button\n fill=\"clear\"\n size=\"small\"\n (click)=\"handleClear($event)\"\n [class.dcf-invisible]=\"!isOpen\"\n [attr.aria-label]=\"\n (items?.length ? locale + '.clear_items' : locale + '.hidden_form') | translate\n \"\n >\n <ngx-decaf-icon\n slot=\"icon-only\"\n [name]=\"'ti-' + (items?.length ? 'trash' : 'eye-off')\"\n />\n </ion-button>\n </div>\n }\n </div>\n </div>\n <div\n class=\"dcf-fieldset-content\"\n [class.dcf-empty]=\"!items?.length && !isOpen\"\n slot=\"content\"\n >\n @if (activePage) {\n <div\n class=\"dcf-animation dcf-animation-slide-top-small dcf-animation-fast\"\n [class.dcf-disabled]=\"!activePage\"\n >\n <ngx-decaf-layout\n [className]=\"''\"\n [flexMode]=\"props.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [pk]=\"pk\"\n [modelId]=\"modelId\"\n [operation]=\"operation\"\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\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group\n [formGroup]=\"formGroup.parent\"\n [disabled]=\"updatingItem\"\n (ionItemReorder)=\"handleReorderItems($any($event))\"\n #accordionComponent\n >\n @for (item of items; track item.index) {\n <ion-item\n [class.not-unique]=\"isUniqueError && item.title === isUniqueError\"\n [class.updating]=\"updatingItem?.['index'] === item.index - 1\"\n lines=\"full\"\n [button]=\"false\"\n >\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\n aria-hidden=\"true\"\n class=\"dcf-reorder-disabled\"\n size=\"small\"\n name=\"swap-vertical-outline\"\n disabled\n ></ion-icon>\n </div>\n }\n }\n\n <ion-label\n [color]=\"\n item.title === isUniqueError && !updatingItem?.[pk] === item.title\n ? 'danger'\n : ''\n \"\n >\n @if (ordenable) {\n {{ item.index }}.{{ item.title }}\n } @else {\n @if (item[pk]) {\n {{ pk }}: {{ item[pk] }} -\n }\n {{ item.title }}\n }\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{ item.description }}</ion-text>\n }\n </ion-label>\n @if (item.info?.length || item.subinfo?.length) {\n <ion-note slot=\"end\">\n @if (item.info?.length) {\n {{ item.info }}\n <br />\n }\n @if (item.subinfo) {\n {{ item.subinfo }}\n }\n </ion-note>\n }\n <div slot=\"end\">\n @if (editable) {\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button\n fill=\"clear\"\n size=\"small\"\n (click)=\"handleUpdateItem($index)\"\n [attr.aria-label]=\"locale + '.edit_item' | translate\"\n >\n <ngx-decaf-icon\n slot=\"icon-only\"\n size=\"small\"\n name=\"ti-cash-edit\"\n [color]=\"!isDarkMode ? 'dark' : 'light'\"\n ></ngx-decaf-icon>\n </ion-button>\n }\n }\n @if (!updatingItem) {\n <ion-button\n fill=\"clear\"\n size=\"small\"\n color=\"danger\"\n (click)=\"handleRemoveItem($index)\"\n [attr.aria-label]=\"locale + '.remove_item' | translate\"\n >\n <ngx-decaf-icon\n slot=\"icon-only\"\n size=\"small\"\n name=\"ti-row-remove\"\n [color]=\"!isDarkMode ? 'dark' : 'light'\"\n />\n </ion-button>\n }\n </div>\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (isUniqueError) {\n <div\n class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\"\n >\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\">\n {{ locale + '.not_unique' | translate: { value: isUniqueError } }}\n </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\n class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{\n locale + (items.length !== max ? '.max_items' : '.max_items_reached')\n | translate: { '0': max }\n }}\n </ion-text>\n </div>\n }\n\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\">\n @if (updatingItem) {\n <div>\n <ion-button\n size=\"small\"\n fill=\"clear\"\n color=\"danger\"\n (click)=\"handleCancelUpdateItem()\"\n [attr.aria-label]=\"locale + '.cancel_update' | translate\"\n >\n {{ locale + '.cancel' | translate }}\n </ion-button>\n </div>\n <div>\n <ion-button\n size=\"small\"\n fill=\"clear\"\n (click)=\"handleCreateItem()\"\n [attr.aria-label]=\"locale + '.update_item' | translate\"\n >\n <ion-icon aria-hidden=\"true\" name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update_item' | translate }}\n </ion-button>\n </div>\n } @else {\n @if (items.length < max || !max) {\n <div>\n <ion-button\n size=\"small\"\n fill=\"clear\"\n class=\"dcf-button-add\"\n [color]=\"isDarkMode ? 'light' : 'dark'\"\n (click)=\"handleCreateItem()\"\n [attr.aria-label]=\"locale + '.create_item' | translate\"\n >\n <!-- <ion-icon aria-hidden=\"true\" name=\"add-outline\" slot=\"start\"></ion-icon> -->\n <ngx-decaf-icon slot=\"icon-only\" name=\"ti-code-plus\" slot=\"start\" />\n {{\n locale +\n (required\n ? items.length\n ? '.add'\n : '.add_first'\n : items.length\n ? '.add'\n : isOpen\n ? '.add_first'\n : '.show_form') | translate\n }}\n </ion-button>\n </div>\n }\n }\n </div>\n }\n </div>\n </div>\n </div>\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 <legend>{{ (title ? title : name) | translate }}</legend>\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-read-item\">\n <div>\n <ngx-decaf-layout\n [className]=\"operation\"\n [operation]=\"operation\"\n [pk]=\"pk\"\n [model]=\"model\"\n [modelId]=\"modelId\"\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", styles: ["fieldset{margin:0;padding:0;min-inline-size:auto}.dcf-loading-container{height:50%;display:flex;justify-content:center;align-items:center}.dcf-loading-container ion-spinner{width:30px;height:30px}.dcf-fieldset-read-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)!important}.dcf-fieldset-component{border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-3);padding:var(--dcf-padding-small)}.dcf-fieldset-component.create ::ng-deep .dcf-item-readonly{display:none!important}.dcf-fieldset-component.dcf-open.dcf-empty .dcf-button-add{margin-top:1rem!important;margin-bottom:.15rem!important}.dcf-fieldset-component.dcf-blank{border-color:transparent;padding:var(--dcf-padding-xsmall) .25rem}.dcf-fieldset-component:not(.dcf-blank):not(.read):not(.delete){padding:var(--dcf-padding)}.dcf-fieldset-component *{overflow-x:hidden!important}.dcf-max-message-container{padding:0 .125rem;margin-bottom:var(--dcf-margin-xsmall)}legend,.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-content{margin-top:.25rem}.dcf-fieldset-content:not(.dcf-empty){padding:var(--dcf-padding-small) .25rem!important;margin-top:var(--dcf-margin-xsmall)}.dcf-fields-list{margin-top:var(--dcf-margin-small);padding-bottom:var(--dcf-padding)!important;max-height:200px}.dcf-fields-list ion-item{--min-height: 30px;--padding-top: 0rem;--padding-bottom: 0rem;--padding-start: .75rem;--padding-end: .5rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--border-color: transparent;--background: rgba(var(--dcf-color-primary-rgb), .025) !important;border:1px solid var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-small);box-sizing:border-box}.dcf-fields-list ion-item:not(:last-child){margin-bottom:var(--dcf-margin-small)}.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-6)}\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: 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: "component", type: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
9379
9372
  };
9380
9373
  FieldsetComponent = __decorate([
9381
9374
  Dynamic(),
@@ -9397,7 +9390,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
9397
9390
  LayoutComponent,
9398
9391
  IonSpinner,
9399
9392
  IconComponent,
9400
- ], template: "@if (['create', 'update'].includes(operation) || !multiple) {\n <div\n [attr.role]=\"['create', 'update'].includes(operation) ? 'group' : 'region'\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.dcf-empty]=\"!items?.length\"\n [class.dcf-open]=\"isOpen\"\n #component\n >\n <div class=\"dcf-width-1-1\">\n <div>\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) && multiple) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button\n fill=\"clear\"\n size=\"small\"\n (click)=\"handleClear($event)\"\n [class.dcf-invisible]=\"!isOpen\"\n [attr.aria-label]=\"\n (items?.length ? locale + '.clear_items' : locale + '.hidden_form') | translate\n \"\n >\n <ngx-decaf-icon\n slot=\"icon-only\"\n [name]=\"'ti-' + (items?.length ? 'trash' : 'eye-off')\"\n />\n </ion-button>\n </div>\n }\n </div>\n </div>\n\n <div\n class=\"dcf-fieldset-content\"\n [class.dcf-empty]=\"!items?.length && !isOpen\"\n slot=\"content\"\n >\n @if (activePage) {\n <div\n class=\"dcf-animation dcf-animation-slide-top-small dcf-animation-fast\"\n [class.dcf-disabled]=\"!activePage\"\n >\n <ngx-decaf-layout\n [className]=\"''\"\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\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group\n [formGroup]=\"formGroup.parent\"\n [disabled]=\"updatingItem\"\n (ionItemReorder)=\"handleReorderItems($any($event))\"\n #accordionComponent\n >\n @for (item of items; track item.index) {\n <ion-item\n [class.not-unique]=\"item.title === isUniqueError\"\n [class.updating]=\"updatingItem?.['index'] === item.index - 1\"\n lines=\"full\"\n [button]=\"false\"\n >\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\n aria-hidden=\"true\"\n class=\"dcf-reorder-disabled\"\n size=\"small\"\n name=\"swap-vertical-outline\"\n disabled\n ></ion-icon>\n </div>\n }\n }\n\n <ion-label\n [color]=\"\n item.title === isUniqueError && !updatingItem?.[pk] === item.title\n ? 'danger'\n : ''\n \"\n >\n @if (ordenable) {\n {{ item.index }}.{{ item.title }}\n } @else {\n @if (item[pk]) {\n {{ pk }}: {{ item[pk] }} -\n }\n {{ item.title }}\n }\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{ item.description }}</ion-text>\n }\n </ion-label>\n @if (item.info?.length || item.subinfo?.length) {\n <ion-note slot=\"end\">\n @if (item.info?.length) {\n {{ item.info }}\n <br />\n }\n @if (item.subinfo) {\n {{ item.subinfo }}\n }\n </ion-note>\n }\n <div slot=\"end\">\n @if (editable) {\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button\n fill=\"clear\"\n size=\"small\"\n (click)=\"handleUpdateItem($index)\"\n [attr.aria-label]=\"locale + '.edit_item' | translate\"\n >\n <ngx-decaf-icon\n slot=\"icon-only\"\n size=\"small\"\n name=\"ti-cash-edit\"\n [color]=\"!isDarkMode ? 'dark' : 'light'\"\n ></ngx-decaf-icon>\n </ion-button>\n }\n }\n @if (!updatingItem) {\n <ion-button\n fill=\"clear\"\n size=\"small\"\n color=\"danger\"\n (click)=\"handleRemoveItem($index)\"\n [attr.aria-label]=\"locale + '.remove_item' | translate\"\n >\n <ngx-decaf-icon\n slot=\"icon-only\"\n size=\"small\"\n name=\"ti-row-remove\"\n [color]=\"!isDarkMode ? 'dark' : 'light'\"\n />\n </ion-button>\n }\n </div>\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (isUniqueError) {\n <div\n class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\"\n >\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\">\n {{ locale + '.not_unique' | translate: { value: isUniqueError } }}\n </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\n class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{\n locale + (items.length !== max ? '.max_items' : '.max_items_reached')\n | translate: { '0': max }\n }}\n </ion-text>\n </div>\n }\n\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\">\n @if (updatingItem) {\n <div>\n <ion-button\n size=\"small\"\n fill=\"clear\"\n color=\"danger\"\n (click)=\"handleCancelUpdateItem()\"\n [attr.aria-label]=\"locale + '.cancel_update' | translate\"\n >\n {{ locale + '.cancel' | translate }}\n </ion-button>\n </div>\n <div>\n <ion-button\n size=\"small\"\n fill=\"clear\"\n (click)=\"handleCreateItem()\"\n [attr.aria-label]=\"locale + '.update_item' | translate\"\n >\n <ion-icon aria-hidden=\"true\" name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update_item' | translate }}\n </ion-button>\n </div>\n } @else {\n @if (items.length < max || !max) {\n <div>\n <ion-button\n size=\"small\"\n fill=\"clear\"\n class=\"dcf-button-add\"\n [color]=\"isDarkMode ? 'light' : 'dark'\"\n (click)=\"handleCreateItem()\"\n [attr.aria-label]=\"locale + '.create_item' | translate\"\n >\n <!-- <ion-icon aria-hidden=\"true\" name=\"add-outline\" slot=\"start\"></ion-icon> -->\n <ngx-decaf-icon slot=\"icon-only\" name=\"ti-code-plus\" slot=\"start\" />\n {{\n locale +\n (required\n ? items.length\n ? '.add'\n : '.add_first'\n : items.length\n ? '.add'\n : isOpen\n ? '.add_first'\n : '.show_form') | translate\n }}\n </ion-button>\n </div>\n }\n }\n </div>\n }\n </div>\n </div>\n </div>\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 <legend>{{ (title ? title : name) | translate }}</legend>\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-read-item\">\n <div>\n <ngx-decaf-layout\n [className]=\"operation\"\n [operation]=\"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", styles: ["fieldset{margin:0;padding:0;min-inline-size:auto}.dcf-loading-container{height:50%;display:flex;justify-content:center;align-items:center}.dcf-loading-container ion-spinner{width:30px;height:30px}.dcf-fieldset-read-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)!important}.dcf-fieldset-component{border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-3);padding:var(--dcf-padding-small)}.dcf-fieldset-component.create ::ng-deep .dcf-item-readonly{display:none!important}.dcf-fieldset-component.dcf-open.dcf-empty .dcf-button-add{margin-top:1rem!important;margin-bottom:.15rem!important}.dcf-fieldset-component.dcf-blank{border-color:transparent;padding:var(--dcf-padding-xsmall) .25rem}.dcf-fieldset-component:not(.dcf-blank):not(.read):not(.delete){padding:var(--dcf-padding)}.dcf-fieldset-component *{overflow-x:hidden!important}.dcf-max-message-container{padding:0 .125rem;margin-bottom:var(--dcf-margin-xsmall)}legend,.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-content{margin-top:.25rem}.dcf-fieldset-content:not(.dcf-empty){padding:var(--dcf-padding-small) .25rem!important;margin-top:var(--dcf-margin-xsmall)}.dcf-fields-list{margin-top:var(--dcf-margin-small);padding-bottom:var(--dcf-padding)!important;max-height:200px}.dcf-fields-list ion-item{--min-height: 30px;--padding-top: 0rem;--padding-bottom: 0rem;--padding-start: .75rem;--padding-end: .5rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--border-color: transparent;--background: rgba(var(--dcf-color-primary-rgb), .025) !important;border:1px solid var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-small);box-sizing:border-box}.dcf-fields-list ion-item:not(:last-child){margin-bottom:var(--dcf-margin-small)}.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-6)}\n"] }]
9393
+ ], template: "@if (['create', 'update'].includes(operation) || !multiple) {\n <div\n [attr.role]=\"['create', 'update'].includes(operation) ? 'group' : 'region'\"\n [class]=\"'dcf-fieldset-component ' + operation\"\n [class.dcf-blank]=\"!borders\"\n [class.dcf-empty]=\"!items?.length\"\n [class.dcf-open]=\"isOpen\"\n #component\n >\n <div class=\"dcf-width-1-1\">\n <div>\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) && multiple) {\n <div class=\"dcf-width-auto dcf-delete\">\n <ion-button\n fill=\"clear\"\n size=\"small\"\n (click)=\"handleClear($event)\"\n [class.dcf-invisible]=\"!isOpen\"\n [attr.aria-label]=\"\n (items?.length ? locale + '.clear_items' : locale + '.hidden_form') | translate\n \"\n >\n <ngx-decaf-icon\n slot=\"icon-only\"\n [name]=\"'ti-' + (items?.length ? 'trash' : 'eye-off')\"\n />\n </ion-button>\n </div>\n }\n </div>\n </div>\n <div\n class=\"dcf-fieldset-content\"\n [class.dcf-empty]=\"!items?.length && !isOpen\"\n slot=\"content\"\n >\n @if (activePage) {\n <div\n class=\"dcf-animation dcf-animation-slide-top-small dcf-animation-fast\"\n [class.dcf-disabled]=\"!activePage\"\n >\n <ngx-decaf-layout\n [className]=\"''\"\n [flexMode]=\"props.flexMode ?? false\"\n [match]=\"false\"\n [gap]=\"'small'\"\n [pk]=\"pk\"\n [modelId]=\"modelId\"\n [operation]=\"operation\"\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\n @if (multiple && ['create', 'update'].includes(operation)) {\n @if (multiple && items.length) {\n <ion-list class=\"dcf-fields-list\">\n <ion-reorder-group\n [formGroup]=\"formGroup.parent\"\n [disabled]=\"updatingItem\"\n (ionItemReorder)=\"handleReorderItems($any($event))\"\n #accordionComponent\n >\n @for (item of items; track item.index) {\n <ion-item\n [class.not-unique]=\"isUniqueError && item.title === isUniqueError\"\n [class.updating]=\"updatingItem?.['index'] === item.index - 1\"\n lines=\"full\"\n [button]=\"false\"\n >\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\n aria-hidden=\"true\"\n class=\"dcf-reorder-disabled\"\n size=\"small\"\n name=\"swap-vertical-outline\"\n disabled\n ></ion-icon>\n </div>\n }\n }\n\n <ion-label\n [color]=\"\n item.title === isUniqueError && !updatingItem?.[pk] === item.title\n ? 'danger'\n : ''\n \"\n >\n @if (ordenable) {\n {{ item.index }}.{{ item.title }}\n } @else {\n @if (item[pk]) {\n {{ pk }}: {{ item[pk] }} -\n }\n {{ item.title }}\n }\n @if (item.description?.length > 0) {\n <br />\n <ion-text class=\"dcf-subtitle\">{{ item.description }}</ion-text>\n }\n </ion-label>\n @if (item.info?.length || item.subinfo?.length) {\n <ion-note slot=\"end\">\n @if (item.info?.length) {\n {{ item.info }}\n <br />\n }\n @if (item.subinfo) {\n {{ item.subinfo }}\n }\n </ion-note>\n }\n <div slot=\"end\">\n @if (editable) {\n @if (!updatingItem || updatingItem?.[pk] !== item.title) {\n <ion-button\n fill=\"clear\"\n size=\"small\"\n (click)=\"handleUpdateItem($index)\"\n [attr.aria-label]=\"locale + '.edit_item' | translate\"\n >\n <ngx-decaf-icon\n slot=\"icon-only\"\n size=\"small\"\n name=\"ti-cash-edit\"\n [color]=\"!isDarkMode ? 'dark' : 'light'\"\n ></ngx-decaf-icon>\n </ion-button>\n }\n }\n @if (!updatingItem) {\n <ion-button\n fill=\"clear\"\n size=\"small\"\n color=\"danger\"\n (click)=\"handleRemoveItem($index)\"\n [attr.aria-label]=\"locale + '.remove_item' | translate\"\n >\n <ngx-decaf-icon\n slot=\"icon-only\"\n size=\"small\"\n name=\"ti-row-remove\"\n [color]=\"!isDarkMode ? 'dark' : 'light'\"\n />\n </ion-button>\n }\n </div>\n </ion-item>\n }\n </ion-reorder-group>\n </ion-list>\n }\n\n @if (isUniqueError) {\n <div\n class=\"dcf-not-unique-container dcf-animation dcf-animation-bottom-small dcf-animation-fast\"\n >\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\">\n {{ locale + '.not_unique' | translate: { value: isUniqueError } }}\n </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\n class=\"dcf-text-small\"\n [color]=\"items.length !== max ? (!isDarkMode ? 'medium' : '') : 'primary'\"\n >\n {{\n locale + (items.length !== max ? '.max_items' : '.max_items_reached')\n | translate: { '0': max }\n }}\n </ion-text>\n </div>\n }\n\n <div class=\"dcf-grid dcf-grid-small dcf-flex dcf-buttons-container\">\n @if (updatingItem) {\n <div>\n <ion-button\n size=\"small\"\n fill=\"clear\"\n color=\"danger\"\n (click)=\"handleCancelUpdateItem()\"\n [attr.aria-label]=\"locale + '.cancel_update' | translate\"\n >\n {{ locale + '.cancel' | translate }}\n </ion-button>\n </div>\n <div>\n <ion-button\n size=\"small\"\n fill=\"clear\"\n (click)=\"handleCreateItem()\"\n [attr.aria-label]=\"locale + '.update_item' | translate\"\n >\n <ion-icon aria-hidden=\"true\" name=\"refresh-outline\" slot=\"start\"></ion-icon>\n {{ locale + '.update_item' | translate }}\n </ion-button>\n </div>\n } @else {\n @if (items.length < max || !max) {\n <div>\n <ion-button\n size=\"small\"\n fill=\"clear\"\n class=\"dcf-button-add\"\n [color]=\"isDarkMode ? 'light' : 'dark'\"\n (click)=\"handleCreateItem()\"\n [attr.aria-label]=\"locale + '.create_item' | translate\"\n >\n <!-- <ion-icon aria-hidden=\"true\" name=\"add-outline\" slot=\"start\"></ion-icon> -->\n <ngx-decaf-icon slot=\"icon-only\" name=\"ti-code-plus\" slot=\"start\" />\n {{\n locale +\n (required\n ? items.length\n ? '.add'\n : '.add_first'\n : items.length\n ? '.add'\n : isOpen\n ? '.add_first'\n : '.show_form') | translate\n }}\n </ion-button>\n </div>\n }\n }\n </div>\n }\n </div>\n </div>\n </div>\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 <legend>{{ (title ? title : name) | translate }}</legend>\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-read-item\">\n <div>\n <ngx-decaf-layout\n [className]=\"operation\"\n [operation]=\"operation\"\n [pk]=\"pk\"\n [model]=\"model\"\n [modelId]=\"modelId\"\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", styles: ["fieldset{margin:0;padding:0;min-inline-size:auto}.dcf-loading-container{height:50%;display:flex;justify-content:center;align-items:center}.dcf-loading-container ion-spinner{width:30px;height:30px}.dcf-fieldset-read-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)!important}.dcf-fieldset-component{border-radius:var(--dcf-border-radius-small);border:1px solid var(--dcf-color-gray-3);padding:var(--dcf-padding-small)}.dcf-fieldset-component.create ::ng-deep .dcf-item-readonly{display:none!important}.dcf-fieldset-component.dcf-open.dcf-empty .dcf-button-add{margin-top:1rem!important;margin-bottom:.15rem!important}.dcf-fieldset-component.dcf-blank{border-color:transparent;padding:var(--dcf-padding-xsmall) .25rem}.dcf-fieldset-component:not(.dcf-blank):not(.read):not(.delete){padding:var(--dcf-padding)}.dcf-fieldset-component *{overflow-x:hidden!important}.dcf-max-message-container{padding:0 .125rem;margin-bottom:var(--dcf-margin-xsmall)}legend,.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-content{margin-top:.25rem}.dcf-fieldset-content:not(.dcf-empty){padding:var(--dcf-padding-small) .25rem!important;margin-top:var(--dcf-margin-xsmall)}.dcf-fields-list{margin-top:var(--dcf-margin-small);padding-bottom:var(--dcf-padding)!important;max-height:200px}.dcf-fields-list ion-item{--min-height: 30px;--padding-top: 0rem;--padding-bottom: 0rem;--padding-start: .75rem;--padding-end: .5rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--border-color: transparent;--background: rgba(var(--dcf-color-primary-rgb), .025) !important;border:1px solid var(--dcf-color-gray-3);border-radius:var(--dcf-border-radius-small);box-sizing:border-box}.dcf-fields-list ion-item:not(:last-child){margin-bottom:var(--dcf-margin-small)}.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-6)}\n"] }]
9401
9394
  }], ctorParameters: () => [], propDecorators: { formControl: [{
9402
9395
  type: Input
9403
9396
  }], customTypes: [{
@@ -11237,7 +11230,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
11237
11230
  * period. This prevents multiple rapid clicks from triggering multiple events.
11238
11231
  *
11239
11232
  * @private
11240
- * @type {Subject<CustomEvent | ListItemCustomEvent | IBaseCustomEvent>}
11233
+ * @type {Subject<CustomEvent | IListItemCustomEvent | IBaseCustomEvent>}
11241
11234
  * @memberOf ListComponent
11242
11235
  */
11243
11236
  this.clickItemSubject = new Subject();
@@ -11366,7 +11359,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
11366
11359
  }
11367
11360
  const mapperFn = value?.['valueParserFn'] || undefined;
11368
11361
  if (typeof mapperFn === 'function') {
11369
- const value = await mapperFn(key, this);
11362
+ const value = await mapperFn(this, key);
11370
11363
  if (typeof value === Primitives.STRING) {
11371
11364
  mapper[value] = key;
11372
11365
  }
@@ -11437,8 +11430,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
11437
11430
  this.data = !this.model
11438
11431
  ? await this.getFromRequest(!!event, start, limit)
11439
11432
  : (await this.getFromModel(!!event));
11440
- if (!this.isModalChild)
11441
- this.refreshEventEmit(this.data);
11433
+ this.refreshEventEmit(this.data);
11442
11434
  if (this.type === ListComponentsTypes.INFINITE) {
11443
11435
  if (this.page === this.pages) {
11444
11436
  if (event?.target)
@@ -11575,12 +11567,12 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
11575
11567
  * debounced click subject. This allows the component to respond to clicks on
11576
11568
  * list items regardless of where they originate from.
11577
11569
  *
11578
- * @param {ListItemCustomEvent | IBaseCustomEvent} event - The click event
11579
- * @returns {void}
11570
+ * @param {IListItemCustomEvent | IBaseCustomEvent} event - The click event
11571
+ * @returns {Promise<void>}
11580
11572
  *
11581
11573
  * @memberOf ListComponent
11582
11574
  */
11583
- handleClick(event) {
11575
+ async handleClick(event) {
11584
11576
  this.clickItemSubject.next(event);
11585
11577
  }
11586
11578
  /**
@@ -11681,7 +11673,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
11681
11673
  * This extracts the relevant data from the event and passes it to parent components.
11682
11674
  *
11683
11675
  * @private
11684
- * @param {ListItemCustomEvent | IBaseCustomEvent} event - The click event
11676
+ * @param {IListItemCustomEvent | IBaseCustomEvent} event - The click event
11685
11677
  * @returns {void}
11686
11678
  *
11687
11679
  * @memberOf ListComponent
@@ -12057,7 +12049,9 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
12057
12049
  else {
12058
12050
  let val;
12059
12051
  for (const _value of arrayValue)
12060
- val = !val ? item[_value] : (typeof val === 'string' ? JSON.parse(val) : val)[_value];
12052
+ val = !val
12053
+ ? item[_value]
12054
+ : (typeof val === Primitives.STRING ? JSON.parse(val) : val)[_value];
12061
12055
  if (isValidDate(new Date(val)))
12062
12056
  val = `${formatDate(val)}`;
12063
12057
  accum[key] = val === null || val === undefined ? value : val;
@@ -12113,7 +12107,7 @@ let ListComponent = class ListComponent extends NgxComponentDirective {
12113
12107
  .join(', ');
12114
12108
  }
12115
12109
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12116
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ListComponent, isStandalone: true, selector: "ngx-decaf-list", inputs: { type: "type", showSearchbar: "showSearchbar", searchbarPlaceholder: "searchbarPlaceholder", data: "data", source: "source", loadMoreData: "loadMoreData", lines: "lines", inset: "inset", scrollThreshold: "scrollThreshold", scrollPosition: "scrollPosition", loadingText: "loadingText", showRefresher: "showRefresher", createButton: "createButton", loadingSpinner: "loadingSpinner", enableFilter: "enableFilter", disableSort: "disableSort", empty: "empty" }, outputs: { clickEvent: "clickEvent" }, host: { listeners: { "window:ListItemClickEvent": "handleClick($event)", "window:searchbarEvent": "handleSearch($event)" }, properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "@if (showRefresher) {\n <ion-refresher\n slot=\"fixed\"\n [pullFactor]=\"1\"\n [pullMin]=\"100\"\n [pullMax]=\"200\"\n (ionRefresh)=\"handleRefresh($event)\"\n >\n <ion-refresher-content />\n </ion-refresher>\n}\n\n@if (showSearchbar) {\n <div [hidden]=\"!data?.length && !searching\">\n <div class=\"dcf-grid dcf-grid-small 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 [indexes]=\"indexes ?? []\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n } @else {\n <ngx-decaf-searchbar\n [placeholder]=\"searchbarPlaceholder\"\n [emitEventToWindow]=\"false\"\n [debounce]=\"500\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n </div>\n @if (createButton) {\n <div\n 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 >\n <div>\n <ion-button expand=\"block\" (click)=\"changeOperation(OperationKeys.CREATE)\">\n Create\n </ion-button>\n </div>\n </div>\n }\n </div>\n </div>\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: isModalChild ? route : undefined,\n model: child,\n isModalChild: child.isModalChild,\n emitEvent: child.emitEvent,\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 } @else {\n <ion-infinite-scroll\n [class]=\"searchValue?.length ? 'dcf-hidden' : ''\"\n [position]=\"scrollPosition\"\n [threshold]=\"scrollThreshold\"\n (ionInfinite)=\"handleRefresh($event)\"\n >\n <ion-infinite-scroll-content\n [loadingSpinner]=\"loadingSpinner\"\n [loadingText]=\"loadingText\"\n />\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%\">\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n </ion-text>\n </ion-label>\n </ion-item>\n }\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"empty.title ? (locale + '.' + empty.title | translate) : ''\"\n [model]=\"empty?.showButton ? model : undefined\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [buttonLink]=\"empty?.link ?? undefined\"\n [borders]=\"borders\"\n [icon]=\"(item?.icon ?? 'folder-open-outline') || empty.icon\"\n className=\"dcf-empty-data\"\n [subtitle]=\"empty.subtitle ? (locale + '.' + empty.subtitle | translate) : ''\"\n />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"empty?.showButton ? model : undefined\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [borders]=\"borders\"\n [operations]=\"operations\"\n [body]=\"'small'\"\n [translatable]=\"true\"\n [title]=\"locale + '.search.title' | translate\"\n [subtitle]=\"locale + '.search.subtitle' | translate: { '0': parseSearchValue() }\"\n [searchValue]=\"searchValue\"\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:0px var(--dcf-padding-small);padding-bottom:0}.dcf-grid-actions .dcf-button-container{margin-top:var(--dcf-margin-small)}@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: ["multiple", "conditions", "sortOptions", "disableSort"], outputs: ["filterEvent", "searchEvent"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "parent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
12110
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ListComponent, isStandalone: true, selector: "ngx-decaf-list", inputs: { type: "type", showSearchbar: "showSearchbar", searchbarPlaceholder: "searchbarPlaceholder", data: "data", source: "source", loadMoreData: "loadMoreData", lines: "lines", inset: "inset", scrollThreshold: "scrollThreshold", scrollPosition: "scrollPosition", loadingText: "loadingText", showRefresher: "showRefresher", createButton: "createButton", loadingSpinner: "loadingSpinner", enableFilter: "enableFilter", disableSort: "disableSort", empty: "empty" }, outputs: { clickEvent: "clickEvent" }, host: { listeners: { "window:ListItemClickEvent": "handleClick($event)", "window:searchbarEvent": "handleSearch($event)" }, properties: { "attr.id": "uid" } }, usesInheritance: true, ngImport: i0, template: "@if (showRefresher) {\n <ion-refresher\n slot=\"fixed\"\n [pullFactor]=\"1\"\n [pullMin]=\"100\"\n [pullMax]=\"200\"\n (ionRefresh)=\"handleRefresh($event)\"\n >\n <ion-refresher-content />\n </ion-refresher>\n}\n\n@if (showSearchbar) {\n <div [hidden]=\"!data?.length && !searching\">\n <div class=\"dcf-grid dcf-grid-small 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 [indexes]=\"indexes ?? []\"\n [sortDirection]=\"sortDirection\"\n [disableSort]=\"disableSort\"\n (filterEvent)=\"handleFilter($event)\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n } @else {\n <ngx-decaf-searchbar\n [placeholder]=\"searchbarPlaceholder\"\n [emitEventToWindow]=\"false\"\n [debounce]=\"500\"\n (searchEvent)=\"handleSearch($event)\"\n />\n }\n </div>\n @if (createButton) {\n <div\n 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 >\n <div>\n <ion-button expand=\"block\" (click)=\"changeOperation(OperationKeys.CREATE)\">\n Create\n </ion-button>\n </div>\n </div>\n }\n </div>\n </div>\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: isModalChild ? route : undefined,\n model: child,\n isModalChild: child.isModalChild,\n emitEvent: child.emitEvent,\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 } @else {\n <ion-infinite-scroll\n [class]=\"searchValue?.length ? 'dcf-hidden' : ''\"\n [position]=\"scrollPosition\"\n [threshold]=\"scrollThreshold\"\n (ionInfinite)=\"handleRefresh($event)\"\n >\n <ion-infinite-scroll-content\n [loadingSpinner]=\"loadingSpinner\"\n [loadingText]=\"loadingText\"\n />\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%\">\n <ion-skeleton-text [animated]=\"true\"></ion-skeleton-text>\n </ion-text>\n </ion-label>\n </ion-item>\n }\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"empty.title ? (locale + '.' + empty.title | translate) : ''\"\n [model]=\"empty?.showButton ? model : undefined\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [buttonLink]=\"empty?.link ?? undefined\"\n [borders]=\"borders\"\n [icon]=\"(item?.icon ?? 'folder-open-outline') || empty.icon\"\n className=\"dcf-empty-data\"\n [subtitle]=\"empty.subtitle ? (locale + '.' + empty.subtitle | translate) : ''\"\n />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"empty?.showButton ? model : undefined\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [borders]=\"borders\"\n [operations]=\"operations\"\n [body]=\"'small'\"\n [translatable]=\"true\"\n [title]=\"locale + '.search.title' | translate\"\n [subtitle]=\"locale + '.search.subtitle' | translate: { '0': parseSearchValue() }\"\n [searchValue]=\"searchValue\"\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:0px var(--dcf-padding-small);padding-bottom:0}.dcf-grid-actions .dcf-button-container{margin-top:var(--dcf-margin-small)}@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: ["multiple", "conditions", "sortOptions", "disableSort"], outputs: ["filterEvent", "searchEvent"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "children", "projectable", "pk", "parent"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
12117
12111
  };
12118
12112
  ListComponent = __decorate([
12119
12113
  Dynamic(),
@@ -12275,7 +12269,7 @@ let ListItemComponent = class ListItemComponent extends NgxComponentDirective {
12275
12269
  * are performed on it. The emitted event contains information about the action,
12276
12270
  * the item data, and other relevant context for parent components to handle.
12277
12271
  *
12278
- * @type {EventEmitter<ListItemCustomEvent>}
12272
+ * @type {EventEmitter<IListItemCustomEvent>}
12279
12273
  * @memberOf ListItemComponent
12280
12274
  */
12281
12275
  this.clickEvent = new EventEmitter();
@@ -12389,7 +12383,7 @@ let ListItemComponent = class ListItemComponent extends NgxComponentDirective {
12389
12383
  *
12390
12384
  * @memberOf ListItemComponent
12391
12385
  */
12392
- async handleAction(action, event, target) {
12386
+ async handleAction(event, action, target) {
12393
12387
  event.stopImmediatePropagation();
12394
12388
  if (this.actionMenuOpen) {
12395
12389
  await this.actionMenuComponent.dismiss();
@@ -12544,7 +12538,7 @@ let ListItemComponent = class ListItemComponent extends NgxComponentDirective {
12544
12538
  this.actionMenuOpen = true;
12545
12539
  }
12546
12540
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12547
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ListItemComponent, isStandalone: true, selector: "ngx-decaf-list-item", inputs: { actionsType: "actionsType", lines: "lines", item: "item", icon: "icon", iconSlot: "iconSlot", button: "button", title: "title", description: "description", info: "info", subinfo: "subinfo", emitEvent: "emitEvent" }, outputs: { clickEvent: "clickEvent" }, host: { listeners: { "window:resize": "enableSlideItems($event)" }, properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }, { propertyName: "actionMenuComponent", first: true, predicate: ["actionMenuComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n@if (title || description) {\n <ion-item-sliding>\n <ion-item\n [id]=\"uid\"\n [lines]=\"lines\"\n [button]=\"!operations?.length ? false : button\"\n [class]=\"className\"\n (click)=\"operations?.includes(OperationKeys.READ) ? handleAction(OperationKeys.READ, $event, component) : ''\"\n #component\n >\n @if (icon && lines !== 'inset') {\n <div class=\"dcf-icon-container dcf-width-auto\" [slot]=\"iconSlot\">\n <ngx-decaf-icon slot=\"icon-only\" [name]=\"icon\" />\n </div>\n }\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-flex dcf-flex-middle dcf-grid-collapse\" dcf-grid>\n @if (icon && lines === 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\" />\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n @if (title) {\n <ion-label class=\"dcf-item-title\">\n {{ title | translate }}\n </ion-label>\n }\n @if (description) {\n <div class=\"dcf-description\" [innerHTML]=\"description\"></div>\n }\n </div>\n @if (info || subinfo) {\n <div class=\"dcf-width-auto@s dcf-width-expand dcf-info dcf-flex dcf-flex-right@s\">\n <div>\n @if (info) {\n <span [innerHTML]=\"info\"></span>\n }\n @if (subinfo) {\n <div class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\" ></div>\n }\n </div>\n </div>\n }\n\n <div class=\"dcf-width-auto dcf-flex dcf-flex-middle dcf-flex-right\">\n @if ((operations?.includes(OperationKeys.DELETE) || operations?.includes(OperationKeys.UPDATE)) && uid) {\n <div class=\"dcf-visible@s\" id=\"dcf-actions\">\n @if(actionsType === 'popover') {\n <ion-button shape=\"round\" fill=\"clear\" color=\"primary\" (click)=\"presentActionsMenu($event)\" [attr.aria-label]=\"locale+'.actions' | translate\">\n <ion-icon slot=\"icon-only\" aria-hidden=\"true\" name=\"ellipsis-vertical-outline\" />\n </ion-button>\n <ion-popover\n #actionMenuComponent\n side=\"bottom\"\n alignment=\"left\"\n [isOpen]=\"actionMenuOpen\"\n (didDismiss)=\"actionMenuOpen = false\">\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-list lines=\"none\">\n <ion-list-header>\n <h4 class=\"dcf-text-capitalize\" [innerHTML]=\"'actions' | translate\"></h4>\n </ion-list-header>\n @for (operation of [OperationKeys.UPDATE, OperationKeys.DELETE]; track operation) {\n @if (operations?.includes(operation)) {\n <ion-item [button]=\"true\" (click)=\"handleAction(operation, $event, component)\">\n <div slot=\"start\">\n @if (operation === OperationKeys.UPDATE) {\n <ngx-decaf-icon [button]=\"true\" slot=\"icon-only\" name=\"ti-edit\" />\n } @else {\n <ngx-decaf-icon [button]=\"true\" slot=\"icon-only\" color=\"danger\" name=\"ti-trash\" />\n }\n </div>\n <ion-label class=\"dcf-text-capitalize\">{{ operation | translate }}</ion-label>\n </ion-item>\n }\n }\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n } @else {\n <div class=\"dcf-grid-actions dcf-grid dcf-grid-small dcf-flex \">\n @for (operation of [OperationKeys.UPDATE, OperationKeys.DELETE]; track operation) {\n <div>\n @if (operations?.includes(operation)) {\n <ngx-decaf-icon\n (click)=\"handleAction(operation, $event, component)\"\n fill=\"clear\" shape=\"round\"\n [attr.aria-label]=\"(locale +'.operations.' + operation) | translate\"\n [button]=\"true\"\n slot=\"icon-only\"\n [color]=\"operation === OperationKeys.UPDATE ? 'dark' : 'danger'\"\n [name]=\"operation === OperationKeys.UPDATE ? 'ti-edit' : 'ti-trash'\"\n />\n\n }\n </div>\n }\n </div>\n }\n\n </div>\n }\n @if (windowWidth > 639) {\n <div id=\"end\">\n <ng-content select=\"[slot='end']\"></ng-content>\n </div>\n }\n </div>\n </div>\n </div>\n </ion-item>\n @if (showSlideItems && uid) {\n <ion-item-options side=\"end\" (ionSwipe)=\"operations.length === 1 ? handleAction(operations[0], $event, component) : ''\">\n @if (operations?.includes(OperationKeys.UPDATE)) {\n <ion-item-option class=\"dcf-update\" (click)=\"handleAction(OperationKeys.UPDATE, $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\" />\n </ion-item-option>\n }\n @if (operations?.includes(OperationKeys.DELETE)) {\n <ion-item-option class=\"dcf-delete\" (click)=\"handleAction(OperationKeys.DELETE, $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\" />\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n", styles: ["ion-item:not(.dcf-palette-dark){--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}ion-item:not(.dcf-palette-dark) .dcf-info{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark) .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item:not(.dcf-palette-dark) .dcf-description{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark)>ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}ion-item:not(.dcf-palette-dark) ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete),ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) ion-icon,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete *,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}ion-item.dcf-palette-dark{--background-hover-opacity: .25;--background-focused-opacity: .25;--border-color: var(--dcf-color-gray-6)}ion-item.dcf-palette-dark .dcf-description{color:var(--dcf-color-gray-4)}ion-item.dcf-palette-dark ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}ion-item.dcf-palette-dark ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete),ion-item.dcf-palette-dark ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) ion-icon,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-delete *,ion-item.dcf-palette-dark ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-update ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-sliding{box-sizing:border-box}ion-item-sliding[class*=active-slide]{border-color:var(--dcf-color-gray-3)}ion-item-sliding ion-item-option{color:var(--dcf-color-gray-5);box-shadow:inset 0 0 5px rgba(var(--dcf-color-dark-rgb),.15)!important;background:var(--dcf-color-gray-3)}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;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8)}ion-item.item-lines-full{--padding-top: .5rem;--padding-bottom: .5rem;--padding-start: .25rem;-padding-end:.25rem;padding:0 .65rem}ion-item.item-lines-inset{--padding-top: 0rem !important;--padding-bottom: 0rem !important;--inner-padding-top: .5rem !important;--inner-padding-bottom: .65rem !important}ion-item .dcf-info{min-width:10vw;background:transparent!important}ion-item .dcf-grid{padding:0!important;margin:0!important;min-width:100%!important}ion-item .dcf-item-title{font-style:normal;font-weight:600;width:max-content!important}ion-item .dcf-description{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-style:normal;font-weight:400;font-size:.925rem}ion-item::part(native){min-width:100%}ion-item [slot=start]{margin-right:.5rem!important}ion-item [slot=end]{margin-left:.5rem!important}ion-item .dcf-info{font-size:.9rem}ion-item .dcf-info .dcf-subinfo.dcf-line{margin-left:.5rem}@media (min-width: var(--dcf-width-sm)){ion-item .dcf-info .dcf-subinfo.dcf-line{display:block;margin-left:0}}ion-item #dcf-actions{padding:5px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-actions{display:none;pointer-events:none!important;cursor:text!important}ion-item #dcf-actions *{display:none;pointer-events:none!important;cursor:text!important}}@media (max-width: var(--dcf-width-m)){ion-item #dcf-end,ion-item [slot=end]{display:none!important}}ion-item #dcf-end{padding-top:5px;display:flex;align-items:flex-end}ion-item .dcf-icon{display:flex;justify-content:center;align-items:center;text-align:center;margin-right:.5rem!important}ion-item .dcf-icon.dcf-grid-icon{min-width:50px;text-align:left;display:flex;justify-content:flex-start}@media (max-width: var(--dcf-width-s)){ion-item .dcf-icon{align-items:flex-start!important}}.dcf-icon-container{background:var(--dcf-color-gray-1);border-radius:50%;width:45px;height:45px;display:flex;justify-content:center;align-items:center}.dcf-icon-container ::ng-deep ion-icon{font-size:20px;transform:translateY(3px)!important}.dcf-icon-container ::ng-deep .ti{top:1px;left:1px}\n"], dependencies: [{ kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonListHeader, selector: "ion-list-header", inputs: ["color", "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: IonItemSliding, selector: "ion-item-sliding", inputs: ["disabled"] }, { kind: "component", type: IonItemOptions, selector: "ion-item-options", inputs: ["side"] }, { kind: "component", type: IonItemOption, selector: "ion-item-option", inputs: ["color", "disabled", "download", "expandable", "href", "mode", "rel", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { 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: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { kind: "component", type: IonPopover, selector: "ion-popover" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
12541
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ListItemComponent, isStandalone: true, selector: "ngx-decaf-list-item", inputs: { actionsType: "actionsType", lines: "lines", item: "item", icon: "icon", iconSlot: "iconSlot", button: "button", title: "title", description: "description", info: "info", subinfo: "subinfo", emitEvent: "emitEvent" }, outputs: { clickEvent: "clickEvent" }, host: { listeners: { "window:resize": "enableSlideItems($event)" }, properties: { "attr.id": "uid" } }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }, { propertyName: "actionMenuComponent", first: true, predicate: ["actionMenuComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "@if (title || description) {\n <ion-item-sliding>\n <ion-item\n [id]=\"uid\"\n [lines]=\"lines\"\n [button]=\"!operations?.length ? false : button\"\n [class]=\"className\"\n (click)=\"\n operations?.includes(OperationKeys.READ)\n ? handleAction($event, OperationKeys.READ, component)\n : ''\n \"\n #component\n >\n @if (icon && lines !== 'inset') {\n <div class=\"dcf-icon-container dcf-width-auto\" [slot]=\"iconSlot\">\n <ngx-decaf-icon slot=\"icon-only\" [name]=\"icon\" />\n </div>\n }\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-flex dcf-flex-middle dcf-grid-collapse\" dcf-grid>\n @if (icon && lines === 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\" />\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n @if (title) {\n <ion-label class=\"dcf-item-title\">\n {{ title | translate }}\n </ion-label>\n }\n @if (description) {\n <div class=\"dcf-description\" [innerHTML]=\"description\"></div>\n }\n </div>\n @if (info || subinfo) {\n <div class=\"dcf-width-auto@s dcf-width-expand dcf-info dcf-flex dcf-flex-right@s\">\n <div>\n @if (info) {\n <span [innerHTML]=\"info\"></span>\n }\n @if (subinfo) {\n <div class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\"></div>\n }\n </div>\n </div>\n }\n\n <div class=\"dcf-width-auto dcf-flex dcf-flex-middle dcf-flex-right\">\n @if (\n (operations?.includes(OperationKeys.DELETE) ||\n operations?.includes(OperationKeys.UPDATE)) &&\n uid\n ) {\n <div class=\"dcf-visible@s\" id=\"dcf-actions\">\n @if (actionsType === 'popover') {\n <ion-button\n shape=\"round\"\n fill=\"clear\"\n color=\"primary\"\n (click)=\"presentActionsMenu($event)\"\n [attr.aria-label]=\"locale + '.actions' | translate\"\n >\n <ion-icon\n slot=\"icon-only\"\n aria-hidden=\"true\"\n name=\"ellipsis-vertical-outline\"\n />\n </ion-button>\n <ion-popover\n #actionMenuComponent\n side=\"bottom\"\n alignment=\"left\"\n [isOpen]=\"actionMenuOpen\"\n (didDismiss)=\"actionMenuOpen = false\"\n >\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-list lines=\"none\">\n <ion-list-header>\n <h4\n class=\"dcf-text-capitalize\"\n [innerHTML]=\"'actions' | translate\"\n ></h4>\n </ion-list-header>\n @for (\n operation of [OperationKeys.UPDATE, OperationKeys.DELETE];\n track operation\n ) {\n @if (operations?.includes(operation)) {\n <ion-item\n [button]=\"true\"\n (click)=\"handleAction($event, operation, component)\"\n >\n <div slot=\"start\">\n @if (operation === OperationKeys.UPDATE) {\n <ngx-decaf-icon\n [button]=\"true\"\n slot=\"icon-only\"\n name=\"ti-edit\"\n />\n } @else {\n <ngx-decaf-icon\n [button]=\"true\"\n slot=\"icon-only\"\n color=\"danger\"\n name=\"ti-trash\"\n />\n }\n </div>\n <ion-label class=\"dcf-text-capitalize\">\n {{ operation | translate }}\n </ion-label>\n </ion-item>\n }\n }\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n } @else {\n <div class=\"dcf-grid-actions dcf-grid dcf-grid-small dcf-flex\">\n @for (\n operation of [OperationKeys.UPDATE, OperationKeys.DELETE];\n track operation\n ) {\n <div>\n @if (operations?.includes(operation)) {\n <ngx-decaf-icon\n (click)=\"handleAction($event, operation, component)\"\n fill=\"clear\"\n shape=\"round\"\n [attr.aria-label]=\"locale + '.operations.' + operation | translate\"\n [button]=\"true\"\n slot=\"icon-only\"\n [color]=\"operation === OperationKeys.UPDATE ? 'dark' : 'danger'\"\n [name]=\"operation === OperationKeys.UPDATE ? 'ti-edit' : 'ti-trash'\"\n />\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (windowWidth > 639) {\n <div id=\"end\">\n <ng-content select=\"[slot='end']\"></ng-content>\n </div>\n }\n </div>\n </div>\n </div>\n </ion-item>\n @if (showSlideItems && uid) {\n <ion-item-options\n side=\"end\"\n (ionSwipe)=\"operations.length === 1 ? handleAction($event, operations[0], component) : ''\"\n >\n @if (operations?.includes(OperationKeys.UPDATE)) {\n <ion-item-option\n class=\"dcf-update\"\n (click)=\"handleAction($event, OperationKeys.UPDATE, component)\"\n [expandable]=\"operations.length === 1\"\n >\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\" />\n </ion-item-option>\n }\n @if (operations?.includes(OperationKeys.DELETE)) {\n <ion-item-option\n class=\"dcf-delete\"\n (click)=\"handleAction($event, OperationKeys.DELETE, component)\"\n [expandable]=\"operations.length === 1\"\n >\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\" />\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n", styles: ["ion-item:not(.dcf-palette-dark){--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}ion-item:not(.dcf-palette-dark) .dcf-info{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark) .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item:not(.dcf-palette-dark) .dcf-description{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark)>ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}ion-item:not(.dcf-palette-dark) ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete),ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) ion-icon,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete *,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}ion-item.dcf-palette-dark{--background-hover-opacity: .25;--background-focused-opacity: .25;--border-color: var(--dcf-color-gray-6)}ion-item.dcf-palette-dark .dcf-description{color:var(--dcf-color-gray-4)}ion-item.dcf-palette-dark ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}ion-item.dcf-palette-dark ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete),ion-item.dcf-palette-dark ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) ion-icon,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-delete *,ion-item.dcf-palette-dark ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-update ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-sliding{box-sizing:border-box}ion-item-sliding[class*=active-slide]{border-color:var(--dcf-color-gray-3)}ion-item-sliding ion-item-option{color:var(--dcf-color-gray-5);box-shadow:inset 0 0 5px rgba(var(--dcf-color-dark-rgb),.15)!important;background:var(--dcf-color-gray-3)}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;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8)}ion-item.item-lines-full{--padding-top: .5rem;--padding-bottom: .5rem;--padding-start: .25rem;-padding-end:.25rem;padding:0 .65rem}ion-item.item-lines-inset{--padding-top: 0rem !important;--padding-bottom: 0rem !important;--inner-padding-top: .5rem !important;--inner-padding-bottom: .65rem !important}ion-item .dcf-info{min-width:10vw;background:transparent!important}ion-item .dcf-grid{padding:0!important;margin:0!important;min-width:100%!important}ion-item .dcf-item-title{font-style:normal;font-weight:600;width:max-content!important}ion-item .dcf-description{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-style:normal;font-weight:400;font-size:.925rem}ion-item::part(native){min-width:100%}ion-item [slot=start]{margin-right:.5rem!important}ion-item [slot=end]{margin-left:.5rem!important}ion-item .dcf-info{font-size:.9rem}ion-item .dcf-info .dcf-subinfo.dcf-line{margin-left:.5rem}@media (min-width: var(--dcf-width-sm)){ion-item .dcf-info .dcf-subinfo.dcf-line{display:block;margin-left:0}}ion-item #dcf-actions{padding:5px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-actions{display:none;pointer-events:none!important;cursor:text!important}ion-item #dcf-actions *{display:none;pointer-events:none!important;cursor:text!important}}@media (max-width: var(--dcf-width-m)){ion-item #dcf-end,ion-item [slot=end]{display:none!important}}ion-item #dcf-end{padding-top:5px;display:flex;align-items:flex-end}ion-item .dcf-icon{display:flex;justify-content:center;align-items:center;text-align:center;margin-right:.5rem!important}ion-item .dcf-icon.dcf-grid-icon{min-width:50px;text-align:left;display:flex;justify-content:flex-start}@media (max-width: var(--dcf-width-s)){ion-item .dcf-icon{align-items:flex-start!important}}.dcf-icon-container{background:var(--dcf-color-gray-1);border-radius:50%;width:45px;height:45px;display:flex;justify-content:center;align-items:center}.dcf-icon-container ::ng-deep ion-icon{font-size:20px;transform:translateY(3px)!important}.dcf-icon-container ::ng-deep .ti{top:1px;left:1px}\n"], dependencies: [{ kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonListHeader, selector: "ion-list-header", inputs: ["color", "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: IonItemSliding, selector: "ion-item-sliding", inputs: ["disabled"] }, { kind: "component", type: IonItemOptions, selector: "ion-item-options", inputs: ["side"] }, { kind: "component", type: IonItemOption, selector: "ion-item-option", inputs: ["color", "disabled", "download", "expandable", "href", "mode", "rel", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { 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: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { kind: "component", type: IonPopover, selector: "ion-popover" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
12548
12542
  };
12549
12543
  ListItemComponent = __decorate([
12550
12544
  Dynamic(),
@@ -12566,7 +12560,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
12566
12560
  IonContent,
12567
12561
  IconComponent,
12568
12562
  IonPopover,
12569
- ], host: { '[attr.id]': 'uid' }, template: "\n@if (title || description) {\n <ion-item-sliding>\n <ion-item\n [id]=\"uid\"\n [lines]=\"lines\"\n [button]=\"!operations?.length ? false : button\"\n [class]=\"className\"\n (click)=\"operations?.includes(OperationKeys.READ) ? handleAction(OperationKeys.READ, $event, component) : ''\"\n #component\n >\n @if (icon && lines !== 'inset') {\n <div class=\"dcf-icon-container dcf-width-auto\" [slot]=\"iconSlot\">\n <ngx-decaf-icon slot=\"icon-only\" [name]=\"icon\" />\n </div>\n }\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-flex dcf-flex-middle dcf-grid-collapse\" dcf-grid>\n @if (icon && lines === 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\" />\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n @if (title) {\n <ion-label class=\"dcf-item-title\">\n {{ title | translate }}\n </ion-label>\n }\n @if (description) {\n <div class=\"dcf-description\" [innerHTML]=\"description\"></div>\n }\n </div>\n @if (info || subinfo) {\n <div class=\"dcf-width-auto@s dcf-width-expand dcf-info dcf-flex dcf-flex-right@s\">\n <div>\n @if (info) {\n <span [innerHTML]=\"info\"></span>\n }\n @if (subinfo) {\n <div class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\" ></div>\n }\n </div>\n </div>\n }\n\n <div class=\"dcf-width-auto dcf-flex dcf-flex-middle dcf-flex-right\">\n @if ((operations?.includes(OperationKeys.DELETE) || operations?.includes(OperationKeys.UPDATE)) && uid) {\n <div class=\"dcf-visible@s\" id=\"dcf-actions\">\n @if(actionsType === 'popover') {\n <ion-button shape=\"round\" fill=\"clear\" color=\"primary\" (click)=\"presentActionsMenu($event)\" [attr.aria-label]=\"locale+'.actions' | translate\">\n <ion-icon slot=\"icon-only\" aria-hidden=\"true\" name=\"ellipsis-vertical-outline\" />\n </ion-button>\n <ion-popover\n #actionMenuComponent\n side=\"bottom\"\n alignment=\"left\"\n [isOpen]=\"actionMenuOpen\"\n (didDismiss)=\"actionMenuOpen = false\">\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-list lines=\"none\">\n <ion-list-header>\n <h4 class=\"dcf-text-capitalize\" [innerHTML]=\"'actions' | translate\"></h4>\n </ion-list-header>\n @for (operation of [OperationKeys.UPDATE, OperationKeys.DELETE]; track operation) {\n @if (operations?.includes(operation)) {\n <ion-item [button]=\"true\" (click)=\"handleAction(operation, $event, component)\">\n <div slot=\"start\">\n @if (operation === OperationKeys.UPDATE) {\n <ngx-decaf-icon [button]=\"true\" slot=\"icon-only\" name=\"ti-edit\" />\n } @else {\n <ngx-decaf-icon [button]=\"true\" slot=\"icon-only\" color=\"danger\" name=\"ti-trash\" />\n }\n </div>\n <ion-label class=\"dcf-text-capitalize\">{{ operation | translate }}</ion-label>\n </ion-item>\n }\n }\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n } @else {\n <div class=\"dcf-grid-actions dcf-grid dcf-grid-small dcf-flex \">\n @for (operation of [OperationKeys.UPDATE, OperationKeys.DELETE]; track operation) {\n <div>\n @if (operations?.includes(operation)) {\n <ngx-decaf-icon\n (click)=\"handleAction(operation, $event, component)\"\n fill=\"clear\" shape=\"round\"\n [attr.aria-label]=\"(locale +'.operations.' + operation) | translate\"\n [button]=\"true\"\n slot=\"icon-only\"\n [color]=\"operation === OperationKeys.UPDATE ? 'dark' : 'danger'\"\n [name]=\"operation === OperationKeys.UPDATE ? 'ti-edit' : 'ti-trash'\"\n />\n\n }\n </div>\n }\n </div>\n }\n\n </div>\n }\n @if (windowWidth > 639) {\n <div id=\"end\">\n <ng-content select=\"[slot='end']\"></ng-content>\n </div>\n }\n </div>\n </div>\n </div>\n </ion-item>\n @if (showSlideItems && uid) {\n <ion-item-options side=\"end\" (ionSwipe)=\"operations.length === 1 ? handleAction(operations[0], $event, component) : ''\">\n @if (operations?.includes(OperationKeys.UPDATE)) {\n <ion-item-option class=\"dcf-update\" (click)=\"handleAction(OperationKeys.UPDATE, $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\" />\n </ion-item-option>\n }\n @if (operations?.includes(OperationKeys.DELETE)) {\n <ion-item-option class=\"dcf-delete\" (click)=\"handleAction(OperationKeys.DELETE, $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\" />\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n", styles: ["ion-item:not(.dcf-palette-dark){--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}ion-item:not(.dcf-palette-dark) .dcf-info{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark) .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item:not(.dcf-palette-dark) .dcf-description{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark)>ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}ion-item:not(.dcf-palette-dark) ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete),ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) ion-icon,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete *,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}ion-item.dcf-palette-dark{--background-hover-opacity: .25;--background-focused-opacity: .25;--border-color: var(--dcf-color-gray-6)}ion-item.dcf-palette-dark .dcf-description{color:var(--dcf-color-gray-4)}ion-item.dcf-palette-dark ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}ion-item.dcf-palette-dark ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete),ion-item.dcf-palette-dark ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) ion-icon,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-delete *,ion-item.dcf-palette-dark ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-update ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-sliding{box-sizing:border-box}ion-item-sliding[class*=active-slide]{border-color:var(--dcf-color-gray-3)}ion-item-sliding ion-item-option{color:var(--dcf-color-gray-5);box-shadow:inset 0 0 5px rgba(var(--dcf-color-dark-rgb),.15)!important;background:var(--dcf-color-gray-3)}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;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8)}ion-item.item-lines-full{--padding-top: .5rem;--padding-bottom: .5rem;--padding-start: .25rem;-padding-end:.25rem;padding:0 .65rem}ion-item.item-lines-inset{--padding-top: 0rem !important;--padding-bottom: 0rem !important;--inner-padding-top: .5rem !important;--inner-padding-bottom: .65rem !important}ion-item .dcf-info{min-width:10vw;background:transparent!important}ion-item .dcf-grid{padding:0!important;margin:0!important;min-width:100%!important}ion-item .dcf-item-title{font-style:normal;font-weight:600;width:max-content!important}ion-item .dcf-description{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-style:normal;font-weight:400;font-size:.925rem}ion-item::part(native){min-width:100%}ion-item [slot=start]{margin-right:.5rem!important}ion-item [slot=end]{margin-left:.5rem!important}ion-item .dcf-info{font-size:.9rem}ion-item .dcf-info .dcf-subinfo.dcf-line{margin-left:.5rem}@media (min-width: var(--dcf-width-sm)){ion-item .dcf-info .dcf-subinfo.dcf-line{display:block;margin-left:0}}ion-item #dcf-actions{padding:5px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-actions{display:none;pointer-events:none!important;cursor:text!important}ion-item #dcf-actions *{display:none;pointer-events:none!important;cursor:text!important}}@media (max-width: var(--dcf-width-m)){ion-item #dcf-end,ion-item [slot=end]{display:none!important}}ion-item #dcf-end{padding-top:5px;display:flex;align-items:flex-end}ion-item .dcf-icon{display:flex;justify-content:center;align-items:center;text-align:center;margin-right:.5rem!important}ion-item .dcf-icon.dcf-grid-icon{min-width:50px;text-align:left;display:flex;justify-content:flex-start}@media (max-width: var(--dcf-width-s)){ion-item .dcf-icon{align-items:flex-start!important}}.dcf-icon-container{background:var(--dcf-color-gray-1);border-radius:50%;width:45px;height:45px;display:flex;justify-content:center;align-items:center}.dcf-icon-container ::ng-deep ion-icon{font-size:20px;transform:translateY(3px)!important}.dcf-icon-container ::ng-deep .ti{top:1px;left:1px}\n"] }]
12563
+ ], host: { '[attr.id]': 'uid' }, template: "@if (title || description) {\n <ion-item-sliding>\n <ion-item\n [id]=\"uid\"\n [lines]=\"lines\"\n [button]=\"!operations?.length ? false : button\"\n [class]=\"className\"\n (click)=\"\n operations?.includes(OperationKeys.READ)\n ? handleAction($event, OperationKeys.READ, component)\n : ''\n \"\n #component\n >\n @if (icon && lines !== 'inset') {\n <div class=\"dcf-icon-container dcf-width-auto\" [slot]=\"iconSlot\">\n <ngx-decaf-icon slot=\"icon-only\" [name]=\"icon\" />\n </div>\n }\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-flex dcf-flex-middle dcf-grid-collapse\" dcf-grid>\n @if (icon && lines === 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\" />\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n @if (title) {\n <ion-label class=\"dcf-item-title\">\n {{ title | translate }}\n </ion-label>\n }\n @if (description) {\n <div class=\"dcf-description\" [innerHTML]=\"description\"></div>\n }\n </div>\n @if (info || subinfo) {\n <div class=\"dcf-width-auto@s dcf-width-expand dcf-info dcf-flex dcf-flex-right@s\">\n <div>\n @if (info) {\n <span [innerHTML]=\"info\"></span>\n }\n @if (subinfo) {\n <div class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\"></div>\n }\n </div>\n </div>\n }\n\n <div class=\"dcf-width-auto dcf-flex dcf-flex-middle dcf-flex-right\">\n @if (\n (operations?.includes(OperationKeys.DELETE) ||\n operations?.includes(OperationKeys.UPDATE)) &&\n uid\n ) {\n <div class=\"dcf-visible@s\" id=\"dcf-actions\">\n @if (actionsType === 'popover') {\n <ion-button\n shape=\"round\"\n fill=\"clear\"\n color=\"primary\"\n (click)=\"presentActionsMenu($event)\"\n [attr.aria-label]=\"locale + '.actions' | translate\"\n >\n <ion-icon\n slot=\"icon-only\"\n aria-hidden=\"true\"\n name=\"ellipsis-vertical-outline\"\n />\n </ion-button>\n <ion-popover\n #actionMenuComponent\n side=\"bottom\"\n alignment=\"left\"\n [isOpen]=\"actionMenuOpen\"\n (didDismiss)=\"actionMenuOpen = false\"\n >\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-list lines=\"none\">\n <ion-list-header>\n <h4\n class=\"dcf-text-capitalize\"\n [innerHTML]=\"'actions' | translate\"\n ></h4>\n </ion-list-header>\n @for (\n operation of [OperationKeys.UPDATE, OperationKeys.DELETE];\n track operation\n ) {\n @if (operations?.includes(operation)) {\n <ion-item\n [button]=\"true\"\n (click)=\"handleAction($event, operation, component)\"\n >\n <div slot=\"start\">\n @if (operation === OperationKeys.UPDATE) {\n <ngx-decaf-icon\n [button]=\"true\"\n slot=\"icon-only\"\n name=\"ti-edit\"\n />\n } @else {\n <ngx-decaf-icon\n [button]=\"true\"\n slot=\"icon-only\"\n color=\"danger\"\n name=\"ti-trash\"\n />\n }\n </div>\n <ion-label class=\"dcf-text-capitalize\">\n {{ operation | translate }}\n </ion-label>\n </ion-item>\n }\n }\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n } @else {\n <div class=\"dcf-grid-actions dcf-grid dcf-grid-small dcf-flex\">\n @for (\n operation of [OperationKeys.UPDATE, OperationKeys.DELETE];\n track operation\n ) {\n <div>\n @if (operations?.includes(operation)) {\n <ngx-decaf-icon\n (click)=\"handleAction($event, operation, component)\"\n fill=\"clear\"\n shape=\"round\"\n [attr.aria-label]=\"locale + '.operations.' + operation | translate\"\n [button]=\"true\"\n slot=\"icon-only\"\n [color]=\"operation === OperationKeys.UPDATE ? 'dark' : 'danger'\"\n [name]=\"operation === OperationKeys.UPDATE ? 'ti-edit' : 'ti-trash'\"\n />\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (windowWidth > 639) {\n <div id=\"end\">\n <ng-content select=\"[slot='end']\"></ng-content>\n </div>\n }\n </div>\n </div>\n </div>\n </ion-item>\n @if (showSlideItems && uid) {\n <ion-item-options\n side=\"end\"\n (ionSwipe)=\"operations.length === 1 ? handleAction($event, operations[0], component) : ''\"\n >\n @if (operations?.includes(OperationKeys.UPDATE)) {\n <ion-item-option\n class=\"dcf-update\"\n (click)=\"handleAction($event, OperationKeys.UPDATE, component)\"\n [expandable]=\"operations.length === 1\"\n >\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\" />\n </ion-item-option>\n }\n @if (operations?.includes(OperationKeys.DELETE)) {\n <ion-item-option\n class=\"dcf-delete\"\n (click)=\"handleAction($event, OperationKeys.DELETE, component)\"\n [expandable]=\"operations.length === 1\"\n >\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\" />\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n", styles: ["ion-item:not(.dcf-palette-dark){--background-hover-opacity: .1;--background-focused-opacity: .1;--border-color: var(--dcf-color-gray-2)}ion-item:not(.dcf-palette-dark) .dcf-info{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark) .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item:not(.dcf-palette-dark) .dcf-description{color:var(--dcf-color-gray-6)}ion-item:not(.dcf-palette-dark)>ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}ion-item:not(.dcf-palette-dark) ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete),ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-delete) ion-icon,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete *,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update .dcf-ti,ion-item:not(.dcf-palette-dark) ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}ion-item.dcf-palette-dark{--background-hover-opacity: .25;--background-focused-opacity: .25;--border-color: var(--dcf-color-gray-6)}ion-item.dcf-palette-dark .dcf-description{color:var(--dcf-color-gray-4)}ion-item.dcf-palette-dark ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}ion-item.dcf-palette-dark ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete),ion-item.dcf-palette-dark ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-delete) ion-icon,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) .dcf-ti,ion-item.dcf-palette-dark ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-delete .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-delete *,ion-item.dcf-palette-dark ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item.dcf-palette-dark ion-item-option.dcf-update .dcf-ti,ion-item.dcf-palette-dark ion-item-option.dcf-update ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-sliding{box-sizing:border-box}ion-item-sliding[class*=active-slide]{border-color:var(--dcf-color-gray-3)}ion-item-sliding ion-item-option{color:var(--dcf-color-gray-5);box-shadow:inset 0 0 5px rgba(var(--dcf-color-dark-rgb),.15)!important;background:var(--dcf-color-gray-3)}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;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8)}ion-item.item-lines-full{--padding-top: .5rem;--padding-bottom: .5rem;--padding-start: .25rem;-padding-end:.25rem;padding:0 .65rem}ion-item.item-lines-inset{--padding-top: 0rem !important;--padding-bottom: 0rem !important;--inner-padding-top: .5rem !important;--inner-padding-bottom: .65rem !important}ion-item .dcf-info{min-width:10vw;background:transparent!important}ion-item .dcf-grid{padding:0!important;margin:0!important;min-width:100%!important}ion-item .dcf-item-title{font-style:normal;font-weight:600;width:max-content!important}ion-item .dcf-description{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-style:normal;font-weight:400;font-size:.925rem}ion-item::part(native){min-width:100%}ion-item [slot=start]{margin-right:.5rem!important}ion-item [slot=end]{margin-left:.5rem!important}ion-item .dcf-info{font-size:.9rem}ion-item .dcf-info .dcf-subinfo.dcf-line{margin-left:.5rem}@media (min-width: var(--dcf-width-sm)){ion-item .dcf-info .dcf-subinfo.dcf-line{display:block;margin-left:0}}ion-item #dcf-actions{padding:5px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-actions{display:none;pointer-events:none!important;cursor:text!important}ion-item #dcf-actions *{display:none;pointer-events:none!important;cursor:text!important}}@media (max-width: var(--dcf-width-m)){ion-item #dcf-end,ion-item [slot=end]{display:none!important}}ion-item #dcf-end{padding-top:5px;display:flex;align-items:flex-end}ion-item .dcf-icon{display:flex;justify-content:center;align-items:center;text-align:center;margin-right:.5rem!important}ion-item .dcf-icon.dcf-grid-icon{min-width:50px;text-align:left;display:flex;justify-content:flex-start}@media (max-width: var(--dcf-width-s)){ion-item .dcf-icon{align-items:flex-start!important}}.dcf-icon-container{background:var(--dcf-color-gray-1);border-radius:50%;width:45px;height:45px;display:flex;justify-content:center;align-items:center}.dcf-icon-container ::ng-deep ion-icon{font-size:20px;transform:translateY(3px)!important}.dcf-icon-container ::ng-deep .ti{top:1px;left:1px}\n"] }]
12570
12564
  }], ctorParameters: () => [], propDecorators: { component: [{
12571
12565
  type: ViewChild,
12572
12566
  args: ['component', { read: ElementRef, static: false }]
@@ -12762,8 +12756,7 @@ let SteppedFormComponent = class SteppedFormComponent extends NgxFormDirective {
12762
12756
  this.pages = this.pageTitles.length;
12763
12757
  if (this.paginated) {
12764
12758
  if (!this.parentForm)
12765
- this.parentForm = (this.formGroup?.root ||
12766
- this.formGroup);
12759
+ this.parentForm = (this.formGroup?.root || this.formGroup);
12767
12760
  this.children = [
12768
12761
  ...this.children.map((c) => {
12769
12762
  if (!c.props)
@@ -13460,7 +13453,7 @@ let FileUploadComponent = class FileUploadComponent extends NgxFormFieldDirectiv
13460
13453
  })));
13461
13454
  }
13462
13455
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FileUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
13463
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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 + (enableDirectoryMode ? \".buttons.select_directory\" : \".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]=\"(files?.length > 1 ? 'dcf-preview-list-container' : '')\">\n @if(!files?.length) {\n <div class=\"dcf-padding-xsmall\">\n <ion-text>{{ locale + '.empty' | translate }}</ion-text>\n </div>\n } @else {\n @if(files?.length === 1 && isImageFile(files[0])) {\n <div class=\"dcf-preview dcf-grid dcf-grid-match dcf-grid-collapse read\">\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 </div>\n </div>\n </div>\n } @else {\n <ion-list class=\"dcf-preview-list\">\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 </ion-list>\n }\n }\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{padding:var(--dcf-padding-xsmall) var(--dcf-spacement-small)!important}.decaf-file-component .dcf-preview.read{padding:var(--dcf-spacement)!important}.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" }] }); }
13456
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: FileUploadComponent, isStandalone: true, selector: "ngx-decaf-file-upload", inputs: { formGroup: "formGroup", name: "name", formControl: "formControl", required: "required", multiple: "multiple", type: "type", 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 + (enableDirectoryMode ? \".buttons.select_directory\" : \".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]=\"(files?.length > 1 ? 'dcf-preview-list-container' : '')\">\n @if(!files?.length) {\n <div class=\"dcf-padding-xsmall\">\n <ion-text>{{ locale + '.empty' | translate }}</ion-text>\n </div>\n } @else {\n @if(files?.length === 1 && isImageFile(files[0])) {\n <div class=\"dcf-preview dcf-grid dcf-grid-match dcf-grid-collapse read\">\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 </div>\n </div>\n </div>\n } @else {\n <ion-list class=\"dcf-preview-list\">\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 </ion-list>\n }\n }\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{padding:var(--dcf-padding-xsmall) var(--dcf-spacement-small)!important}.decaf-file-component .dcf-preview.read{padding:var(--dcf-spacement)!important}.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" }] }); }
13464
13457
  };
13465
13458
  FileUploadComponent = __decorate([
13466
13459
  Dynamic(),
@@ -13495,8 +13488,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
13495
13488
  type: Input
13496
13489
  }], type: [{
13497
13490
  type: Input
13498
- }], label: [{
13499
- type: Input
13500
13491
  }], buttonLabel: [{
13501
13492
  type: Input
13502
13493
  }], size: [{
@@ -13695,7 +13686,7 @@ class NgxRouterService {
13695
13686
  * @memberOf RouterService
13696
13687
  */
13697
13688
  getQueryParamValue(param) {
13698
- return (this.parseAllQueryParams(param)?.[0]?.[param] || undefined);
13689
+ return this.parseAllQueryParams(param)?.[0]?.[param] || undefined;
13699
13690
  }
13700
13691
  /**
13701
13692
  * @description Retrieves the last segment of the current URL.
@@ -13724,9 +13715,7 @@ class NgxRouterService {
13724
13715
  * @memberOf RouterService
13725
13716
  */
13726
13717
  getLastUrlSegment() {
13727
- return (this.router.url || globalThis.window.location.href)
13728
- .split('/')
13729
- .pop();
13718
+ return (this.router.url || globalThis.window.location.href).split('/').pop();
13730
13719
  }
13731
13720
  /**
13732
13721
  * @description Retrieves the current URL of the application.
@@ -13789,8 +13778,7 @@ class NgxRouterService {
13789
13778
  const currentNavigation = this.router.getCurrentNavigation();
13790
13779
  if (!!currentNavigation &&
13791
13780
  currentNavigation.previousNavigation?.finalUrl?.toString() !== undefined)
13792
- this.previousUrl =
13793
- currentNavigation.previousNavigation?.finalUrl?.toString();
13781
+ this.previousUrl = currentNavigation.previousNavigation?.finalUrl?.toString();
13794
13782
  return this.previousUrl;
13795
13783
  }
13796
13784
  /**
@@ -13893,24 +13881,16 @@ let TableComponent = class TableComponent extends ListComponent {
13893
13881
  }, {});
13894
13882
  }
13895
13883
  async ngOnInit() {
13896
- this.initialized = false;
13884
+ // this.parseProps(this);
13885
+ await super.initialize();
13897
13886
  this.type = ListComponentsTypes.PAGINATED;
13898
13887
  this.empty = Object.assign({}, DefaultListEmptyOptions, this.empty);
13899
- if (!this.initialized) {
13900
- this.parseProps(this);
13901
- }
13902
13888
  this.repositoryObserverSubject
13903
13889
  .pipe(debounceTime(100), shareReplay$1(1), takeUntil$1(this.destroySubscriptions$))
13904
13890
  .subscribe(([modelInstance, event, uid]) => this.handleObserveEvent(modelInstance, event, uid));
13905
13891
  this.cols = this._cols;
13906
- if (this.allowOperations)
13907
- this.allowOperations =
13908
- this.isAllowed(OperationKeys.UPDATE) || this.isAllowed(OperationKeys.DELETE);
13892
+ this.getOperations();
13909
13893
  this.searchValue = undefined;
13910
- if (this.operations) {
13911
- this.cols.push('actions');
13912
- }
13913
- this.headers = this._headers;
13914
13894
  const filter = this.routerService.getQueryParamValue('filter');
13915
13895
  if (filter) {
13916
13896
  const value = this.routerService.getQueryParamValue('value');
@@ -13931,9 +13911,21 @@ let TableComponent = class TableComponent extends ListComponent {
13931
13911
  if (this.filterModel) {
13932
13912
  await this.getFilterOptions();
13933
13913
  }
13934
- await super.initialize();
13935
13914
  await this.refresh();
13936
13915
  }
13916
+ getOperations() {
13917
+ if (this.allowOperations) {
13918
+ this.allowOperations =
13919
+ this.isAllowed(OperationKeys.UPDATE) || this.isAllowed(OperationKeys.DELETE);
13920
+ }
13921
+ else {
13922
+ this.operations = [];
13923
+ }
13924
+ if (this.operations?.length) {
13925
+ this.cols.push('actions');
13926
+ }
13927
+ this.headers = this._headers;
13928
+ }
13937
13929
  async getFilterOptions() {
13938
13930
  const repo = getModelAndRepository(this.filterModel);
13939
13931
  if (repo) {
@@ -13953,54 +13945,81 @@ let TableComponent = class TableComponent extends ListComponent {
13953
13945
  this.filterOptions = query.map((item) => this.filterOptionsMapper(item));
13954
13946
  }
13955
13947
  }
13956
- itemMapper(item, mapper, props = {}) {
13948
+ async itemMapper(item, mapper, props = {}) {
13957
13949
  this.model = item;
13958
- const mapped = super.itemMapper(item, this.cols.filter((c) => c !== 'actions'), props);
13950
+ const mapped = await super.itemMapper(item, this.cols.filter((c) => c !== 'actions'), props);
13959
13951
  const { children } = this.props || [];
13960
- return Object.keys(mapped).reduce((accum, curr, index) => {
13961
- const child = children?.[index];
13962
- if (child) {
13963
- const { events } = child?.['props'] || {};
13964
- if (events) {
13965
- const { render } = events || undefined;
13966
- if (render) {
13967
- const clazz = new (events.render())();
13968
- const renderFn = clazz.render.bind(this);
13969
- if (renderFn instanceof Promise) {
13970
- (async () => await renderFn)();
13971
- }
13972
- else {
13973
- renderFn();
13952
+ const entries = Object.entries(mapped);
13953
+ const resultEntries = await Promise.all(entries.map(async ([curr, value], index) => {
13954
+ try {
13955
+ const child = children[index];
13956
+ if (child) {
13957
+ const { events, name } = child?.['props'] || {};
13958
+ if (events) {
13959
+ const sequence = (mapper[name]?.sequence || index) + (!this.cols.includes('actions') ? 1 : 0);
13960
+ const evts = this.parseEvents(events, this);
13961
+ for (const [key, evt] of Object.entries(evts)) {
13962
+ const handler = evt;
13963
+ if (key === ComponentEventNames.Render) {
13964
+ if (handler?.name === ComponentEventNames.Render) {
13965
+ value = await handler.bind(this)(this, name, value);
13966
+ }
13967
+ else {
13968
+ const handlerFn = await handler(this, name, value);
13969
+ value =
13970
+ typeof handlerFn === 'function' || handlerFn instanceof Promise
13971
+ ? await handlerFn.bind(this)(this, name, value)
13972
+ : handlerFn;
13973
+ }
13974
+ }
13975
+ if (key === 'handleClick' || key === 'handleAction') {
13976
+ props = {
13977
+ ...props,
13978
+ handler: {
13979
+ col: String(sequence),
13980
+ handle: handler.bind(this),
13981
+ },
13982
+ };
13983
+ }
13974
13984
  }
13975
13985
  }
13976
13986
  }
13977
13987
  }
13978
- const parserFn = mapper[this.cols[index]]?.valueParserFn || undefined;
13979
- return {
13980
- ...accum,
13981
- [curr]: parserFn ? parserFn(mapped[curr], this) : mapped[curr],
13982
- };
13983
- }, { ...props });
13988
+ catch (error) {
13989
+ this.log
13990
+ .for(this.itemMapper)
13991
+ .error(`Error mapping child events. ${error?.message || error}`);
13992
+ }
13993
+ const propName = this.cols[index];
13994
+ const parserFn = mapper[propName]?.valueParserFn || undefined;
13995
+ const resolvedValue = parserFn ? await parserFn(this, propName, value) : value;
13996
+ return [curr, resolvedValue];
13997
+ }));
13998
+ return resultEntries.reduce((accum, [key, value]) => ({ ...accum, [key]: value }), {
13999
+ ...props,
14000
+ });
13984
14001
  }
13985
14002
  async mapResults(data) {
14003
+ this._data = [...data];
13986
14004
  if (!data || !data.length)
13987
14005
  return [];
13988
- return data.reduce((accum, curr) => [
13989
- ...accum,
13990
- this.itemMapper(curr, this.mapper, { uid: curr[this.pk] }),
13991
- ], []);
14006
+ return await Promise.all(data.map((curr) => this.itemMapper(curr, this.mapper, { uid: curr[this.pk] })));
13992
14007
  }
13993
- async handleAction(event, action, uid, redirect) {
13994
- if (action === OperationKeys.READ && !this.isAllowed(OperationKeys.UPDATE)) {
13995
- redirect = false;
14008
+ async handleAction(event, handler, uid, action) {
14009
+ if (handler) {
14010
+ const handlerFn = await handler(this, event, uid);
14011
+ return typeof handlerFn === 'function' ? handlerFn() : handlerFn;
14012
+ }
14013
+ await this.handleRedirect(event, uid, action);
14014
+ }
14015
+ async handleRedirect(event, uid, action) {
14016
+ if (event instanceof Event) {
14017
+ event.preventDefault();
14018
+ event.stopImmediatePropagation();
13996
14019
  }
13997
- if (redirect) {
14020
+ if (this.operations.includes(action)) {
13998
14021
  await this.router.navigate([`/${this.route}/${action}/${uid}`]);
13999
14022
  }
14000
- event.stopImmediatePropagation();
14001
- const data = this.items.find((item) => item['uid'] === uid);
14002
- if (data)
14003
- this.listenEvent.emit({ name: ComponentEventNames.Click, data });
14004
14023
  }
14005
14024
  async openFilterSelectOptions(event) {
14006
14025
  const type = this.filterOptions.length > 10 ? SelectFieldInterfaces.MODAL : SelectFieldInterfaces.POPOVER;
@@ -14034,7 +14053,7 @@ let TableComponent = class TableComponent extends ListComponent {
14034
14053
  }
14035
14054
  }
14036
14055
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
14037
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TableComponent, isStandalone: true, selector: "ngx-decaf-table", inputs: { filterModel: "filterModel", filterOptions: "filterOptions", filterLabel: "filterLabel", filterOptionsMapper: "filterOptionsMapper", allowOperations: "allowOperations" }, usesInheritance: true, ngImport: i0, template: "@if (showSearchbar && (data?.length || searching)) {\n <div class=\"dcf-grid-actions\">\n <div class=\"dcf-grid dcf-grid-small\">\n <div class=\"dcf-width-expand@s\">\n <ngx-decaf-searchbar\n [emitEventToWindow]=\"false\"\n [debounce]=\"500\"\n (searchEvent)=\"handleSearch($event)\"\n />\n </div>\n @if (filterOptions?.length) {\n <div\n class=\"dcf-width-1-3@s dcf-width-1-4@m dcf-select-filter-container dcf-flex dcf-flex-middle\"\n >\n <ion-select\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [mode]=\"'md'\"\n fill=\"outline\"\n [value]=\"filterValue ?? ''\"\n [labelPlacement]=\"'floating'\"\n [label]=\"locale + '.filter.label' | translate\"\n (click)=\"openFilterSelectOptions($event)\"\n [placeholder]=\"locale + '.filter.label' | translate\"\n interface=\"popover\"\n >\n <ion-select-option value=\"\">{{ locale + '.filter.all' | translate }}</ion-select-option>\n @for (option of filterOptions; track $index) {\n <ion-select-option value=\"{{ option.value }}\">{{ option.text }}</ion-select-option>\n }\n <ion-button\n fill=\"clear\"\n (click)=\"handleFilterSelectClear($event)\"\n slot=\"end\"\n size=\"small\"\n [disabled]=\"!filterValue\"\n >\n <ngx-decaf-icon fill=\"clear\" slot=\"icon-only\" [name]=\"'ti-input-x'\" />\n </ion-button>\n </ion-select>\n </div>\n }\n </div>\n </div>\n}\n<div class=\"dcf-table-container\" [class.dcf-empty]=\"!data?.length\">\n @if (initialized && data?.length) {\n <table class=\"dcf-table\">\n <thead>\n <tr>\n @for (header of headers; track $index) {\n <th>{{ locale + '.' + header + '.label' | translate }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (item of items; track trackItemFn($index, item)) {\n <tr (click)=\"handleAction($event, OperationKeys.READ, item.uid, true)\">\n @for (col of item | keyvalue; track $index) {\n @if (!['actions', 'uid'].includes(col.key)) {\n <td\n [innerHTML]=\"typeof col.value === 'string' ? col.value : (col.value | async)\"\n ></td>\n } @else {\n @if (allowOperations) {\n <td class=\"dcf-col-actions\">\n <div class=\"dcf-flex dcf-flex-center\">\n @if (operations?.includes(OperationKeys.UPDATE)) {\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleAction($event, OperationKeys.UPDATE, item.uid, true)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"primary\"\n name=\"ti-edit\"\n />\n }\n @if (operations?.includes(OperationKeys.DELETE)) {\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleAction($event, OperationKeys.DELETE, item.uid, true)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"danger\"\n name=\"ti-trash\"\n />\n }\n </div>\n </td>\n }\n }\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"'component.list.empty.title' | translate\"\n [subtitle]=\"'component.list.empty.subtitle' | translate\"\n [model]=\"empty?.showButton ? model : undefined\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [buttonLink]=\"empty?.link ?? undefined\"\n [borders]=\"borders\"\n [icon]=\"(item?.icon ?? 'folder-open-outline') || empty.icon\"\n className=\"dcf-empty-data\"\n />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"empty?.showButton ? model : undefined\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [borders]=\"borders\"\n [operations]=\"operations\"\n [body]=\"'small'\"\n [translatable]=\"true\"\n [title]=\"'component.list.search.title' | translate\"\n [subtitle]=\"'component.list.search.subtitle' | translate: { '0': parseSearchValue() }\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n</div>\n@if (loadMoreData) {\n <div class=\"dcf-table-pagination\">\n @if (pages > 0 && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n }\n </div>\n}\n", styles: [".dcf-table-container{display:block;overflow-x:auto!important;box-sizing:border-box;overflow-y:hidden;scrollbar-width:thin;border-radius:var(--dcf-border-radius-small);box-shadow:var(--dcf-box-shadow-small)!important;background-color:var(--dcf-card-background);border:1px solid var(--dcf-color-gray-2)}.dcf-table-container::-webkit-scrollbar{width:5px}.dcf-table-container table{min-width:680px}.dcf-table{width:100%;border-collapse:collapse;border-radius:var(--dcf-border-radius-xsmall);overflow:hidden;background:var(--dcf-card-background);color:var(--dcf-text-color);font-size:.8rem}.dcf-table thead{background:rgba(var(--dcf-color-primary-rgb),.075);text-transform:uppercase;color:var(--dcf-color-dark);letter-spacing:.06em;font-size:.825rem;white-space:nowrap;width:auto}.dcf-table thead th{text-align:left;padding:.875rem 1rem;font-weight:600;max-width:max-content}.dcf-table tbody tr{transition:background .12s ease,box-shadow .12s ease}.dcf-table tbody tr:hover{background:rgba(var(--dcf-color-primary-rgb),.05);cursor:pointer}.dcf-table tbody tr:not(:last-child){border-bottom:1px solid var(--dcf-color-gray-2)}.dcf-table tbody td{padding:1rem 1.125rem;font-size:.875rem}.dcf-table tbody td:first-child{font-weight:600}.dcf-table tbody td.dcf-col-actions{padding-top:0!important;padding-bottom:0!important}.dcf-table tfoot{font-size:.85rem}.dcf-table tfoot td{padding:.875rem 1.125rem;border-top:1px solid 1px solid var(--dcf-color-gray-2)}.dcf-select-filter-container{min-width:200px}.dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (max-width: 480px){.dcf-buttons-grid{flex-direction:row-reverse!important}.dcf-buttons-grid>div{width:100%}.dcf-buttons-grid>div+div{margin-top:1rem}.dcf-buttons-grid ion-button{width:100%}}ion-select{margin-top:.5rem;max-height:40px!important}ion-select ion-button{transform:scale(.75)!important;margin:0!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: 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: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { kind: "component", type: PaginationComponent, selector: "ngx-decaf-pagination", inputs: ["totalPages", "current"], outputs: ["clickEvent"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
14056
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TableComponent, isStandalone: true, selector: "ngx-decaf-table", inputs: { filterModel: "filterModel", filterOptions: "filterOptions", filterLabel: "filterLabel", filterOptionsMapper: "filterOptionsMapper", allowOperations: "allowOperations" }, usesInheritance: true, ngImport: i0, template: "@if (showSearchbar && (data?.length || searching)) {\n <div class=\"dcf-grid-actions\">\n <div class=\"dcf-grid dcf-grid-small\">\n <div class=\"dcf-width-expand@s\">\n <ngx-decaf-searchbar\n [emitEventToWindow]=\"false\"\n [debounce]=\"500\"\n (searchEvent)=\"handleSearch($event)\"\n />\n </div>\n @if (filterOptions?.length) {\n <div\n class=\"dcf-width-1-3@s dcf-width-1-4@m dcf-select-filter-container dcf-flex dcf-flex-middle\"\n >\n <ion-select\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [mode]=\"'md'\"\n fill=\"outline\"\n [value]=\"filterValue ?? ''\"\n [labelPlacement]=\"'floating'\"\n [label]=\"locale + '.filter.label' | translate\"\n (click)=\"openFilterSelectOptions($event)\"\n [placeholder]=\"locale + '.filter.label' | translate\"\n interface=\"popover\"\n >\n <ion-select-option value=\"\">{{ locale + '.filter.all' | translate }}</ion-select-option>\n @for (option of filterOptions; track $index) {\n <ion-select-option value=\"{{ option.value }}\">{{ option.text }}</ion-select-option>\n }\n <ion-button\n fill=\"clear\"\n (click)=\"handleFilterSelectClear($event)\"\n slot=\"end\"\n size=\"small\"\n [disabled]=\"!filterValue\"\n >\n <ngx-decaf-icon fill=\"clear\" slot=\"icon-only\" [name]=\"'ti-input-x'\" />\n </ion-button>\n </ion-select>\n </div>\n }\n </div>\n </div>\n}\n<div class=\"dcf-table-container\" [class.dcf-empty]=\"!data?.length\">\n @if (initialized && data?.length) {\n <table class=\"dcf-table\">\n <thead>\n <tr>\n @for (header of headers; track $index) {\n <th>{{ locale + '.' + header + '.label' | translate }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (item of items; track trackItemFn($index, item)) {\n <tr>\n @for (col of item | keyvalue; track $index) {\n @if (!['handler', 'actions', 'uid'].includes(col.key)) {\n <td\n (click)=\"\n handleAction(\n $event,\n item?.handler && item?.handler.col === col.key\n ? item.handler.handle\n : undefined,\n item.uid,\n OperationKeys.READ\n )\n \"\n [innerHTML]=\"col.value\"\n ></td>\n } @else {\n @if (allowOperations && col.key !== 'handler') {\n <td class=\"dcf-col-actions\">\n <div class=\"\">\n @if (operations?.includes(OperationKeys.UPDATE)) {\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleRedirect($event, item.uid, OperationKeys.UPDATE, true)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"primary\"\n name=\"ti-edit\"\n />\n }\n @if (operations?.includes(OperationKeys.DELETE)) {\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleRedirect($event, item.uid, OperationKeys.DELETE, true)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"danger\"\n name=\"ti-trash\"\n />\n }\n </div>\n </td>\n }\n }\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"'component.list.empty.title' | translate\"\n [subtitle]=\"'component.list.empty.subtitle' | translate\"\n [model]=\"empty?.showButton ? model : undefined\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [buttonLink]=\"empty?.link ?? undefined\"\n [borders]=\"borders\"\n [icon]=\"(item?.icon ?? 'folder-open-outline') || empty.icon\"\n className=\"dcf-empty-data\"\n />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"empty?.showButton ? model : undefined\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [borders]=\"borders\"\n [operations]=\"operations\"\n [body]=\"'small'\"\n [translatable]=\"true\"\n [title]=\"'component.list.search.title' | translate\"\n [subtitle]=\"'component.list.search.subtitle' | translate: { '0': parseSearchValue() }\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n</div>\n@if (loadMoreData) {\n <div class=\"dcf-table-pagination\">\n @if (pages > 0 && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n }\n </div>\n}\n", styles: [".dcf-table-container{display:block;overflow-x:auto!important;box-sizing:border-box;overflow-y:hidden;scrollbar-width:thin;border-radius:var(--dcf-border-radius-small);box-shadow:var(--dcf-box-shadow-small)!important;background-color:var(--dcf-card-background);border:1px solid var(--dcf-color-gray-2)}.dcf-table-container::-webkit-scrollbar{width:5px}.dcf-table-container table{min-width:680px}.dcf-table{width:100%;border-collapse:collapse;border-radius:var(--dcf-border-radius-xsmall);overflow:hidden;background:var(--dcf-card-background);color:var(--dcf-text-color);font-size:.8rem}.dcf-table thead{background:rgba(var(--dcf-color-primary-rgb),.075);text-transform:uppercase;color:var(--dcf-color-dark);letter-spacing:.06em;font-size:.825rem;white-space:nowrap;width:auto}.dcf-table thead th{text-align:left;padding:.875rem 1rem;font-weight:600;max-width:max-content}.dcf-table tbody tr{transition:background .12s ease,box-shadow .12s ease}.dcf-table tbody tr:hover{background:rgba(var(--dcf-color-primary-rgb),.05);cursor:pointer}.dcf-table tbody tr:not(:last-child){border-bottom:1px solid var(--dcf-color-gray-2)}.dcf-table tbody td{padding:1rem 1.125rem;font-size:.875rem}.dcf-table tbody td:first-child{font-weight:600}.dcf-table tbody td.dcf-col-actions{padding-top:0!important;padding-bottom:0!important}.dcf-table tfoot{font-size:.85rem}.dcf-table tfoot td{padding:.875rem 1.125rem;border-top:1px solid 1px solid var(--dcf-color-gray-2)}.dcf-select-filter-container{min-width:200px}.dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (max-width: 480px){.dcf-buttons-grid{flex-direction:row-reverse!important}.dcf-buttons-grid>div{width:100%}.dcf-buttons-grid>div+div{margin-top:1rem}.dcf-buttons-grid ion-button{width:100%}}ion-select{margin-top:.5rem;max-height:40px!important}ion-select ion-button{transform:scale(.75)!important;margin:0!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: 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: IconComponent, selector: "ngx-decaf-icon", inputs: ["name", "color", "slot", "button", "buttonFill", "buttonShape", "width", "size", "inline"] }, { kind: "component", type: PaginationComponent, selector: "ngx-decaf-pagination", inputs: ["totalPages", "current"], outputs: ["clickEvent"] }, { kind: "pipe", type: i1$1.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
14038
14057
  };
14039
14058
  TableComponent = __decorate([
14040
14059
  Dynamic()
@@ -14050,7 +14069,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
14050
14069
  EmptyStateComponent,
14051
14070
  IconComponent,
14052
14071
  PaginationComponent,
14053
- ], template: "@if (showSearchbar && (data?.length || searching)) {\n <div class=\"dcf-grid-actions\">\n <div class=\"dcf-grid dcf-grid-small\">\n <div class=\"dcf-width-expand@s\">\n <ngx-decaf-searchbar\n [emitEventToWindow]=\"false\"\n [debounce]=\"500\"\n (searchEvent)=\"handleSearch($event)\"\n />\n </div>\n @if (filterOptions?.length) {\n <div\n class=\"dcf-width-1-3@s dcf-width-1-4@m dcf-select-filter-container dcf-flex dcf-flex-middle\"\n >\n <ion-select\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [mode]=\"'md'\"\n fill=\"outline\"\n [value]=\"filterValue ?? ''\"\n [labelPlacement]=\"'floating'\"\n [label]=\"locale + '.filter.label' | translate\"\n (click)=\"openFilterSelectOptions($event)\"\n [placeholder]=\"locale + '.filter.label' | translate\"\n interface=\"popover\"\n >\n <ion-select-option value=\"\">{{ locale + '.filter.all' | translate }}</ion-select-option>\n @for (option of filterOptions; track $index) {\n <ion-select-option value=\"{{ option.value }}\">{{ option.text }}</ion-select-option>\n }\n <ion-button\n fill=\"clear\"\n (click)=\"handleFilterSelectClear($event)\"\n slot=\"end\"\n size=\"small\"\n [disabled]=\"!filterValue\"\n >\n <ngx-decaf-icon fill=\"clear\" slot=\"icon-only\" [name]=\"'ti-input-x'\" />\n </ion-button>\n </ion-select>\n </div>\n }\n </div>\n </div>\n}\n<div class=\"dcf-table-container\" [class.dcf-empty]=\"!data?.length\">\n @if (initialized && data?.length) {\n <table class=\"dcf-table\">\n <thead>\n <tr>\n @for (header of headers; track $index) {\n <th>{{ locale + '.' + header + '.label' | translate }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (item of items; track trackItemFn($index, item)) {\n <tr (click)=\"handleAction($event, OperationKeys.READ, item.uid, true)\">\n @for (col of item | keyvalue; track $index) {\n @if (!['actions', 'uid'].includes(col.key)) {\n <td\n [innerHTML]=\"typeof col.value === 'string' ? col.value : (col.value | async)\"\n ></td>\n } @else {\n @if (allowOperations) {\n <td class=\"dcf-col-actions\">\n <div class=\"dcf-flex dcf-flex-center\">\n @if (operations?.includes(OperationKeys.UPDATE)) {\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleAction($event, OperationKeys.UPDATE, item.uid, true)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"primary\"\n name=\"ti-edit\"\n />\n }\n @if (operations?.includes(OperationKeys.DELETE)) {\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleAction($event, OperationKeys.DELETE, item.uid, true)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"danger\"\n name=\"ti-trash\"\n />\n }\n </div>\n </td>\n }\n }\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"'component.list.empty.title' | translate\"\n [subtitle]=\"'component.list.empty.subtitle' | translate\"\n [model]=\"empty?.showButton ? model : undefined\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [buttonLink]=\"empty?.link ?? undefined\"\n [borders]=\"borders\"\n [icon]=\"(item?.icon ?? 'folder-open-outline') || empty.icon\"\n className=\"dcf-empty-data\"\n />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"empty?.showButton ? model : undefined\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [borders]=\"borders\"\n [operations]=\"operations\"\n [body]=\"'small'\"\n [translatable]=\"true\"\n [title]=\"'component.list.search.title' | translate\"\n [subtitle]=\"'component.list.search.subtitle' | translate: { '0': parseSearchValue() }\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n</div>\n@if (loadMoreData) {\n <div class=\"dcf-table-pagination\">\n @if (pages > 0 && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n }\n </div>\n}\n", styles: [".dcf-table-container{display:block;overflow-x:auto!important;box-sizing:border-box;overflow-y:hidden;scrollbar-width:thin;border-radius:var(--dcf-border-radius-small);box-shadow:var(--dcf-box-shadow-small)!important;background-color:var(--dcf-card-background);border:1px solid var(--dcf-color-gray-2)}.dcf-table-container::-webkit-scrollbar{width:5px}.dcf-table-container table{min-width:680px}.dcf-table{width:100%;border-collapse:collapse;border-radius:var(--dcf-border-radius-xsmall);overflow:hidden;background:var(--dcf-card-background);color:var(--dcf-text-color);font-size:.8rem}.dcf-table thead{background:rgba(var(--dcf-color-primary-rgb),.075);text-transform:uppercase;color:var(--dcf-color-dark);letter-spacing:.06em;font-size:.825rem;white-space:nowrap;width:auto}.dcf-table thead th{text-align:left;padding:.875rem 1rem;font-weight:600;max-width:max-content}.dcf-table tbody tr{transition:background .12s ease,box-shadow .12s ease}.dcf-table tbody tr:hover{background:rgba(var(--dcf-color-primary-rgb),.05);cursor:pointer}.dcf-table tbody tr:not(:last-child){border-bottom:1px solid var(--dcf-color-gray-2)}.dcf-table tbody td{padding:1rem 1.125rem;font-size:.875rem}.dcf-table tbody td:first-child{font-weight:600}.dcf-table tbody td.dcf-col-actions{padding-top:0!important;padding-bottom:0!important}.dcf-table tfoot{font-size:.85rem}.dcf-table tfoot td{padding:.875rem 1.125rem;border-top:1px solid 1px solid var(--dcf-color-gray-2)}.dcf-select-filter-container{min-width:200px}.dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (max-width: 480px){.dcf-buttons-grid{flex-direction:row-reverse!important}.dcf-buttons-grid>div{width:100%}.dcf-buttons-grid>div+div{margin-top:1rem}.dcf-buttons-grid ion-button{width:100%}}ion-select{margin-top:.5rem;max-height:40px!important}ion-select ion-button{transform:scale(.75)!important;margin:0!important}\n"] }]
14072
+ ], template: "@if (showSearchbar && (data?.length || searching)) {\n <div class=\"dcf-grid-actions\">\n <div class=\"dcf-grid dcf-grid-small\">\n <div class=\"dcf-width-expand@s\">\n <ngx-decaf-searchbar\n [emitEventToWindow]=\"false\"\n [debounce]=\"500\"\n (searchEvent)=\"handleSearch($event)\"\n />\n </div>\n @if (filterOptions?.length) {\n <div\n class=\"dcf-width-1-3@s dcf-width-1-4@m dcf-select-filter-container dcf-flex dcf-flex-middle\"\n >\n <ion-select\n [id]=\"name\"\n toggleIcon=\"chevron-down-outline\"\n expandedIcon=\"chevron-up-outline\"\n [mode]=\"'md'\"\n fill=\"outline\"\n [value]=\"filterValue ?? ''\"\n [labelPlacement]=\"'floating'\"\n [label]=\"locale + '.filter.label' | translate\"\n (click)=\"openFilterSelectOptions($event)\"\n [placeholder]=\"locale + '.filter.label' | translate\"\n interface=\"popover\"\n >\n <ion-select-option value=\"\">{{ locale + '.filter.all' | translate }}</ion-select-option>\n @for (option of filterOptions; track $index) {\n <ion-select-option value=\"{{ option.value }}\">{{ option.text }}</ion-select-option>\n }\n <ion-button\n fill=\"clear\"\n (click)=\"handleFilterSelectClear($event)\"\n slot=\"end\"\n size=\"small\"\n [disabled]=\"!filterValue\"\n >\n <ngx-decaf-icon fill=\"clear\" slot=\"icon-only\" [name]=\"'ti-input-x'\" />\n </ion-button>\n </ion-select>\n </div>\n }\n </div>\n </div>\n}\n<div class=\"dcf-table-container\" [class.dcf-empty]=\"!data?.length\">\n @if (initialized && data?.length) {\n <table class=\"dcf-table\">\n <thead>\n <tr>\n @for (header of headers; track $index) {\n <th>{{ locale + '.' + header + '.label' | translate }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (item of items; track trackItemFn($index, item)) {\n <tr>\n @for (col of item | keyvalue; track $index) {\n @if (!['handler', 'actions', 'uid'].includes(col.key)) {\n <td\n (click)=\"\n handleAction(\n $event,\n item?.handler && item?.handler.col === col.key\n ? item.handler.handle\n : undefined,\n item.uid,\n OperationKeys.READ\n )\n \"\n [innerHTML]=\"col.value\"\n ></td>\n } @else {\n @if (allowOperations && col.key !== 'handler') {\n <td class=\"dcf-col-actions\">\n <div class=\"\">\n @if (operations?.includes(OperationKeys.UPDATE)) {\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleRedirect($event, item.uid, OperationKeys.UPDATE, true)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"primary\"\n name=\"ti-edit\"\n />\n }\n @if (operations?.includes(OperationKeys.DELETE)) {\n <ngx-decaf-icon\n [button]=\"true\"\n (click)=\"handleRedirect($event, item.uid, OperationKeys.DELETE, true)\"\n fill=\"clear\"\n slot=\"icon-only\"\n color=\"danger\"\n name=\"ti-trash\"\n />\n }\n </div>\n </td>\n }\n }\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n @if (!searching) {\n <ngx-decaf-empty-state\n [title]=\"'component.list.empty.title' | translate\"\n [subtitle]=\"'component.list.empty.subtitle' | translate\"\n [model]=\"empty?.showButton ? model : undefined\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [buttonLink]=\"empty?.link ?? undefined\"\n [borders]=\"borders\"\n [icon]=\"(item?.icon ?? 'folder-open-outline') || empty.icon\"\n className=\"dcf-empty-data\"\n />\n } @else {\n <ngx-decaf-empty-state\n icon=\"search-outline\"\n [model]=\"empty?.showButton ? model : undefined\"\n [route]=\"route\"\n [modelId]=\"modelId\"\n [borders]=\"borders\"\n [operations]=\"operations\"\n [body]=\"'small'\"\n [translatable]=\"true\"\n [title]=\"'component.list.search.title' | translate\"\n [subtitle]=\"'component.list.search.subtitle' | translate: { '0': parseSearchValue() }\"\n [searchValue]=\"searchValue\"\n />\n }\n }\n</div>\n@if (loadMoreData) {\n <div class=\"dcf-table-pagination\">\n @if (pages > 0 && !searchValue?.length) {\n <ngx-decaf-pagination\n [totalPages]=\"pages\"\n [current]=\"page\"\n (clickEvent)=\"handlePaginate($event)\"\n />\n }\n </div>\n}\n", styles: [".dcf-table-container{display:block;overflow-x:auto!important;box-sizing:border-box;overflow-y:hidden;scrollbar-width:thin;border-radius:var(--dcf-border-radius-small);box-shadow:var(--dcf-box-shadow-small)!important;background-color:var(--dcf-card-background);border:1px solid var(--dcf-color-gray-2)}.dcf-table-container::-webkit-scrollbar{width:5px}.dcf-table-container table{min-width:680px}.dcf-table{width:100%;border-collapse:collapse;border-radius:var(--dcf-border-radius-xsmall);overflow:hidden;background:var(--dcf-card-background);color:var(--dcf-text-color);font-size:.8rem}.dcf-table thead{background:rgba(var(--dcf-color-primary-rgb),.075);text-transform:uppercase;color:var(--dcf-color-dark);letter-spacing:.06em;font-size:.825rem;white-space:nowrap;width:auto}.dcf-table thead th{text-align:left;padding:.875rem 1rem;font-weight:600;max-width:max-content}.dcf-table tbody tr{transition:background .12s ease,box-shadow .12s ease}.dcf-table tbody tr:hover{background:rgba(var(--dcf-color-primary-rgb),.05);cursor:pointer}.dcf-table tbody tr:not(:last-child){border-bottom:1px solid var(--dcf-color-gray-2)}.dcf-table tbody td{padding:1rem 1.125rem;font-size:.875rem}.dcf-table tbody td:first-child{font-weight:600}.dcf-table tbody td.dcf-col-actions{padding-top:0!important;padding-bottom:0!important}.dcf-table tfoot{font-size:.85rem}.dcf-table tfoot td{padding:.875rem 1.125rem;border-top:1px solid 1px solid var(--dcf-color-gray-2)}.dcf-select-filter-container{min-width:200px}.dcf-buttons-grid{margin-top:var(--dcf-margin-medium);margin-bottom:var(--dcf-margin)}@media (max-width: 480px){.dcf-buttons-grid{flex-direction:row-reverse!important}.dcf-buttons-grid>div{width:100%}.dcf-buttons-grid>div+div{margin-top:1rem}.dcf-buttons-grid ion-button{width:100%}}ion-select{margin-top:.5rem;max-height:40px!important}ion-select ion-button{transform:scale(.75)!important;margin:0!important}\n"] }]
14054
14073
  }], propDecorators: { filterModel: [{
14055
14074
  type: Input
14056
14075
  }], filterOptions: [{
@@ -14191,13 +14210,13 @@ class NgxEventHandler extends DecafEventHandler {
14191
14210
  // eslint-disable-next-line @typescript-eslint/no-useless-constructor
14192
14211
  constructor() {
14193
14212
  super();
14194
- //TODO: pass to ui decorator decaf componnet
14195
- this.readonly = false;
14213
+ this._data = null;
14196
14214
  }
14197
14215
  async handle(event, data, instance, ...args) {
14198
14216
  this.log.for(this.handle).info(`Handle called with args: ${event}, ${data}, ${instance}`);
14199
14217
  }
14200
14218
  from(...args) {
14219
+ this.log.for(this.process).info(`Process called with args: ${args}`);
14201
14220
  return this;
14202
14221
  }
14203
14222
  async process(...args) {
@@ -14341,5 +14360,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
14341
14360
  * Generated bundle index. Do not edit.
14342
14361
  */
14343
14362
 
14344
- export { ActionRoles, AngularEngineKeys, BaseComponentProps, CPTKN, CardComponent, ComponentEventNames, ComponentRendererComponent, ComponentsTagNames, CrudFieldComponent, CrudFormComponent, CssClasses, DB_ADAPTER_FLAVOUR_TOKEN, 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, ModalConfirmComponent, ModelRendererComponent, NgxComponentDirective, NgxEventHandler, NgxFormDirective, NgxFormFieldDirective, NgxFormService, NgxMediaService, NgxModelPageDirective, NgxPageDirective, NgxParentComponentDirective, NgxRenderingEngine, NgxRouterService, NgxSvgDirective, PaginationComponent, RouteDirections, SearchbarComponent, SelectFieldInterfaces, SteppedFormComponent, TableComponent, TransactionHooks, WindowColorSchemes, cleanSpaces, dataMapper, decafPageTransition, filterString, formatDate, generateRandomValue, getDbAdapterFlavour, getFakerData, getInjectablesRegistry, getLocaleContext, getLocaleContextByKey, getLocaleFromClassName, getLocaleLanguage, getLogger, getMenuIcon, getModelAndRepository, getNgxInlineModal, getNgxModalComponent, getNgxModalCrudComponent, getNgxSelectOptionsModal, getOnWindow, getOnWindowDocument, getWindow, getWindowDocument, getWindowWidth, isClassConstructor, isDarkMode, isDevelopmentMode, isNotUndefined, isValidDate, itemMapper, parseToValidDate, presentModalConfirm, presentNgxInlineModal, presentNgxLightBoxModal, provideDecafDarkMode, provideDecafDbAdapter, provideDecafDynamicComponents, provideDecafI18nConfig, provideDecafI18nLoader, provideDecafPageTransition, removeFocusTrap, setOnWindow, stringToBoolean, windowEventEmitter };
14363
+ export { ActionRoles, AngularEngineKeys, BaseComponentProps, CPTKN, CardComponent, ComponentRendererComponent, ComponentsTagNames, CrudFieldComponent, CrudFormComponent, CssClasses, DB_ADAPTER_FLAVOUR_TOKEN, DB_ADAPTER_PROVIDER_TOKEN, DecafFakerRepository, DefaultFormReactiveOptions, DefaultListEmptyOptions, DefaultModalOptions, Dynamic, DynamicModule, EmptyStateComponent, FieldsetComponent, FileUploadComponent, FilterComponent, ForAngularCommonModule, ForAngularComponentsModule, I18N_CONFIG_TOKEN, I18nLoader, I18nLoaderFactory, I18nParser, IconComponent, LOCALE_ROOT_TOKEN, LayoutComponent, ListComponent, ListComponentsTypes, ListItemComponent, ListItemPositions, ModalComponent, ModalConfirmComponent, ModelRendererComponent, NgxComponentDirective, NgxEventHandler, NgxFormDirective, NgxFormFieldDirective, NgxFormService, NgxMediaService, NgxModelPageDirective, NgxPageDirective, NgxParentComponentDirective, NgxRenderingEngine, NgxRouterService, NgxSvgDirective, PaginationComponent, RouteDirections, SearchbarComponent, SelectFieldInterfaces, SteppedFormComponent, TableComponent, WindowColorSchemes, cleanSpaces, dataMapper, decafPageTransition, filterString, formatDate, generateRandomValue, getDbAdapterFlavour, getFakerData, getInjectablesRegistry, getLocaleContext, getLocaleContextByKey, getLocaleFromClassName, getLocaleLanguage, getLogger, getMenuIcon, getModelAndRepository, getNgxInlineModal, getNgxModalComponent, getNgxModalCrudComponent, getNgxSelectOptionsModal, getOnWindow, getOnWindowDocument, getWindow, getWindowDocument, getWindowWidth, isDarkMode, isDevelopmentMode, isNotUndefined, isValidDate, itemMapper, presentModalConfirm, presentNgxInlineModal, presentNgxLightBoxModal, provideDecafDarkMode, provideDecafDbAdapter, provideDecafDynamicComponents, provideDecafI18nConfig, provideDecafI18nLoader, provideDecafPageTransition, removeFocusTrap, setOnWindow, stringToBoolean, windowEventEmitter };
14345
14364
  //# sourceMappingURL=decaf-ts-for-angular.mjs.map