ngx-material-entity 15.1.0 → 15.1.2

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.
Files changed (28) hide show
  1. package/classes/entity.utilities.d.ts +37 -0
  2. package/components/input/date/date-range-input/date-range-input.component.d.ts +6 -3
  3. package/components/input/date/date-time-input/date-time-input.component.d.ts +2 -1
  4. package/components/input/file/file-image-input/file-image-input.component.d.ts +4 -2
  5. package/components/input/file/file-input/file-input.component.d.ts +5 -2
  6. package/components/input/string/string-password-input/string-password-input.component.d.ts +2 -1
  7. package/decorators/base/base-property.decorator.d.ts +2 -1
  8. package/decorators/custom/custom.decorator.d.ts +2 -1
  9. package/encapsulation/reflect.utilities.d.ts +9 -0
  10. package/esm2020/classes/entity.utilities.mjs +51 -2
  11. package/esm2020/components/input/date/date-range-input/date-range-input.component.mjs +21 -1
  12. package/esm2020/components/input/date/date-time-input/date-time-input.component.mjs +9 -1
  13. package/esm2020/components/input/file/file-default-input/file-default-input.component.mjs +3 -3
  14. package/esm2020/components/input/file/file-image-input/file-image-input.component.mjs +17 -3
  15. package/esm2020/components/input/file/file-input/file-input.component.mjs +14 -2
  16. package/esm2020/components/input/string/string-password-input/string-password-input.component.mjs +8 -3
  17. package/esm2020/decorators/base/base-property.decorator.mjs +6 -2
  18. package/esm2020/decorators/base/property-decorator-internal.data.mjs +3 -3
  19. package/esm2020/decorators/custom/custom.decorator.mjs +4 -3
  20. package/esm2020/decorators/date/date.decorator.mjs +4 -3
  21. package/esm2020/decorators/file/file.decorator.mjs +4 -3
  22. package/esm2020/decorators/string/string.decorator.mjs +3 -2
  23. package/esm2020/encapsulation/reflect.utilities.mjs +12 -1
  24. package/fesm2015/ngx-material-entity.mjs +341 -226
  25. package/fesm2015/ngx-material-entity.mjs.map +1 -1
  26. package/fesm2020/ngx-material-entity.mjs +337 -223
  27. package/fesm2020/ngx-material-entity.mjs.map +1 -1
  28. package/package.json +1 -1
@@ -45,89 +45,6 @@ import { MatSort } from '@angular/material/sort';
45
45
  import * as i9 from '@angular/material/menu';
46
46
  import { MatMenuModule } from '@angular/material/menu';
47
47
 
48
- /**
49
- * Encapsulates all functionality of Reflect.
50
- */
51
- class ReflectUtilities {
52
- /**
53
- * Gets the metadata value for the provided metadata key on the target object or its prototype chain.
54
- *
55
- * @param metadataKey - A key used to store and retrieve metadata.
56
- * @param target - The target object on which the metadata is defined.
57
- * @param propertyKey - The property key for the target.
58
- * @returns The metadata value for the metadata key if found; otherwise, undefined.
59
- */
60
- static getMetadata(metadataKey, target, propertyKey) {
61
- return Reflect.getMetadata(metadataKey, target, propertyKey);
62
- }
63
- /**
64
- * Returns the string and symbol keys of the own properties of an object. The own properties of an object
65
- * are those that are defined directly on that object, and are not inherited from the object's prototype.
66
- *
67
- * @param target - Object that contains the own properties.
68
- * @returns The keys of the given object.
69
- */
70
- static ownKeys(target) {
71
- return Reflect.ownKeys(target);
72
- }
73
- /**
74
- * Gets the property of target, equivalent to `target[propertyKey]`.
75
- *
76
- * @param target - Object that contains the property on itself or in its prototype chain.
77
- * @param propertyKey - The property name.
78
- * @returns The property of the target of the given key.
79
- */
80
- static get(target, propertyKey) {
81
- return Reflect.get(target, propertyKey);
82
- }
83
- /**
84
- * Sets the property of target, equivalent to `target[propertyKey] = value`.
85
- *
86
- * @param target - Object that contains the property on itself or in its prototype chain.
87
- * @param propertyKey - The property name.
88
- * @param value - The value to set the property to.
89
- * @returns If setting the value was successful.
90
- */
91
- static set(target, propertyKey, value) {
92
- return Reflect.set(target, propertyKey, value);
93
- }
94
- /**
95
- * Equivalent to `propertyKey in target`.
96
- *
97
- * @param target - Object that contains the property on itself or in its prototype chain.
98
- * @param propertyKey - Name of the property.
99
- * @returns Whether or not the given target has the key.
100
- */
101
- static has(target, propertyKey) {
102
- return Reflect.has(target, propertyKey);
103
- }
104
- /**
105
- * Define a unique metadata entry on the target.
106
- *
107
- * @param metadataKey - A key used to store and retrieve metadata.
108
- * @param metadataValue - A value that contains attached metadata.
109
- * @param target - The target object on which to define metadata.
110
- * @param propertyKey - The property key for the target.
111
- */
112
- static defineMetadata(metadataKey, metadataValue, target, propertyKey) {
113
- Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey);
114
- }
115
- }
116
-
117
- /**
118
- * The base decorator for setting metadata on properties.
119
- *
120
- * @param metadata - The metadata to define.
121
- * @param type - The type of metadata.
122
- * @returns The method that sets the metadata.
123
- */
124
- function baseProperty(metadata, type) {
125
- return function (target, propertyKey) {
126
- ReflectUtilities.defineMetadata('metadata', metadata, target, propertyKey);
127
- ReflectUtilities.defineMetadata('type', type, target, propertyKey);
128
- };
129
- }
130
-
131
48
  /**
132
49
  * The enum Values for all the different DecoratorTypes.
133
50
  */
@@ -160,135 +77,6 @@ var DecoratorTypes;
160
77
  DecoratorTypes["CUSTOM"] = "custom";
161
78
  })(DecoratorTypes || (DecoratorTypes = {}));
162
79
 
163
- /**
164
- * The internal Position. Sets default values and validates user input.
165
- */
166
- class PositionInternal {
167
- constructor(data) {
168
- var _a, _b, _c;
169
- this.validateInput(data);
170
- this.row = (_a = data === null || data === void 0 ? void 0 : data.row) !== null && _a !== void 0 ? _a : -1;
171
- this.order = (_b = data === null || data === void 0 ? void 0 : data.order) !== null && _b !== void 0 ? _b : -1;
172
- this.tab = (_c = data === null || data === void 0 ? void 0 : data.tab) !== null && _c !== void 0 ? _c : -1;
173
- this.tabName = data === null || data === void 0 ? void 0 : data.tabName;
174
- }
175
- validateInput(data) {
176
- if ((data === null || data === void 0 ? void 0 : data.order) != null) {
177
- if (data.order < 1) {
178
- throw new Error('order must be at least 1');
179
- }
180
- if (data.order > 12) {
181
- throw new Error('order cannot be bigger than 12 (the minimum value for a bootstrap column)');
182
- }
183
- }
184
- if ((data === null || data === void 0 ? void 0 : data.row) != null && data.row < 1) {
185
- throw new Error('row must be at least 1');
186
- }
187
- if ((data === null || data === void 0 ? void 0 : data.tab) != null && data.tab < 2) {
188
- throw new Error('tab must be at least 2');
189
- }
190
- }
191
- }
192
- /**
193
- * The internal PropertyDecoratorConfig. Sets default values.
194
- */
195
- class PropertyDecoratorConfigInternal {
196
- constructor(data) {
197
- var _a, _b, _c, _d, _e;
198
- this.display = (_a = data.display) !== null && _a !== void 0 ? _a : true;
199
- this.displayName = data.displayName;
200
- this.required = (_b = data.required) !== null && _b !== void 0 ? _b : true;
201
- this.omitForCreate = (_c = data.omitForCreate) !== null && _c !== void 0 ? _c : false;
202
- this.omitForUpdate = (_d = data.omitForUpdate) !== null && _d !== void 0 ? _d : false;
203
- this.defaultWidths = (_e = data.defaultWidths) !== null && _e !== void 0 ? _e : [6, 6, 12];
204
- this.position = new PositionInternal(data.position);
205
- }
206
- }
207
-
208
- /**
209
- * The internal DropdownStringDecoratorConfig. Sets default values.
210
- */
211
- class DropdownStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
212
- constructor(data) {
213
- super(data);
214
- this.displayStyle = data.displayStyle;
215
- this.dropdownValues = data.dropdownValues;
216
- }
217
- }
218
- /**
219
- * The internal DefaultStringDecoratorConfig. Sets default values.
220
- */
221
- class DefaultStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
222
- constructor(data) {
223
- super(data);
224
- this.displayStyle = data.displayStyle;
225
- this.minLength = data.minLength;
226
- this.maxLength = data.maxLength;
227
- this.regex = data.regex;
228
- }
229
- }
230
- /**
231
- * The internal TextboxStringDecoratorConfig. Sets default values.
232
- */
233
- class TextboxStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
234
- constructor(data) {
235
- super(data);
236
- this.displayStyle = data.displayStyle;
237
- this.minLength = data.minLength;
238
- this.maxLength = data.maxLength;
239
- }
240
- }
241
- /**
242
- * The internal AutocompleteStringDecoratorConfig. Sets default values.
243
- */
244
- class AutocompleteStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
245
- constructor(data) {
246
- super(data);
247
- this.displayStyle = data.displayStyle;
248
- this.autocompleteValues = data.autocompleteValues;
249
- this.minLength = data.minLength;
250
- this.maxLength = data.maxLength;
251
- this.regex = data.regex;
252
- }
253
- }
254
- /**
255
- * The internal PasswordStringDecoratorConfig. Sets default values.
256
- */
257
- class PasswordStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
258
- constructor(data) {
259
- var _a, _b, _c;
260
- super(data);
261
- this.displayStyle = data.displayStyle;
262
- this.minLength = data.minLength;
263
- this.maxLength = data.maxLength;
264
- this.regex = data.regex;
265
- this.needsConfirmation = (_a = data.needsConfirmation) !== null && _a !== void 0 ? _a : true;
266
- this.confirmationDisplayName = (_b = data.confirmationDisplayName) !== null && _b !== void 0 ? _b : 'Confirm Password';
267
- this.passwordsDontMatchErrorMessage = (_c = data.passwordsDontMatchErrorMessage) !== null && _c !== void 0 ? _c : 'Passwords need to match!';
268
- }
269
- }
270
-
271
- /**
272
- * Decorator for setting and getting string Property metadata.
273
- *
274
- * @param metadata - The metadata of the string property.
275
- * @returns The method that defines the metadata.
276
- */
277
- function string(metadata) {
278
- switch (metadata.displayStyle) {
279
- case 'dropdown':
280
- return baseProperty(new DropdownStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_DROPDOWN);
281
- case 'autocomplete':
282
- return baseProperty(new AutocompleteStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_AUTOCOMPLETE);
283
- case 'textbox':
284
- return baseProperty(new TextboxStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_TEXTBOX);
285
- case 'password':
286
- return baseProperty(new PasswordStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_PASSWORD);
287
- default:
288
- return baseProperty(new DefaultStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING);
289
- }
290
- }
291
-
292
80
  /**
293
81
  * Encapsulates all functionality of lodash.
294
82
  */
@@ -363,6 +151,86 @@ class LodashUtilities {
363
151
  }
364
152
  }
365
153
 
154
+ /**
155
+ * Encapsulates all functionality of Reflect.
156
+ */
157
+ class ReflectUtilities {
158
+ /**
159
+ * Gets the metadata value for the provided metadata key on the target object or its prototype chain.
160
+ *
161
+ * @param metadataKey - A key used to store and retrieve metadata.
162
+ * @param target - The target object on which the metadata is defined.
163
+ * @param propertyKey - The property key for the target.
164
+ * @returns The metadata value for the metadata key if found; otherwise, undefined.
165
+ */
166
+ static getMetadata(metadataKey, target, propertyKey) {
167
+ return Reflect.getMetadata(metadataKey, target, propertyKey);
168
+ }
169
+ /**
170
+ * Returns the string and symbol keys of the own properties of an object. The own properties of an object
171
+ * are those that are defined directly on that object, and are not inherited from the object's prototype.
172
+ *
173
+ * @param target - Object that contains the own properties.
174
+ * @returns The keys of the given object.
175
+ */
176
+ static ownKeys(target) {
177
+ return Reflect.ownKeys(target);
178
+ }
179
+ /**
180
+ * Gets the property of target, equivalent to `target[propertyKey]`.
181
+ *
182
+ * @param target - Object that contains the property on itself or in its prototype chain.
183
+ * @param propertyKey - The property name.
184
+ * @returns The property of the target of the given key.
185
+ */
186
+ static get(target, propertyKey) {
187
+ return Reflect.get(target, propertyKey);
188
+ }
189
+ /**
190
+ * Sets the property of target, equivalent to `target[propertyKey] = value`.
191
+ *
192
+ * @param target - Object that contains the property on itself or in its prototype chain.
193
+ * @param propertyKey - The property name.
194
+ * @param value - The value to set the property to.
195
+ * @returns If setting the value was successful.
196
+ */
197
+ static set(target, propertyKey, value) {
198
+ return Reflect.set(target, propertyKey, value);
199
+ }
200
+ /**
201
+ * Equivalent to `propertyKey in target`.
202
+ *
203
+ * @param target - Object that contains the property on itself or in its prototype chain.
204
+ * @param propertyKey - Name of the property.
205
+ * @returns Whether or not the given target has the key.
206
+ */
207
+ static has(target, propertyKey) {
208
+ return Reflect.has(target, propertyKey);
209
+ }
210
+ /**
211
+ * Checks if the targets key entry has a metadata value for the given metadata key.
212
+ *
213
+ * @returns Whether the metadata is null or not.
214
+ * @param metadataKey - The key of the metadata on the property.
215
+ * @param target - Object that contains the property on itself or in its prototype chain.
216
+ * @param propertyKey - The key of the target.
217
+ */
218
+ static hasMetadata(metadataKey, target, propertyKey) {
219
+ return this.getMetadata(metadataKey, target, propertyKey) != null;
220
+ }
221
+ /**
222
+ * Define a unique metadata entry on the target.
223
+ *
224
+ * @param metadataKey - A key used to store and retrieve metadata.
225
+ * @param metadataValue - A value that contains attached metadata.
226
+ * @param target - The target object on which to define metadata.
227
+ * @param propertyKey - The property key for the target.
228
+ */
229
+ static defineMetadata(metadataKey, metadataValue, target, propertyKey) {
230
+ Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey);
231
+ }
232
+ }
233
+
366
234
  const DAY_IN_MS = 1000 * 60 * 60 * 24;
367
235
  /**
368
236
  * Contains Helper Functions for handling date properties.
@@ -1385,6 +1253,13 @@ class EntityUtilities {
1385
1253
  static resetChangesOnEntity(entity, entityPriorChanges) {
1386
1254
  for (const key in entityPriorChanges) {
1387
1255
  ReflectUtilities.set(entity, key, ReflectUtilities.get(entityPriorChanges, key));
1256
+ if (ReflectUtilities.hasMetadata(this.METADATA_KEYS_TO_RESET_KEY, entity, key)) {
1257
+ for (const k of ReflectUtilities.getMetadata(this.METADATA_KEYS_TO_RESET_KEY, entity, key)) {
1258
+ if (ReflectUtilities.hasMetadata(k, entity, key)) {
1259
+ ReflectUtilities.defineMetadata(k, undefined, entity, key);
1260
+ }
1261
+ }
1262
+ }
1388
1263
  }
1389
1264
  }
1390
1265
  static getEntityRows(entity, tab, hideOmitForCreate, hideOmitForEdit) {
@@ -1421,7 +1296,7 @@ class EntityUtilities {
1421
1296
  const numberOfTabs = EntityUtilities.getNumberOfTabs(keys, entity);
1422
1297
  if (EntityUtilities.getEntityRows(entity, -1, hideOmitForCreate, hideOmitForEdit).length) {
1423
1298
  const firstTab = {
1424
- tabName: 'Tab 1',
1299
+ tabName: EntityUtilities.getFirstTabName(entity),
1425
1300
  tab: -1,
1426
1301
  rows: EntityUtilities.getEntityRows(entity, -1, hideOmitForCreate, hideOmitForEdit)
1427
1302
  };
@@ -1461,6 +1336,13 @@ class EntityUtilities {
1461
1336
  .find(m => m.position.tab === tab && m.position.tabName)) === null || _a === void 0 ? void 0 : _a.position.tabName;
1462
1337
  return providedTabName !== null && providedTabName !== void 0 ? providedTabName : `Tab ${tab}`;
1463
1338
  }
1339
+ static getFirstTabName(entity) {
1340
+ var _a;
1341
+ const providedTabName = (_a = EntityUtilities.keysOf(entity)
1342
+ .map(k => EntityUtilities.getPropertyMetadata(entity, k))
1343
+ .find(m => m.position.tabName && m.position.tab === -1)) === null || _a === void 0 ? void 0 : _a.position.tabName;
1344
+ return providedTabName !== null && providedTabName !== void 0 ? providedTabName : 'Tab 1';
1345
+ }
1464
1346
  /**
1465
1347
  * Gets the keys of the provided entity correctly typed.
1466
1348
  *
@@ -1482,11 +1364,193 @@ class EntityUtilities {
1482
1364
  return keys;
1483
1365
  }
1484
1366
  }
1367
+ /**
1368
+ * The key for all keys of metadata that should be set to undefined when the entity gets reset.
1369
+ */
1370
+ EntityUtilities.METADATA_KEYS_TO_RESET_KEY = 'metadataKeysToReset';
1371
+ /**
1372
+ * The key for the metadata that saves the single preview image value on image properties.
1373
+ */
1374
+ EntityUtilities.SINGLE_PREVIEW_IMAGE_KEY = 'singlePreviewImage';
1375
+ /**
1376
+ * The key for the metadata that saves the multi preview images value on image properties.
1377
+ */
1378
+ EntityUtilities.MULTI_PREVIEW_IMAGES_KEY = 'multiPreviewImages';
1379
+ /**
1380
+ * The key for the metadata that saves the filenames value on file properties.
1381
+ */
1382
+ EntityUtilities.FILENAMES_KEY = 'fileNames';
1383
+ /**
1384
+ * The key for the metadata that saves the confirm password value on password properties.
1385
+ */
1386
+ EntityUtilities.CONFIRM_PASSWORD_KEY = 'confirmPassword';
1387
+ /**
1388
+ * The key for the metadata that saves the time value on date time properties.
1389
+ */
1390
+ EntityUtilities.TIME_KEY = 'time';
1391
+ /**
1392
+ * The key for the metadata that saves the date range value on date range properties.
1393
+ */
1394
+ EntityUtilities.DATE_RANGE_KEY = 'dateRange';
1395
+ /**
1396
+ * The key for the metadata that saves the date range start value on date range properties.
1397
+ */
1398
+ EntityUtilities.DATE_RANGE_START_KEY = 'dateRangeStart';
1399
+ /**
1400
+ * The key for the metadata that saves the date range end value on date range properties.
1401
+ */
1402
+ EntityUtilities.DATE_RANGE_END_KEY = 'dateRangeEnd';
1485
1403
  // eslint-disable-next-line @typescript-eslint/member-ordering, jsdoc/require-jsdoc, @typescript-eslint/typedef
1486
1404
  EntityUtilities.construct = EntityUtilities.new;
1487
1405
  // eslint-disable-next-line @typescript-eslint/member-ordering, jsdoc/require-jsdoc, @typescript-eslint/typedef
1488
1406
  EntityUtilities.build = EntityUtilities.new;
1489
1407
 
1408
+ /**
1409
+ * The base decorator for setting metadata on properties.
1410
+ *
1411
+ * @param metadata - The metadata to define.
1412
+ * @param type - The type of metadata.
1413
+ * @param metadataKeysToReset - Any metadata keys which values should be set to undefined on reset.
1414
+ * @returns The method that sets the metadata.
1415
+ */
1416
+ function baseProperty(metadata, type, metadataKeysToReset) {
1417
+ return function (target, propertyKey) {
1418
+ ReflectUtilities.defineMetadata('metadata', metadata, target, propertyKey);
1419
+ ReflectUtilities.defineMetadata('type', type, target, propertyKey);
1420
+ // eslint-disable-next-line max-len
1421
+ ReflectUtilities.defineMetadata(EntityUtilities.METADATA_KEYS_TO_RESET_KEY, metadataKeysToReset, target, propertyKey);
1422
+ };
1423
+ }
1424
+
1425
+ /**
1426
+ * The internal Position. Sets default values and validates user input.
1427
+ */
1428
+ class PositionInternal {
1429
+ constructor(data) {
1430
+ var _a, _b, _c;
1431
+ this.validateInput(data);
1432
+ this.row = (_a = data === null || data === void 0 ? void 0 : data.row) !== null && _a !== void 0 ? _a : -1;
1433
+ this.order = (_b = data === null || data === void 0 ? void 0 : data.order) !== null && _b !== void 0 ? _b : -1;
1434
+ this.tab = (_c = data === null || data === void 0 ? void 0 : data.tab) !== null && _c !== void 0 ? _c : -1;
1435
+ this.tabName = data === null || data === void 0 ? void 0 : data.tabName;
1436
+ }
1437
+ validateInput(data) {
1438
+ if ((data === null || data === void 0 ? void 0 : data.order) != null) {
1439
+ if (data.order < 1) {
1440
+ throw new Error('order must be at least 1');
1441
+ }
1442
+ if (data.order > 12) {
1443
+ throw new Error('order cannot be bigger than 12 (the minimum value for a bootstrap column)');
1444
+ }
1445
+ }
1446
+ if ((data === null || data === void 0 ? void 0 : data.row) != null && data.row < 1) {
1447
+ throw new Error('row must be at least 1');
1448
+ }
1449
+ if ((data === null || data === void 0 ? void 0 : data.tab) != null && data.tab != -1 && data.tab < 2) {
1450
+ throw new Error('tab must be either -1 for the first tab or at least 2');
1451
+ }
1452
+ }
1453
+ }
1454
+ /**
1455
+ * The internal PropertyDecoratorConfig. Sets default values.
1456
+ */
1457
+ class PropertyDecoratorConfigInternal {
1458
+ constructor(data) {
1459
+ var _a, _b, _c, _d, _e;
1460
+ this.display = (_a = data.display) !== null && _a !== void 0 ? _a : true;
1461
+ this.displayName = data.displayName;
1462
+ this.required = (_b = data.required) !== null && _b !== void 0 ? _b : true;
1463
+ this.omitForCreate = (_c = data.omitForCreate) !== null && _c !== void 0 ? _c : false;
1464
+ this.omitForUpdate = (_d = data.omitForUpdate) !== null && _d !== void 0 ? _d : false;
1465
+ this.defaultWidths = (_e = data.defaultWidths) !== null && _e !== void 0 ? _e : [6, 6, 12];
1466
+ this.position = new PositionInternal(data.position);
1467
+ }
1468
+ }
1469
+
1470
+ /**
1471
+ * The internal DropdownStringDecoratorConfig. Sets default values.
1472
+ */
1473
+ class DropdownStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
1474
+ constructor(data) {
1475
+ super(data);
1476
+ this.displayStyle = data.displayStyle;
1477
+ this.dropdownValues = data.dropdownValues;
1478
+ }
1479
+ }
1480
+ /**
1481
+ * The internal DefaultStringDecoratorConfig. Sets default values.
1482
+ */
1483
+ class DefaultStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
1484
+ constructor(data) {
1485
+ super(data);
1486
+ this.displayStyle = data.displayStyle;
1487
+ this.minLength = data.minLength;
1488
+ this.maxLength = data.maxLength;
1489
+ this.regex = data.regex;
1490
+ }
1491
+ }
1492
+ /**
1493
+ * The internal TextboxStringDecoratorConfig. Sets default values.
1494
+ */
1495
+ class TextboxStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
1496
+ constructor(data) {
1497
+ super(data);
1498
+ this.displayStyle = data.displayStyle;
1499
+ this.minLength = data.minLength;
1500
+ this.maxLength = data.maxLength;
1501
+ }
1502
+ }
1503
+ /**
1504
+ * The internal AutocompleteStringDecoratorConfig. Sets default values.
1505
+ */
1506
+ class AutocompleteStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
1507
+ constructor(data) {
1508
+ super(data);
1509
+ this.displayStyle = data.displayStyle;
1510
+ this.autocompleteValues = data.autocompleteValues;
1511
+ this.minLength = data.minLength;
1512
+ this.maxLength = data.maxLength;
1513
+ this.regex = data.regex;
1514
+ }
1515
+ }
1516
+ /**
1517
+ * The internal PasswordStringDecoratorConfig. Sets default values.
1518
+ */
1519
+ class PasswordStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
1520
+ constructor(data) {
1521
+ var _a, _b, _c;
1522
+ super(data);
1523
+ this.displayStyle = data.displayStyle;
1524
+ this.minLength = data.minLength;
1525
+ this.maxLength = data.maxLength;
1526
+ this.regex = data.regex;
1527
+ this.needsConfirmation = (_a = data.needsConfirmation) !== null && _a !== void 0 ? _a : true;
1528
+ this.confirmationDisplayName = (_b = data.confirmationDisplayName) !== null && _b !== void 0 ? _b : 'Confirm Password';
1529
+ this.passwordsDontMatchErrorMessage = (_c = data.passwordsDontMatchErrorMessage) !== null && _c !== void 0 ? _c : 'Passwords need to match!';
1530
+ }
1531
+ }
1532
+
1533
+ /**
1534
+ * Decorator for setting and getting string Property metadata.
1535
+ *
1536
+ * @param metadata - The metadata of the string property.
1537
+ * @returns The method that defines the metadata.
1538
+ */
1539
+ function string(metadata) {
1540
+ switch (metadata.displayStyle) {
1541
+ case 'dropdown':
1542
+ return baseProperty(new DropdownStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_DROPDOWN);
1543
+ case 'autocomplete':
1544
+ return baseProperty(new AutocompleteStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_AUTOCOMPLETE);
1545
+ case 'textbox':
1546
+ return baseProperty(new TextboxStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_TEXTBOX);
1547
+ case 'password':
1548
+ return baseProperty(new PasswordStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_PASSWORD, [EntityUtilities.CONFIRM_PASSWORD_KEY]);
1549
+ default:
1550
+ return baseProperty(new DefaultStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING);
1551
+ }
1552
+ }
1553
+
1490
1554
  /**
1491
1555
  * A base Entity class with a builtin id.
1492
1556
  */
@@ -2332,6 +2396,24 @@ class DateRangeInputComponent extends NgxMatEntityBaseInputComponent {
2332
2396
  super(...arguments);
2333
2397
  this.defaultDateFilter = DateUtilities.defaultDateFilter;
2334
2398
  }
2399
+ get dateRange() {
2400
+ return ReflectUtilities.getMetadata(EntityUtilities.DATE_RANGE_KEY, this.entity, this.key);
2401
+ }
2402
+ set dateRange(value) {
2403
+ ReflectUtilities.defineMetadata(EntityUtilities.DATE_RANGE_KEY, value, this.entity, this.key);
2404
+ }
2405
+ get dateRangeStart() {
2406
+ return ReflectUtilities.getMetadata(EntityUtilities.DATE_RANGE_START_KEY, this.entity, this.key);
2407
+ }
2408
+ set dateRangeStart(value) {
2409
+ ReflectUtilities.defineMetadata(EntityUtilities.DATE_RANGE_START_KEY, value, this.entity, this.key);
2410
+ }
2411
+ get dateRangeEnd() {
2412
+ return ReflectUtilities.getMetadata(EntityUtilities.DATE_RANGE_END_KEY, this.entity, this.key);
2413
+ }
2414
+ set dateRangeEnd(value) {
2415
+ ReflectUtilities.defineMetadata(EntityUtilities.DATE_RANGE_END_KEY, value, this.entity, this.key);
2416
+ }
2335
2417
  ngOnInit() {
2336
2418
  var _a;
2337
2419
  super.ngOnInit();
@@ -2370,6 +2452,12 @@ class DateTimeInputComponent extends NgxMatEntityBaseInputComponent {
2370
2452
  this.DateUtilities = DateUtilities;
2371
2453
  this.defaultDateFilter = () => true;
2372
2454
  }
2455
+ get time() {
2456
+ return ReflectUtilities.getMetadata(EntityUtilities.TIME_KEY, this.entity, this.key);
2457
+ }
2458
+ set time(value) {
2459
+ ReflectUtilities.defineMetadata(EntityUtilities.TIME_KEY, value, this.entity, this.key);
2460
+ }
2373
2461
  ngOnInit() {
2374
2462
  super.ngOnInit();
2375
2463
  this.time = DateUtilities.getTimeFromDate(this.propertyValue);
@@ -2483,6 +2571,12 @@ class FileInputComponent {
2483
2571
  this.FileUtilities = FileUtilities;
2484
2572
  this.fileDataChangeEvent = new EventEmitter();
2485
2573
  }
2574
+ get filenames() {
2575
+ return ReflectUtilities.getMetadata(EntityUtilities.FILENAMES_KEY, this.entity, this.key);
2576
+ }
2577
+ set filenames(value) {
2578
+ ReflectUtilities.defineMetadata(EntityUtilities.FILENAMES_KEY, value, this.entity, this.key);
2579
+ }
2486
2580
  ngOnInit() {
2487
2581
  return __awaiter(this, void 0, void 0, function* () {
2488
2582
  if (this.metadata.multiple) {
@@ -2646,12 +2740,16 @@ class FileInputComponent {
2646
2740
  }
2647
2741
  }
2648
2742
  FileInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: FileInputComponent, deps: [{ token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
2649
- FileInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.3", type: FileInputComponent, selector: "file-input", inputs: { propertyValue: "propertyValue", metadata: "metadata", getValidationErrorMessage: "getValidationErrorMessage", isReadOnly: "isReadOnly" }, outputs: { fileDataChangeEvent: "fileDataChangeEvent" }, ngImport: i0, template: "<input #fileInput\n type=\"file\" hidden\n [multiple]=\"metadata.multiple\"\n [accept]=\"FileUtilities.getAcceptString(metadata.allowedMimeTypes)\"\n (change)=\"setFileFromInput($event)\"\n>\n\n<mat-form-field floatLabel=\"always\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-grid #chipGrid\n [(ngModel)]=\"filenames\" name=\"file\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip-row *ngFor=\"let name of filenames\" (removed)=\"removeFile(name)\">\n {{name}}\n <span class=\"mat-mdc-chip-remove mat-mdc-chip-trailing-icon ngx-mat-grey\" (click)=\"downloadFile(name)\">\n <i class=\"fas fa-download\"></i>\n </span>\n <button *ngIf=\"!isReadOnly\" type=\"button\" matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip-row>\n <input [matChipInputFor]=\"chipGrid\" [readonly]=\"true\" hidden>\n </mat-chip-grid>\n <button *ngIf=\"downloadAllEnabled()\" type=\"button\" class=\"ngx-mat-grey\" mat-icon-button matSuffix (click)=\"downloadAll()\">\n <i class=\"fas fa-file-zipper\"></i>\n </button>\n <button type=\"button\" class=\"ngx-mat-grey\" mat-icon-button matSuffix [disabled]=\"isReadOnly\" (click)=\"fileInput.click()\">\n <i class=\"fas fa-upload\"></i>\n </button>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>\n\n<div *ngIf=\"metadata.dragAndDrop && !isReadOnly\" class=\"drag-drop\" dragDrop (files)=\"setFile($event)\">\n <button type=\"button\" mat-icon-button [disabled]=\"isReadOnly\" (click)=\"fileInput.click()\">\n <i class=\"fas fa-file-arrow-up ngx-mat-grey\"></i>\n </button>\n</div>", styles: ["mat-form-field{width:100%}.ngx-mat-grey{opacity:1;color:#0000008a}.drag-drop{display:flex;align-items:center;justify-content:center;height:200px;border:2px dashed rgba(0,0,0,.54);border-radius:15px;margin-top:5px;margin-bottom:5px}.drag-drop i{font-size:30px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5$3.MatChipGrid, selector: "mat-chip-grid", inputs: ["tabIndex", "disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i5$3.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i5$3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i5$3.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["color", "disabled", "disableRipple", "tabIndex", "editable"], outputs: ["edited"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: DragDropDirective, selector: "[dragDrop]", outputs: ["files"] }] });
2743
+ FileInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.3", type: FileInputComponent, selector: "file-input", inputs: { propertyValue: "propertyValue", entity: "entity", key: "key", metadata: "metadata", getValidationErrorMessage: "getValidationErrorMessage", isReadOnly: "isReadOnly" }, outputs: { fileDataChangeEvent: "fileDataChangeEvent" }, ngImport: i0, template: "<input #fileInput\n type=\"file\" hidden\n [multiple]=\"metadata.multiple\"\n [accept]=\"FileUtilities.getAcceptString(metadata.allowedMimeTypes)\"\n (change)=\"setFileFromInput($event)\"\n>\n\n<mat-form-field floatLabel=\"always\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-grid #chipGrid\n [(ngModel)]=\"filenames\" name=\"file\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip-row *ngFor=\"let name of filenames\" (removed)=\"removeFile(name)\">\n {{name}}\n <span class=\"mat-mdc-chip-remove mat-mdc-chip-trailing-icon ngx-mat-grey\" (click)=\"downloadFile(name)\">\n <i class=\"fas fa-download\"></i>\n </span>\n <button *ngIf=\"!isReadOnly\" type=\"button\" matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip-row>\n <input [matChipInputFor]=\"chipGrid\" [readonly]=\"true\" hidden>\n </mat-chip-grid>\n <button *ngIf=\"downloadAllEnabled()\" type=\"button\" class=\"ngx-mat-grey\" mat-icon-button matSuffix (click)=\"downloadAll()\">\n <i class=\"fas fa-file-zipper\"></i>\n </button>\n <button type=\"button\" class=\"ngx-mat-grey\" mat-icon-button matSuffix [disabled]=\"isReadOnly\" (click)=\"fileInput.click()\">\n <i class=\"fas fa-upload\"></i>\n </button>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>\n\n<div *ngIf=\"metadata.dragAndDrop && !isReadOnly\" class=\"drag-drop\" dragDrop (files)=\"setFile($event)\">\n <button type=\"button\" mat-icon-button [disabled]=\"isReadOnly\" (click)=\"fileInput.click()\">\n <i class=\"fas fa-file-arrow-up ngx-mat-grey\"></i>\n </button>\n</div>", styles: ["mat-form-field{width:100%}.ngx-mat-grey{opacity:1;color:#0000008a}.drag-drop{display:flex;align-items:center;justify-content:center;height:200px;border:2px dashed rgba(0,0,0,.54);border-radius:15px;margin-top:5px;margin-bottom:5px}.drag-drop i{font-size:30px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5$3.MatChipGrid, selector: "mat-chip-grid", inputs: ["tabIndex", "disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i5$3.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i5$3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i5$3.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["color", "disabled", "disableRipple", "tabIndex", "editable"], outputs: ["edited"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: DragDropDirective, selector: "[dragDrop]", outputs: ["files"] }] });
2650
2744
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: FileInputComponent, decorators: [{
2651
2745
  type: Component,
2652
2746
  args: [{ selector: 'file-input', template: "<input #fileInput\n type=\"file\" hidden\n [multiple]=\"metadata.multiple\"\n [accept]=\"FileUtilities.getAcceptString(metadata.allowedMimeTypes)\"\n (change)=\"setFileFromInput($event)\"\n>\n\n<mat-form-field floatLabel=\"always\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-grid #chipGrid\n [(ngModel)]=\"filenames\" name=\"file\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip-row *ngFor=\"let name of filenames\" (removed)=\"removeFile(name)\">\n {{name}}\n <span class=\"mat-mdc-chip-remove mat-mdc-chip-trailing-icon ngx-mat-grey\" (click)=\"downloadFile(name)\">\n <i class=\"fas fa-download\"></i>\n </span>\n <button *ngIf=\"!isReadOnly\" type=\"button\" matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip-row>\n <input [matChipInputFor]=\"chipGrid\" [readonly]=\"true\" hidden>\n </mat-chip-grid>\n <button *ngIf=\"downloadAllEnabled()\" type=\"button\" class=\"ngx-mat-grey\" mat-icon-button matSuffix (click)=\"downloadAll()\">\n <i class=\"fas fa-file-zipper\"></i>\n </button>\n <button type=\"button\" class=\"ngx-mat-grey\" mat-icon-button matSuffix [disabled]=\"isReadOnly\" (click)=\"fileInput.click()\">\n <i class=\"fas fa-upload\"></i>\n </button>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>\n\n<div *ngIf=\"metadata.dragAndDrop && !isReadOnly\" class=\"drag-drop\" dragDrop (files)=\"setFile($event)\">\n <button type=\"button\" mat-icon-button [disabled]=\"isReadOnly\" (click)=\"fileInput.click()\">\n <i class=\"fas fa-file-arrow-up ngx-mat-grey\"></i>\n </button>\n</div>", styles: ["mat-form-field{width:100%}.ngx-mat-grey{opacity:1;color:#0000008a}.drag-drop{display:flex;align-items:center;justify-content:center;height:200px;border:2px dashed rgba(0,0,0,.54);border-radius:15px;margin-top:5px;margin-bottom:5px}.drag-drop i{font-size:30px}\n"] }]
2653
2747
  }], ctorParameters: function () { return [{ type: i1.MatDialog }]; }, propDecorators: { propertyValue: [{
2654
2748
  type: Input
2749
+ }], entity: [{
2750
+ type: Input
2751
+ }], key: [{
2752
+ type: Input
2655
2753
  }], metadata: [{
2656
2754
  type: Input
2657
2755
  }], getValidationErrorMessage: [{
@@ -2675,10 +2773,10 @@ class FileDefaultInputComponent extends NgxMatEntityBaseInputComponent {
2675
2773
  }
2676
2774
  }
2677
2775
  FileDefaultInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: FileDefaultInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2678
- FileDefaultInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.3", type: FileDefaultInputComponent, selector: "file-default-input", usesInheritance: true, ngImport: i0, template: "<div [class.file-input]=\"metadata.dragAndDrop\" [class.mat-elevation-z8]=\"metadata.dragAndDrop\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [propertyValue]=\"propertyValue\"\n [metadata]=\"metadata\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n >\n </file-input>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}\n"], dependencies: [{ kind: "component", type: FileInputComponent, selector: "file-input", inputs: ["propertyValue", "metadata", "getValidationErrorMessage", "isReadOnly"], outputs: ["fileDataChangeEvent"] }] });
2776
+ FileDefaultInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.3", type: FileDefaultInputComponent, selector: "file-default-input", usesInheritance: true, ngImport: i0, template: "<div [class.file-input]=\"metadata.dragAndDrop\" [class.mat-elevation-z8]=\"metadata.dragAndDrop\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [propertyValue]=\"propertyValue\"\n [metadata]=\"metadata\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n [entity]=\"entity\"\n [key]=\"key\"\n >\n </file-input>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}\n"], dependencies: [{ kind: "component", type: FileInputComponent, selector: "file-input", inputs: ["propertyValue", "entity", "key", "metadata", "getValidationErrorMessage", "isReadOnly"], outputs: ["fileDataChangeEvent"] }] });
2679
2777
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: FileDefaultInputComponent, decorators: [{
2680
2778
  type: Component,
2681
- args: [{ selector: 'file-default-input', template: "<div [class.file-input]=\"metadata.dragAndDrop\" [class.mat-elevation-z8]=\"metadata.dragAndDrop\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [propertyValue]=\"propertyValue\"\n [metadata]=\"metadata\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n >\n </file-input>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}\n"] }]
2779
+ args: [{ selector: 'file-default-input', template: "<div [class.file-input]=\"metadata.dragAndDrop\" [class.mat-elevation-z8]=\"metadata.dragAndDrop\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [propertyValue]=\"propertyValue\"\n [metadata]=\"metadata\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n [entity]=\"entity\"\n [key]=\"key\"\n >\n </file-input>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}\n"] }]
2682
2780
  }] });
2683
2781
 
2684
2782
  // eslint-disable-next-line max-len
@@ -2691,6 +2789,18 @@ class FileImageInputComponent extends NgxMatEntityBaseInputComponent {
2691
2789
  this.imageIndex = 0;
2692
2790
  this.placeHolder = placeholder;
2693
2791
  }
2792
+ get multiPreviewImages() {
2793
+ return ReflectUtilities.getMetadata(EntityUtilities.MULTI_PREVIEW_IMAGES_KEY, this.entity, this.key);
2794
+ }
2795
+ set multiPreviewImages(value) {
2796
+ ReflectUtilities.defineMetadata(EntityUtilities.MULTI_PREVIEW_IMAGES_KEY, value, this.entity, this.key);
2797
+ }
2798
+ get singlePreviewImage() {
2799
+ return ReflectUtilities.getMetadata(EntityUtilities.SINGLE_PREVIEW_IMAGE_KEY, this.entity, this.key);
2800
+ }
2801
+ set singlePreviewImage(value) {
2802
+ ReflectUtilities.defineMetadata(EntityUtilities.SINGLE_PREVIEW_IMAGE_KEY, value, this.entity, this.key);
2803
+ }
2694
2804
  setSinglePreviewImage() {
2695
2805
  return __awaiter(this, void 0, void 0, function* () {
2696
2806
  if (this.propertyValue) {
@@ -2766,10 +2876,10 @@ class FileImageInputComponent extends NgxMatEntityBaseInputComponent {
2766
2876
  }
2767
2877
  }
2768
2878
  FileImageInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: FileImageInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2769
- FileImageInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.3", type: FileImageInputComponent, selector: "file-image-input", usesInheritance: true, ngImport: i0, template: "<div *ngIf=\"!metadata.dragAndDrop && !metadata.preview\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [propertyValue]=\"propertyValue\"\n [metadata]=\"metadata\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n >\n </file-input>\n</div>\n\n<div *ngIf=\"metadata.dragAndDrop || metadata.preview\" class=\"file-input mat-elevation-z8\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [propertyValue]=\"propertyValue\"\n [metadata]=\"metadata\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n >\n </file-input>\n\n <div class=\"image-preview\" *ngIf=\"metadata.preview && metadata.multiple\">\n <i (click)=\"prev()\" [class.disabled]=\"imageIndex === 0\" class=\"prev-button fa-solid fa-angle-left\"></i>\n <img *ngIf=\"multiPreviewImages?.[imageIndex]\" class=\"mat-elevation-z2\" [src]=\"multiPreviewImages?.[imageIndex]\">\n <img *ngIf=\"!multiPreviewImages?.[imageIndex]\" class=\"mat-elevation-z2\" [src]=\"metadata.previewPlaceholderUrl ?? placeHolder\">\n <i (click)=\"next()\"\n [class.disabled]=\"!multiPreviewImages || !multiPreviewImages.length || imageIndex === (multiPreviewImages.length - 1)\"\n class=\"next-button fa-solid fa-angle-right\"\n >\n </i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && metadata.multiple\">\n <button type=\"button\" (click)=\"setIndex(imageIndex-4)\" mat-icon-button *ngIf=\"\n this.multiPreviewImages\n && multiPreviewImages[imageIndex-4]\n && imageIndex === (this.multiPreviewImages.length - 1)\"\n >\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 3}}</span>\n </button>\n <!-- eslint-disable-next-line @angular-eslint/template/conditional-complexity -->\n <button type=\"button\" (click)=\"setIndex(imageIndex-3)\" mat-icon-button *ngIf=\"this.multiPreviewImages\n && multiPreviewImages[imageIndex-3]\n && (\n imageIndex === (this.multiPreviewImages.length - 2)\n || imageIndex === (this.multiPreviewImages.length - 1)\n )\"\n >\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 2}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex-2)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex-2]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 1}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex-1)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex-1]\">\n <i class=\"dot\"></i>\n <span class=\"image-index\">{{imageIndex}}</span>\n </button>\n <button type=\"button\" mat-icon-button disabled>\n <i class=\"dot selected\"></i>\n <span class=\"image-index\">{{imageIndex + 1}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+1)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+1]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 2}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+2)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+2]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 3}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+3)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+3] && imageIndex <= 1\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 4}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+4)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+4] && imageIndex === 0\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 5}}</span>\n </button>\n </div>\n\n <div class=\"image-preview\" *ngIf=\"metadata.preview && !metadata.multiple\">\n <i class=\"prev-button disabled fa-solid fa-angle-left\"></i>\n <img class=\"mat-elevation-z2\" [src]=\"singlePreviewImage ?? metadata.previewPlaceholderUrl ?? placeHolder\">\n <i class=\"next-button disabled fa-solid fa-angle-right\"></i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && !metadata.multiple\">\n <button type=\"button\" disabled mat-icon-button>\n <span class=\"dot selected\"></span>\n <span class=\"image-index\">1</span>\n </button>\n </div>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}.image-preview{height:250px;display:flex;align-items:center;padding-top:15px;padding-bottom:15px}.image-preview .prev-button{font-size:100px;margin-left:5px;color:#0000008a}.image-preview .next-button{font-size:100px;margin-right:5px;color:#0000008a}.image-preview .prev-button:hover,.image-preview .next-button:hover{cursor:pointer;color:#000000b3;transition:all .5s ease}.image-preview .prev-button.disabled,.image-preview .next-button.disabled{color:#00000042}.image-preview .prev-button.disabled:hover,.image-preview .next-button.disabled:hover{color:#00000042;transition:none;cursor:default}.image-preview img{max-width:calc(100% - 100px);max-height:100%;margin-left:auto;margin-right:auto;border-radius:3px}.preview-nav{text-align:center}.preview-nav button{display:inline-block;width:18px;height:18px;margin-left:5px;margin-right:5px}.preview-nav button .dot{height:100%;width:100%;background-color:#00000061;border-radius:50%;display:block}.preview-nav button .dot.selected{background-color:#0000008a}.preview-nav button .image-index{position:absolute;height:100%;width:100%;display:block;top:-11.5px;color:#fff}.preview-nav button:hover .dot{background-color:#0000008a;transition:all .3s ease}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: FileInputComponent, selector: "file-input", inputs: ["propertyValue", "metadata", "getValidationErrorMessage", "isReadOnly"], outputs: ["fileDataChangeEvent"] }] });
2879
+ FileImageInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.3", type: FileImageInputComponent, selector: "file-image-input", usesInheritance: true, ngImport: i0, template: "<div *ngIf=\"!metadata.dragAndDrop && !metadata.preview\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [propertyValue]=\"propertyValue\"\n [metadata]=\"metadata\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n [entity]=\"entity\"\n [key]=\"key\"\n >\n </file-input>\n</div>\n\n<div *ngIf=\"metadata.dragAndDrop || metadata.preview\" class=\"file-input mat-elevation-z8\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [propertyValue]=\"propertyValue\"\n [metadata]=\"metadata\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n [entity]=\"entity\"\n [key]=\"key\"\n >\n </file-input>\n\n <div class=\"image-preview\" *ngIf=\"metadata.preview && metadata.multiple\">\n <i (click)=\"prev()\" [class.disabled]=\"imageIndex === 0\" class=\"prev-button fa-solid fa-angle-left\"></i>\n <img *ngIf=\"multiPreviewImages?.[imageIndex]\" class=\"mat-elevation-z2\" [src]=\"multiPreviewImages?.[imageIndex]\">\n <img *ngIf=\"!multiPreviewImages?.[imageIndex]\" class=\"mat-elevation-z2\" [src]=\"metadata.previewPlaceholderUrl ?? placeHolder\">\n <i (click)=\"next()\"\n [class.disabled]=\"!multiPreviewImages || !multiPreviewImages.length || imageIndex === (multiPreviewImages.length - 1)\"\n class=\"next-button fa-solid fa-angle-right\"\n >\n </i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && metadata.multiple\">\n <button type=\"button\" (click)=\"setIndex(imageIndex-4)\" mat-icon-button *ngIf=\"\n this.multiPreviewImages\n && multiPreviewImages[imageIndex-4]\n && imageIndex === (this.multiPreviewImages.length - 1)\"\n >\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 3}}</span>\n </button>\n <!-- eslint-disable-next-line @angular-eslint/template/conditional-complexity -->\n <button type=\"button\" (click)=\"setIndex(imageIndex-3)\" mat-icon-button *ngIf=\"this.multiPreviewImages\n && multiPreviewImages[imageIndex-3]\n && (\n imageIndex === (this.multiPreviewImages.length - 2)\n || imageIndex === (this.multiPreviewImages.length - 1)\n )\"\n >\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 2}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex-2)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex-2]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 1}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex-1)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex-1]\">\n <i class=\"dot\"></i>\n <span class=\"image-index\">{{imageIndex}}</span>\n </button>\n <button type=\"button\" mat-icon-button disabled>\n <i class=\"dot selected\"></i>\n <span class=\"image-index\">{{imageIndex + 1}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+1)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+1]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 2}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+2)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+2]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 3}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+3)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+3] && imageIndex <= 1\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 4}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+4)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+4] && imageIndex === 0\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 5}}</span>\n </button>\n </div>\n\n <div class=\"image-preview\" *ngIf=\"metadata.preview && !metadata.multiple\">\n <i class=\"prev-button disabled fa-solid fa-angle-left\"></i>\n <img class=\"mat-elevation-z2\" [src]=\"singlePreviewImage ?? metadata.previewPlaceholderUrl ?? placeHolder\">\n <i class=\"next-button disabled fa-solid fa-angle-right\"></i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && !metadata.multiple\">\n <button type=\"button\" disabled mat-icon-button>\n <span class=\"dot selected\"></span>\n <span class=\"image-index\">1</span>\n </button>\n </div>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}.image-preview{height:250px;display:flex;align-items:center;padding-top:15px;padding-bottom:15px}.image-preview .prev-button{font-size:100px;margin-left:5px;color:#0000008a}.image-preview .next-button{font-size:100px;margin-right:5px;color:#0000008a}.image-preview .prev-button:hover,.image-preview .next-button:hover{cursor:pointer;color:#000000b3;transition:all .5s ease}.image-preview .prev-button.disabled,.image-preview .next-button.disabled{color:#00000042}.image-preview .prev-button.disabled:hover,.image-preview .next-button.disabled:hover{color:#00000042;transition:none;cursor:default}.image-preview img{max-width:calc(100% - 100px);max-height:100%;margin-left:auto;margin-right:auto;border-radius:3px}.preview-nav{text-align:center}.preview-nav button{display:inline-block;width:18px;height:18px;margin-left:5px;margin-right:5px}.preview-nav button .dot{height:100%;width:100%;background-color:#00000061;border-radius:50%;display:block}.preview-nav button .dot.selected{background-color:#0000008a}.preview-nav button .image-index{position:absolute;height:100%;width:100%;display:block;top:-11.5px;color:#fff}.preview-nav button:hover .dot{background-color:#0000008a;transition:all .3s ease}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: FileInputComponent, selector: "file-input", inputs: ["propertyValue", "entity", "key", "metadata", "getValidationErrorMessage", "isReadOnly"], outputs: ["fileDataChangeEvent"] }] });
2770
2880
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: FileImageInputComponent, decorators: [{
2771
2881
  type: Component,
2772
- args: [{ selector: 'file-image-input', template: "<div *ngIf=\"!metadata.dragAndDrop && !metadata.preview\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [propertyValue]=\"propertyValue\"\n [metadata]=\"metadata\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n >\n </file-input>\n</div>\n\n<div *ngIf=\"metadata.dragAndDrop || metadata.preview\" class=\"file-input mat-elevation-z8\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [propertyValue]=\"propertyValue\"\n [metadata]=\"metadata\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n >\n </file-input>\n\n <div class=\"image-preview\" *ngIf=\"metadata.preview && metadata.multiple\">\n <i (click)=\"prev()\" [class.disabled]=\"imageIndex === 0\" class=\"prev-button fa-solid fa-angle-left\"></i>\n <img *ngIf=\"multiPreviewImages?.[imageIndex]\" class=\"mat-elevation-z2\" [src]=\"multiPreviewImages?.[imageIndex]\">\n <img *ngIf=\"!multiPreviewImages?.[imageIndex]\" class=\"mat-elevation-z2\" [src]=\"metadata.previewPlaceholderUrl ?? placeHolder\">\n <i (click)=\"next()\"\n [class.disabled]=\"!multiPreviewImages || !multiPreviewImages.length || imageIndex === (multiPreviewImages.length - 1)\"\n class=\"next-button fa-solid fa-angle-right\"\n >\n </i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && metadata.multiple\">\n <button type=\"button\" (click)=\"setIndex(imageIndex-4)\" mat-icon-button *ngIf=\"\n this.multiPreviewImages\n && multiPreviewImages[imageIndex-4]\n && imageIndex === (this.multiPreviewImages.length - 1)\"\n >\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 3}}</span>\n </button>\n <!-- eslint-disable-next-line @angular-eslint/template/conditional-complexity -->\n <button type=\"button\" (click)=\"setIndex(imageIndex-3)\" mat-icon-button *ngIf=\"this.multiPreviewImages\n && multiPreviewImages[imageIndex-3]\n && (\n imageIndex === (this.multiPreviewImages.length - 2)\n || imageIndex === (this.multiPreviewImages.length - 1)\n )\"\n >\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 2}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex-2)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex-2]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 1}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex-1)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex-1]\">\n <i class=\"dot\"></i>\n <span class=\"image-index\">{{imageIndex}}</span>\n </button>\n <button type=\"button\" mat-icon-button disabled>\n <i class=\"dot selected\"></i>\n <span class=\"image-index\">{{imageIndex + 1}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+1)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+1]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 2}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+2)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+2]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 3}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+3)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+3] && imageIndex <= 1\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 4}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+4)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+4] && imageIndex === 0\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 5}}</span>\n </button>\n </div>\n\n <div class=\"image-preview\" *ngIf=\"metadata.preview && !metadata.multiple\">\n <i class=\"prev-button disabled fa-solid fa-angle-left\"></i>\n <img class=\"mat-elevation-z2\" [src]=\"singlePreviewImage ?? metadata.previewPlaceholderUrl ?? placeHolder\">\n <i class=\"next-button disabled fa-solid fa-angle-right\"></i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && !metadata.multiple\">\n <button type=\"button\" disabled mat-icon-button>\n <span class=\"dot selected\"></span>\n <span class=\"image-index\">1</span>\n </button>\n </div>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}.image-preview{height:250px;display:flex;align-items:center;padding-top:15px;padding-bottom:15px}.image-preview .prev-button{font-size:100px;margin-left:5px;color:#0000008a}.image-preview .next-button{font-size:100px;margin-right:5px;color:#0000008a}.image-preview .prev-button:hover,.image-preview .next-button:hover{cursor:pointer;color:#000000b3;transition:all .5s ease}.image-preview .prev-button.disabled,.image-preview .next-button.disabled{color:#00000042}.image-preview .prev-button.disabled:hover,.image-preview .next-button.disabled:hover{color:#00000042;transition:none;cursor:default}.image-preview img{max-width:calc(100% - 100px);max-height:100%;margin-left:auto;margin-right:auto;border-radius:3px}.preview-nav{text-align:center}.preview-nav button{display:inline-block;width:18px;height:18px;margin-left:5px;margin-right:5px}.preview-nav button .dot{height:100%;width:100%;background-color:#00000061;border-radius:50%;display:block}.preview-nav button .dot.selected{background-color:#0000008a}.preview-nav button .image-index{position:absolute;height:100%;width:100%;display:block;top:-11.5px;color:#fff}.preview-nav button:hover .dot{background-color:#0000008a;transition:all .3s ease}\n"] }]
2882
+ args: [{ selector: 'file-image-input', template: "<div *ngIf=\"!metadata.dragAndDrop && !metadata.preview\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [propertyValue]=\"propertyValue\"\n [metadata]=\"metadata\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n [entity]=\"entity\"\n [key]=\"key\"\n >\n </file-input>\n</div>\n\n<div *ngIf=\"metadata.dragAndDrop || metadata.preview\" class=\"file-input mat-elevation-z8\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [propertyValue]=\"propertyValue\"\n [metadata]=\"metadata\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n [entity]=\"entity\"\n [key]=\"key\"\n >\n </file-input>\n\n <div class=\"image-preview\" *ngIf=\"metadata.preview && metadata.multiple\">\n <i (click)=\"prev()\" [class.disabled]=\"imageIndex === 0\" class=\"prev-button fa-solid fa-angle-left\"></i>\n <img *ngIf=\"multiPreviewImages?.[imageIndex]\" class=\"mat-elevation-z2\" [src]=\"multiPreviewImages?.[imageIndex]\">\n <img *ngIf=\"!multiPreviewImages?.[imageIndex]\" class=\"mat-elevation-z2\" [src]=\"metadata.previewPlaceholderUrl ?? placeHolder\">\n <i (click)=\"next()\"\n [class.disabled]=\"!multiPreviewImages || !multiPreviewImages.length || imageIndex === (multiPreviewImages.length - 1)\"\n class=\"next-button fa-solid fa-angle-right\"\n >\n </i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && metadata.multiple\">\n <button type=\"button\" (click)=\"setIndex(imageIndex-4)\" mat-icon-button *ngIf=\"\n this.multiPreviewImages\n && multiPreviewImages[imageIndex-4]\n && imageIndex === (this.multiPreviewImages.length - 1)\"\n >\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 3}}</span>\n </button>\n <!-- eslint-disable-next-line @angular-eslint/template/conditional-complexity -->\n <button type=\"button\" (click)=\"setIndex(imageIndex-3)\" mat-icon-button *ngIf=\"this.multiPreviewImages\n && multiPreviewImages[imageIndex-3]\n && (\n imageIndex === (this.multiPreviewImages.length - 2)\n || imageIndex === (this.multiPreviewImages.length - 1)\n )\"\n >\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 2}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex-2)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex-2]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 1}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex-1)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex-1]\">\n <i class=\"dot\"></i>\n <span class=\"image-index\">{{imageIndex}}</span>\n </button>\n <button type=\"button\" mat-icon-button disabled>\n <i class=\"dot selected\"></i>\n <span class=\"image-index\">{{imageIndex + 1}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+1)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+1]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 2}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+2)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+2]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 3}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+3)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+3] && imageIndex <= 1\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 4}}</span>\n </button>\n <button type=\"button\" (click)=\"setIndex(imageIndex+4)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+4] && imageIndex === 0\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 5}}</span>\n </button>\n </div>\n\n <div class=\"image-preview\" *ngIf=\"metadata.preview && !metadata.multiple\">\n <i class=\"prev-button disabled fa-solid fa-angle-left\"></i>\n <img class=\"mat-elevation-z2\" [src]=\"singlePreviewImage ?? metadata.previewPlaceholderUrl ?? placeHolder\">\n <i class=\"next-button disabled fa-solid fa-angle-right\"></i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && !metadata.multiple\">\n <button type=\"button\" disabled mat-icon-button>\n <span class=\"dot selected\"></span>\n <span class=\"image-index\">1</span>\n </button>\n </div>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}.image-preview{height:250px;display:flex;align-items:center;padding-top:15px;padding-bottom:15px}.image-preview .prev-button{font-size:100px;margin-left:5px;color:#0000008a}.image-preview .next-button{font-size:100px;margin-right:5px;color:#0000008a}.image-preview .prev-button:hover,.image-preview .next-button:hover{cursor:pointer;color:#000000b3;transition:all .5s ease}.image-preview .prev-button.disabled,.image-preview .next-button.disabled{color:#00000042}.image-preview .prev-button.disabled:hover,.image-preview .next-button.disabled:hover{color:#00000042;transition:none;cursor:default}.image-preview img{max-width:calc(100% - 100px);max-height:100%;margin-left:auto;margin-right:auto;border-radius:3px}.preview-nav{text-align:center}.preview-nav button{display:inline-block;width:18px;height:18px;margin-left:5px;margin-right:5px}.preview-nav button .dot{height:100%;width:100%;background-color:#00000061;border-radius:50%;display:block}.preview-nav button .dot.selected{background-color:#0000008a}.preview-nav button .image-index{position:absolute;height:100%;width:100%;display:block;top:-11.5px;color:#fff}.preview-nav button:hover .dot{background-color:#0000008a;transition:all .3s ease}\n"] }]
2773
2883
  }] });
2774
2884
 
2775
2885
  const NGX_GET_VALIDATION_ERROR_MESSAGE = new InjectionToken('Provider for the default getValidationErrorMessage.', {
@@ -2939,15 +3049,19 @@ class StringPasswordInputComponent extends NgxMatEntityBaseInputComponent {
2939
3049
  this.hide = true;
2940
3050
  this.hideConfirm = true;
2941
3051
  }
3052
+ get confirmPassword() {
3053
+ return ReflectUtilities.getMetadata(EntityUtilities.CONFIRM_PASSWORD_KEY, this.entity, this.key);
3054
+ }
3055
+ set confirmPassword(value) {
3056
+ ReflectUtilities.defineMetadata(EntityUtilities.CONFIRM_PASSWORD_KEY, value, this.entity, this.key);
3057
+ }
2942
3058
  ngOnInit() {
2943
3059
  super.ngOnInit();
2944
3060
  this.confirmRequired = this.metadata.required;
2945
3061
  this.confirmPassword = LodashUtilities.cloneDeep(this.propertyValue);
2946
- ReflectUtilities.defineMetadata('confirmPassword', this.confirmPassword, this.entity, this.key);
2947
3062
  }
2948
3063
  passwordInput() {
2949
3064
  this.confirmRequired = Boolean(this.propertyValue);
2950
- ReflectUtilities.defineMetadata('confirmPassword', this.confirmPassword, this.entity, this.key);
2951
3065
  this.emitChange();
2952
3066
  }
2953
3067
  }
@@ -4380,10 +4494,10 @@ function date(metadata) {
4380
4494
  return baseProperty(new DefaultDateDecoratorConfigInternal(metadata), DecoratorTypes.DATE);
4381
4495
  }
4382
4496
  else if (metadata.displayStyle === 'datetime') {
4383
- return baseProperty(new DateTimeDateDecoratorConfigInternal(metadata), DecoratorTypes.DATE_TIME);
4497
+ return baseProperty(new DateTimeDateDecoratorConfigInternal(metadata), DecoratorTypes.DATE_TIME, [EntityUtilities.TIME_KEY]);
4384
4498
  }
4385
4499
  else {
4386
- return baseProperty(new DateRangeDateDecoratorConfigInternal(metadata), DecoratorTypes.DATE_RANGE);
4500
+ return baseProperty(new DateRangeDateDecoratorConfigInternal(metadata), DecoratorTypes.DATE_RANGE, [EntityUtilities.DATE_RANGE_END_KEY, EntityUtilities.DATE_RANGE_KEY, EntityUtilities.DATE_RANGE_START_KEY]);
4387
4501
  }
4388
4502
  }
4389
4503
 
@@ -4646,9 +4760,9 @@ function getDefaultMaxSizeTotalErrorDialogData(data) {
4646
4760
  function file(metadata) {
4647
4761
  switch (metadata.type) {
4648
4762
  case 'other':
4649
- return baseProperty(new DefaultFileDecoratorConfigInternal(metadata), DecoratorTypes.FILE_DEFAULT);
4763
+ return baseProperty(new DefaultFileDecoratorConfigInternal(metadata), DecoratorTypes.FILE_DEFAULT, [EntityUtilities.FILENAMES_KEY]);
4650
4764
  case 'image':
4651
- return baseProperty(new ImageFileDecoratorConfigInternal(metadata), DecoratorTypes.FILE_IMAGE);
4765
+ return baseProperty(new ImageFileDecoratorConfigInternal(metadata), DecoratorTypes.FILE_IMAGE, [EntityUtilities.FILENAMES_KEY, EntityUtilities.MULTI_PREVIEW_IMAGES_KEY, EntityUtilities.SINGLE_PREVIEW_IMAGE_KEY]);
4652
4766
  default:
4653
4767
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
4654
4768
  throw new Error(`Unknown metadata type ${metadata.type}`);
@@ -4690,10 +4804,11 @@ class CustomDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
4690
4804
  * Decorator for setting and getting custom property metadata.
4691
4805
  *
4692
4806
  * @param metadata - The metadata of the custom property.
4807
+ * @param metadataKeysToReset - Any metadata keys which values should be set to undefined on reset.
4693
4808
  * @returns The method that defines the metadata.
4694
4809
  */
4695
- function custom(metadata) {
4696
- return baseProperty(new CustomDecoratorConfigInternal(metadata), DecoratorTypes.CUSTOM);
4810
+ function custom(metadata, metadataKeysToReset) {
4811
+ return baseProperty(new CustomDecoratorConfigInternal(metadata), DecoratorTypes.CUSTOM, metadataKeysToReset);
4697
4812
  }
4698
4813
 
4699
4814
  /**