ngx-material-entity 0.1.3 → 1.0.0

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 (163) hide show
  1. package/README.md +914 -336
  2. package/capsulation/lodash.utilities.d.ts +62 -0
  3. package/capsulation/reflect.utilities.d.ts +56 -0
  4. package/classes/{base-builder.class.d.ts → base.builder.d.ts} +2 -1
  5. package/classes/date.utilities.d.ts +70 -0
  6. package/classes/entity.model.d.ts +20 -0
  7. package/classes/entity.service.d.ts +108 -0
  8. package/classes/{entity-utilities.class.d.ts → entity.utilities.d.ts} +52 -16
  9. package/classes/file.utilities.d.ts +52 -0
  10. package/components/confirm-dialog/confirm-dialog-data.builder.d.ts +1 -1
  11. package/components/input/add-array-item-dialog-data.builder.d.ts +4 -4
  12. package/components/input/add-array-item-dialog-data.d.ts +2 -2
  13. package/components/input/array/array-date-input/array-date-input.component.d.ts +11 -0
  14. package/components/input/array/array-date-range-input/array-date-range-input.component.d.ts +20 -0
  15. package/components/input/array/array-date-time-input/array-date-time-input.component.d.ts +22 -0
  16. package/components/input/array/array-string-autocomplete-chips/array-string-autocomplete-chips.component.d.ts +51 -0
  17. package/components/input/array/array-string-chips-input/array-string-chips-input.component.d.ts +44 -0
  18. package/components/input/array/array-table.class.d.ts +49 -0
  19. package/components/input/base-input.component.d.ts +31 -0
  20. package/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.d.ts +10 -0
  21. package/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.d.ts +9 -0
  22. package/components/input/boolean/boolean-toggle-input/boolean-toggle-input.component.d.ts +10 -0
  23. package/components/input/custom/custom.component.d.ts +13 -0
  24. package/components/input/date/date-input/date-input.component.d.ts +13 -0
  25. package/components/input/date/date-range-input/date-range-input.component.d.ts +20 -0
  26. package/components/input/date/date-time-input/date-time-input.component.d.ts +31 -0
  27. package/components/input/file/file-default-input/file-default-input.component.d.ts +13 -0
  28. package/components/input/file/file-image-input/file-image-input.component.d.ts +22 -0
  29. package/components/input/file/file-input/dragDrop.directive.d.ts +32 -0
  30. package/components/input/file/file-input/file-input.component.d.ts +32 -0
  31. package/components/input/input.component.d.ts +49 -73
  32. package/components/input/input.module.d.ts +38 -15
  33. package/components/input/number/number-dropdown-input/number-dropdown-input.component.d.ts +9 -0
  34. package/components/input/number/number-input/number-input.component.d.ts +9 -0
  35. package/components/input/string/string-autocomplete-input/string-autocomplete-input.component.d.ts +18 -0
  36. package/components/input/string/string-dropdown-input/string-dropdown-input.component.d.ts +9 -0
  37. package/components/input/string/string-input/string-input.component.d.ts +9 -0
  38. package/components/input/string/string-textbox-input/string-textbox-input.component.d.ts +9 -0
  39. package/components/table/create-dialog/create-dialog-data.builder.d.ts +1 -1
  40. package/components/table/create-dialog/create-entity-dialog-data.builder.d.ts +5 -5
  41. package/components/table/create-dialog/create-entity-dialog-data.d.ts +3 -3
  42. package/components/table/create-dialog/create-entity-dialog.component.d.ts +9 -5
  43. package/components/table/edit-dialog/edit-dialog-data.builder.d.ts +4 -4
  44. package/components/table/edit-dialog/edit-entity-dialog-data.d.ts +3 -3
  45. package/components/table/edit-dialog/edit-entity-dialog.builder.d.ts +5 -5
  46. package/components/table/edit-dialog/edit-entity-dialog.component.d.ts +7 -5
  47. package/components/table/table-data.builder.d.ts +9 -9
  48. package/components/table/table-data.d.ts +8 -8
  49. package/components/table/table.component.d.ts +2 -2
  50. package/decorators/array/array-decorator-internal.data.d.ts +72 -7
  51. package/decorators/array/array-decorator.data.d.ts +179 -13
  52. package/decorators/array/array.decorator.d.ts +3 -3
  53. package/decorators/base/base-property.decorator.d.ts +2 -3
  54. package/decorators/base/decorator-types.enum.d.ts +15 -4
  55. package/decorators/base/dropdown-value.interface.d.ts +14 -0
  56. package/decorators/custom/custom-decorator-internal.data.d.ts +17 -0
  57. package/decorators/custom/custom-decorator.data.d.ts +33 -0
  58. package/decorators/custom/custom.decorator.d.ts +11 -0
  59. package/decorators/date/date-decorator-internal.data.d.ts +44 -0
  60. package/decorators/date/date-decorator.data.d.ts +129 -0
  61. package/decorators/date/date.decorator.d.ts +8 -0
  62. package/decorators/file/file-decorator-internal.data.d.ts +92 -0
  63. package/decorators/file/file-decorator.data.d.ts +92 -0
  64. package/decorators/file/file.decorator.d.ts +9 -0
  65. package/decorators/number/number-decorator-internal.data.d.ts +2 -4
  66. package/decorators/number/number-decorator.data.d.ts +2 -4
  67. package/decorators/number/number.decorator.d.ts +2 -2
  68. package/decorators/object/object-decorator-internal.data.d.ts +3 -3
  69. package/decorators/object/object-decorator.data.d.ts +5 -5
  70. package/decorators/object/object.decorator.d.ts +2 -2
  71. package/decorators/string/string-decorator-internal.data.d.ts +2 -4
  72. package/decorators/string/string-decorator.data.d.ts +2 -4
  73. package/esm2020/capsulation/lodash.utilities.mjs +75 -0
  74. package/esm2020/capsulation/reflect.utilities.mjs +69 -0
  75. package/esm2020/classes/base.builder.mjs +42 -0
  76. package/esm2020/classes/date.utilities.mjs +158 -0
  77. package/esm2020/classes/entity.model.mjs +23 -0
  78. package/esm2020/classes/entity.service.mjs +180 -0
  79. package/esm2020/classes/entity.utilities.mjs +686 -0
  80. package/esm2020/classes/file.utilities.mjs +123 -0
  81. package/esm2020/components/confirm-dialog/confirm-dialog-data.builder.mjs +5 -5
  82. package/esm2020/components/confirm-dialog/confirm-dialog.component.mjs +3 -3
  83. package/esm2020/components/input/add-array-item-dialog-data.builder.mjs +4 -4
  84. package/esm2020/components/input/add-array-item-dialog-data.mjs +1 -1
  85. package/esm2020/components/input/array/array-date-input/array-date-input.component.mjs +26 -0
  86. package/esm2020/components/input/array/array-date-range-input/array-date-range-input.component.mjs +50 -0
  87. package/esm2020/components/input/array/array-date-time-input/array-date-time-input.component.mjs +50 -0
  88. package/esm2020/components/input/array/array-string-autocomplete-chips/array-string-autocomplete-chips.component.mjs +119 -0
  89. package/esm2020/components/input/array/array-string-chips-input/array-string-chips-input.component.mjs +104 -0
  90. package/esm2020/components/input/array/array-table.class.mjs +107 -0
  91. package/esm2020/components/input/base-input.component.mjs +39 -0
  92. package/esm2020/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.mjs +23 -0
  93. package/esm2020/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.mjs +17 -0
  94. package/esm2020/components/input/boolean/boolean-toggle-input/boolean-toggle-input.component.mjs +23 -0
  95. package/esm2020/components/input/custom/custom.component.mjs +25 -0
  96. package/esm2020/components/input/date/date-input/date-input.component.mjs +23 -0
  97. package/esm2020/components/input/date/date-range-input/date-range-input.component.mjs +51 -0
  98. package/esm2020/components/input/date/date-time-input/date-time-input.component.mjs +63 -0
  99. package/esm2020/components/input/file/file-default-input/file-default-input.component.mjs +24 -0
  100. package/esm2020/components/input/file/file-image-input/file-image-input.component.mjs +79 -0
  101. package/esm2020/components/input/file/file-input/dragDrop.directive.mjs +64 -0
  102. package/esm2020/components/input/file/file-input/file-input.component.mjs +152 -0
  103. package/esm2020/components/input/input.component.mjs +143 -179
  104. package/esm2020/components/input/input.module.mjs +76 -6
  105. package/esm2020/components/input/number/number-dropdown-input/number-dropdown-input.component.mjs +18 -0
  106. package/esm2020/components/input/number/number-input/number-input.component.mjs +16 -0
  107. package/esm2020/components/input/string/string-autocomplete-input/string-autocomplete-input.component.mjs +37 -0
  108. package/esm2020/components/input/string/string-dropdown-input/string-dropdown-input.component.mjs +18 -0
  109. package/esm2020/components/input/string/string-input/string-input.component.mjs +16 -0
  110. package/esm2020/components/input/string/string-textbox-input/string-textbox-input.component.mjs +17 -0
  111. package/esm2020/components/table/create-dialog/create-dialog-data.builder.mjs +3 -3
  112. package/esm2020/components/table/create-dialog/create-entity-dialog-data.builder.mjs +2 -2
  113. package/esm2020/components/table/create-dialog/create-entity-dialog-data.mjs +1 -1
  114. package/esm2020/components/table/create-dialog/create-entity-dialog.component.mjs +16 -9
  115. package/esm2020/components/table/edit-dialog/edit-dialog-data.builder.mjs +3 -3
  116. package/esm2020/components/table/edit-dialog/edit-entity-dialog-data.mjs +1 -1
  117. package/esm2020/components/table/edit-dialog/edit-entity-dialog.builder.mjs +3 -3
  118. package/esm2020/components/table/edit-dialog/edit-entity-dialog.component.mjs +19 -11
  119. package/esm2020/components/table/table-data.builder.mjs +4 -4
  120. package/esm2020/components/table/table-data.mjs +1 -1
  121. package/esm2020/components/table/table.component.mjs +21 -23
  122. package/esm2020/decorators/array/array-decorator-internal.data.mjs +102 -14
  123. package/esm2020/decorators/array/array-decorator.data.mjs +2 -2
  124. package/esm2020/decorators/array/array.decorator.mjs +8 -2
  125. package/esm2020/decorators/base/base-property.decorator.mjs +4 -3
  126. package/esm2020/decorators/base/decorator-types.enum.mjs +10 -1
  127. package/esm2020/decorators/base/dropdown-value.interface.mjs +2 -0
  128. package/esm2020/decorators/base/property-decorator-internal.data.mjs +10 -10
  129. package/esm2020/decorators/base/property-decorator.data.mjs +1 -1
  130. package/esm2020/decorators/boolean/boolean-decorator-internal.data.mjs +3 -3
  131. package/esm2020/decorators/custom/custom-decorator-internal.data.mjs +26 -0
  132. package/esm2020/decorators/custom/custom-decorator.data.mjs +2 -0
  133. package/esm2020/decorators/custom/custom.decorator.mjs +13 -0
  134. package/esm2020/decorators/date/date-decorator-internal.data.mjs +48 -0
  135. package/esm2020/decorators/date/date-decorator.data.mjs +7 -0
  136. package/esm2020/decorators/date/date.decorator.mjs +21 -0
  137. package/esm2020/decorators/file/file-decorator-internal.data.mjs +98 -0
  138. package/esm2020/decorators/file/file-decorator.data.mjs +7 -0
  139. package/esm2020/decorators/file/file.decorator.mjs +22 -0
  140. package/esm2020/decorators/number/number-decorator-internal.data.mjs +1 -1
  141. package/esm2020/decorators/number/number-decorator.data.mjs +1 -1
  142. package/esm2020/decorators/number/number.decorator.mjs +3 -3
  143. package/esm2020/decorators/object/object-decorator-internal.data.mjs +2 -2
  144. package/esm2020/decorators/object/object-decorator.data.mjs +1 -1
  145. package/esm2020/decorators/object/object.decorator.mjs +1 -1
  146. package/esm2020/decorators/string/string-decorator-internal.data.mjs +1 -1
  147. package/esm2020/decorators/string/string-decorator.data.mjs +1 -1
  148. package/esm2020/decorators/string/string.decorator.mjs +1 -1
  149. package/esm2020/mocks/placeholder-data.png.mjs +3 -0
  150. package/esm2020/public-api.mjs +15 -5
  151. package/fesm2015/ngx-material-entity.mjs +2649 -422
  152. package/fesm2015/ngx-material-entity.mjs.map +1 -1
  153. package/fesm2020/ngx-material-entity.mjs +2537 -397
  154. package/fesm2020/ngx-material-entity.mjs.map +1 -1
  155. package/mocks/placeholder-data.png.d.ts +1 -0
  156. package/package.json +7 -1
  157. package/public-api.d.ts +15 -4
  158. package/classes/entity-model.class.d.ts +0 -9
  159. package/classes/entity-service.class.d.ts +0 -66
  160. package/esm2020/classes/base-builder.class.mjs +0 -43
  161. package/esm2020/classes/entity-model.class.mjs +0 -19
  162. package/esm2020/classes/entity-service.class.mjs +0 -76
  163. package/esm2020/classes/entity-utilities.class.mjs +0 -377
@@ -1,43 +1,114 @@
1
1
  import 'reflect-metadata';
2
- import { __decorate, __metadata, __awaiter } from 'tslib';
2
+ import { __awaiter, __decorate, __metadata } from 'tslib';
3
+ import { isEqual, cloneDeep, omit, isNil, omitBy, isArray } from 'lodash';
3
4
  import { BehaviorSubject, firstValueFrom, Subject, takeUntil } from 'rxjs';
4
- import { isEqual, omit, omitBy, isNil, cloneDeep } from 'lodash';
5
5
  import * as i0 from '@angular/core';
6
- import { Component, Inject, NgModule, Input, ViewChild } from '@angular/core';
6
+ import { Component, Inject, NgModule, EventEmitter, Input, Output, Directive, HostListener, ViewChild } from '@angular/core';
7
7
  import * as i1 from '@angular/material/dialog';
8
8
  import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
9
- import * as i6 from '@angular/material/checkbox';
9
+ import * as i2 from '@angular/material/checkbox';
10
10
  import { MatCheckboxModule } from '@angular/material/checkbox';
11
11
  import * as i3 from '@angular/material/button';
12
12
  import { MatButtonModule } from '@angular/material/button';
13
- import * as i11 from '@angular/common';
13
+ import * as i4 from '@angular/common';
14
14
  import { CommonModule } from '@angular/common';
15
- import * as i13 from '@angular/forms';
15
+ import * as i3$1 from '@angular/forms';
16
16
  import { FormsModule } from '@angular/forms';
17
- import * as i9 from '@angular/material/table';
17
+ import * as i4$2 from '@angular/material/table';
18
18
  import { MatTableDataSource, MatTableModule } from '@angular/material/table';
19
19
  import { SelectionModel } from '@angular/cdk/collections';
20
- import * as i2 from '@angular/material/form-field';
20
+ import * as i1$1 from '@angular/material/form-field';
21
21
  import { MatFormFieldModule } from '@angular/material/form-field';
22
- import * as i3$1 from '@angular/material/autocomplete';
22
+ import * as i4$1 from '@angular/material/input';
23
+ import { MatInputModule } from '@angular/material/input';
24
+ import * as i3$2 from '@angular/cdk/text-field';
25
+ import * as i2$1 from '@angular/material/autocomplete';
23
26
  import { MatAutocompleteModule } from '@angular/material/autocomplete';
24
- import * as i4 from '@angular/material/core';
25
- import * as i5 from '@angular/material/select';
27
+ import * as i3$3 from '@angular/material/core';
28
+ import * as i2$2 from '@angular/material/select';
26
29
  import { MatSelectModule } from '@angular/material/select';
27
- import * as i7 from '@angular/material/slide-toggle';
30
+ import * as i2$3 from '@angular/material/slide-toggle';
28
31
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
29
- import * as i10 from '@angular/material/chips';
32
+ import * as i2$4 from '@angular/material/datepicker';
33
+ import { MatDatepickerModule } from '@angular/material/datepicker';
34
+ import * as i2$5 from '@angular/material/chips';
30
35
  import { MatChipsModule } from '@angular/material/chips';
31
- import * as i12 from '@angular/material/input';
32
- import { MatInputModule } from '@angular/material/input';
33
- import * as i14 from '@angular/cdk/text-field';
34
36
  import { MatIconModule } from '@angular/material/icon';
35
- import * as i7$1 from '@angular/material/paginator';
37
+ import * as i7 from '@angular/material/paginator';
36
38
  import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
37
39
  import { MatSort } from '@angular/material/sort';
38
- import * as i4$1 from '@angular/material/menu';
40
+ import * as i4$3 from '@angular/material/menu';
39
41
  import { MatMenuModule } from '@angular/material/menu';
40
42
 
43
+ /**
44
+ * Encapsulates all functionality of Reflect.
45
+ */
46
+ class ReflectUtilities {
47
+ /**
48
+ * Gets the metadata value for the provided metadata key on the target object or its prototype chain.
49
+ *
50
+ * @param metadataKey - A key used to store and retrieve metadata.
51
+ * @param target - The target object on which the metadata is defined.
52
+ * @param propertyKey - The property key for the target.
53
+ * @returns The metadata value for the metadata key if found; otherwise, undefined.
54
+ */
55
+ static getMetadata(metadataKey, target, propertyKey) {
56
+ return Reflect.getMetadata(metadataKey, target, propertyKey);
57
+ }
58
+ /**
59
+ * Returns the string and symbol keys of the own properties of an object. The own properties of an object
60
+ * are those that are defined directly on that object, and are not inherited from the object's prototype.
61
+ *
62
+ * @param target - Object that contains the own properties.
63
+ * @returns The keys of the given object.
64
+ */
65
+ static ownKeys(target) {
66
+ return Reflect.ownKeys(target);
67
+ }
68
+ /**
69
+ * Gets the property of target, equivalent to `target[propertyKey]`.
70
+ *
71
+ * @param target - Object that contains the property on itself or in its prototype chain.
72
+ * @param propertyKey - The property name.
73
+ * @returns The property of the target of the given key.
74
+ */
75
+ static get(target, propertyKey) {
76
+ return Reflect.get(target, propertyKey);
77
+ }
78
+ /**
79
+ * Sets the property of target, equivalent to `target[propertyKey] = value`.
80
+ *
81
+ * @param target - Object that contains the property on itself or in its prototype chain.
82
+ * @param propertyKey - The property name.
83
+ * @param value - The value to set the property to.
84
+ * @returns If setting the value was successful.
85
+ */
86
+ static set(target, propertyKey, value) {
87
+ return Reflect.set(target, propertyKey, value);
88
+ }
89
+ /**
90
+ * Equivalent to `propertyKey in target`.
91
+ *
92
+ * @param target - Object that contains the property on itself or in its prototype chain.
93
+ * @param propertyKey - Name of the property.
94
+ * @returns Whether or not the given target has the key.
95
+ */
96
+ static has(target, propertyKey) {
97
+ return Reflect.has(target, propertyKey);
98
+ }
99
+ /**
100
+ * Define a unique metadata entry on the target.
101
+ *
102
+ * @param metadataKey - A key used to store and retrieve metadata.
103
+ * @param metadataValue - A value that contains attached metadata.
104
+ * @param target - The target object on which to define metadata.
105
+ * @param propertyKey - The property key for the target.
106
+ */
107
+ static defineMetadata(metadataKey, metadataValue, target, propertyKey) {
108
+ Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey);
109
+ }
110
+ }
111
+
41
112
  /**
42
113
  * The base decorator for setting metadata on properties.
43
114
  *
@@ -47,8 +118,8 @@ import { MatMenuModule } from '@angular/material/menu';
47
118
  */
48
119
  function baseProperty(metadata, type) {
49
120
  return function (target, propertyKey) {
50
- Reflect.defineMetadata('metadata', metadata, target, propertyKey);
51
- Reflect.defineMetadata('type', type, target, propertyKey);
121
+ ReflectUtilities.defineMetadata('metadata', metadata, target, propertyKey);
122
+ ReflectUtilities.defineMetadata('type', type, target, propertyKey);
52
123
  };
53
124
  }
54
125
 
@@ -68,8 +139,17 @@ var DecoratorTypes;
68
139
  DecoratorTypes["BOOLEAN_DROPDOWN"] = "booleanDropdown";
69
140
  DecoratorTypes["OBJECT"] = "object";
70
141
  DecoratorTypes["ARRAY"] = "array";
142
+ DecoratorTypes["ARRAY_DATE"] = "arrayDate";
143
+ DecoratorTypes["ARRAY_DATE_TIME"] = "arrayDateTime";
144
+ DecoratorTypes["ARRAY_DATE_RANGE"] = "arrayDateRange";
71
145
  DecoratorTypes["ARRAY_STRING_CHIPS"] = "arrayStringChips";
72
146
  DecoratorTypes["ARRAY_STRING_AUTOCOMPLETE_CHIPS"] = "arrayStringAutocompleteChips";
147
+ DecoratorTypes["DATE"] = "date";
148
+ DecoratorTypes["DATE_RANGE"] = "dateRange";
149
+ DecoratorTypes["DATE_TIME"] = "dateTime";
150
+ DecoratorTypes["FILE_DEFAULT"] = "fileDefault";
151
+ DecoratorTypes["FILE_IMAGE"] = "fileImage";
152
+ DecoratorTypes["CUSTOM"] = "custom";
73
153
  })(DecoratorTypes || (DecoratorTypes = {}));
74
154
 
75
155
  /**
@@ -77,12 +157,13 @@ var DecoratorTypes;
77
157
  */
78
158
  class PositionInternal {
79
159
  constructor(data) {
160
+ var _a, _b;
80
161
  this.validateInput(data);
81
- this.row = (data === null || data === void 0 ? void 0 : data.row) ? data.row : -1;
82
- this.order = (data === null || data === void 0 ? void 0 : data.order) ? data.order : -1;
162
+ this.row = (_a = data === null || data === void 0 ? void 0 : data.row) !== null && _a !== void 0 ? _a : -1;
163
+ this.order = (_b = data === null || data === void 0 ? void 0 : data.order) !== null && _b !== void 0 ? _b : -1;
83
164
  }
84
165
  validateInput(data) {
85
- if (data === null || data === void 0 ? void 0 : data.order) {
166
+ if ((data === null || data === void 0 ? void 0 : data.order) != null) {
86
167
  if (data.order < 1) {
87
168
  throw new Error('order must be at least 1');
88
169
  }
@@ -90,7 +171,7 @@ class PositionInternal {
90
171
  throw new Error('order cannot be bigger than 12 (the minimum value for a bootstrap column)');
91
172
  }
92
173
  }
93
- if ((data === null || data === void 0 ? void 0 : data.row) && (data.row < 1)) {
174
+ if ((data === null || data === void 0 ? void 0 : data.row) != null && data.row < 1) {
94
175
  throw new Error('row must be at least 1');
95
176
  }
96
177
  }
@@ -100,12 +181,13 @@ class PositionInternal {
100
181
  */
101
182
  class PropertyDecoratorConfigInternal {
102
183
  constructor(data) {
103
- this.display = data.display != undefined ? data.display : true;
184
+ var _a, _b, _c, _d, _e;
185
+ this.display = (_a = data.display) !== null && _a !== void 0 ? _a : true;
104
186
  this.displayName = data.displayName;
105
- this.required = data.required != undefined ? data.required : true;
106
- this.omitForCreate = data.omitForCreate != undefined ? data.omitForCreate : false;
107
- this.omitForUpdate = data.omitForUpdate != undefined ? data.omitForUpdate : false;
108
- this.defaultWidths = data.defaultWidths ? data.defaultWidths : [6, 6, 12];
187
+ this.required = (_b = data.required) !== null && _b !== void 0 ? _b : true;
188
+ this.omitForCreate = (_c = data.omitForCreate) !== null && _c !== void 0 ? _c : false;
189
+ this.omitForUpdate = (_d = data.omitForUpdate) !== null && _d !== void 0 ? _d : false;
190
+ this.defaultWidths = (_e = data.defaultWidths) !== null && _e !== void 0 ? _e : [6, 6, 12];
109
191
  this.position = new PositionInternal(data.position);
110
192
  }
111
193
  }
@@ -179,23 +261,365 @@ function string(metadata) {
179
261
  }
180
262
 
181
263
  /**
182
- * The base Entity class.
264
+ * Encapsulates all functionality of lodash.
183
265
  */
184
- class Entity {
266
+ class LodashUtilities {
267
+ /**
268
+ * Performs a deep comparison between two values to determine if they are
269
+ * equivalent.
270
+ *
271
+ * **Note:** This method supports comparing arrays, array buffers, booleans,
272
+ * date objects, error objects, maps, numbers, `Object` objects, regexps,
273
+ * sets, strings, symbols, and typed arrays. `Object` objects are compared
274
+ * by their own, not inherited, enumerable properties. Functions and DOM
275
+ * nodes are **not** supported.
276
+ *
277
+ * @param value - The value to compare.
278
+ * @param other - The other value to compare.
279
+ * @returns Returns `true` if the values are equivalent, else `false`.
280
+ */
281
+ static isEqual(value, other) {
282
+ return isEqual(value, other);
283
+ }
284
+ /**
285
+ * This method is like _.clone except that it recursively clones value.
286
+ *
287
+ * @param value - The value to recursively clone.
288
+ * @returns Returns the deep cloned value.
289
+ */
290
+ static cloneDeep(value) {
291
+ return cloneDeep(value);
292
+ }
293
+ /**
294
+ * The opposite of `_.pick`; this method creates an object composed of the
295
+ * own and inherited enumerable properties of `object` that are not omitted.
296
+ *
297
+ * @param object - The source object.
298
+ * @param paths - The property names to omit, specified
299
+ * individually or in arrays.
300
+ * @returns Returns the new object.
301
+ */
302
+ static omit(object, ...paths) {
303
+ return omit(object, ...paths);
304
+ }
305
+ /**
306
+ * Checks if `value` is `null` or `undefined`.
307
+ *
308
+ * @param value - The value to check.
309
+ * @returns Returns `true` if `value` is nullish, else `false`.
310
+ */
311
+ static isNil(value) {
312
+ return isNil(value);
313
+ }
314
+ /**
315
+ * The opposite of `_.pickBy`; this method creates an object composed of the
316
+ * own and inherited enumerable properties of `object` that `predicate`
317
+ * doesn't return truthy for.
318
+ *
319
+ * @param object - The source object.
320
+ * @param predicate - The function invoked per property.
321
+ * @returns Returns the new object.
322
+ */
323
+ static omitBy(object, predicate) {
324
+ return omitBy(object, predicate);
325
+ }
326
+ /**
327
+ * Checks if value is classified as an Array object.
328
+ *
329
+ * @param value - The value to check.
330
+ * @returns Returns true if value is correctly classified, else false.
331
+ */
332
+ static isArray(value) {
333
+ return isArray(value);
334
+ }
335
+ }
336
+
337
+ const DAY_IN_MS = 1000 * 60 * 60 * 24;
338
+ /**
339
+ * Contains Helper Functions for handling date properties.
340
+ */
341
+ class DateUtilities {
342
+ /**
343
+ * Gets the given value as a date value.
344
+ *
345
+ * @param value - The value to get as a date.
346
+ * @returns The given value as a date.
347
+ */
348
+ static asDate(value) {
349
+ return value;
350
+ }
351
+ /**
352
+ * Gets the default times used by the DateTime picker when nothing is specified by the user.
353
+ *
354
+ * @param format - The time format. Defaults to 24.
355
+ * @param minuteSteps - The steps from one time value to the next. Defaults to 30.
356
+ * @returns Times in the 24 hour format from 0:00 until 23:30 in 30 minute steps.
357
+ */
358
+ static getDefaultTimes(format = 24, minuteSteps = 30) {
359
+ const res = [{ displayName: '-', value: undefined }];
360
+ for (let hour = 0; hour < 24; hour++) {
361
+ for (let minute = 0; minute < 60; minute += minuteSteps) {
362
+ res.push(DateUtilities.getTimeDropdownValue(format, hour, minute));
363
+ }
364
+ }
365
+ return res;
366
+ }
367
+ static getTimeDropdownValue(format, hour, minute) {
368
+ const displayHour = DateUtilities.getFormattedHour(format, LodashUtilities.cloneDeep(hour));
369
+ const displayMinute = DateUtilities.getFormattedMinute(format, hour, minute);
370
+ return {
371
+ displayName: `${displayHour}:${displayMinute}`,
372
+ value: {
373
+ hours: hour,
374
+ minutes: minute
375
+ }
376
+ };
377
+ }
378
+ static getFormattedHour(format, hour) {
379
+ if (format === 12 && hour > 12) {
380
+ hour -= 12;
381
+ }
382
+ return hour;
383
+ }
384
+ static getFormattedMinute(format, hour, minute) {
385
+ let res = `${minute}`;
386
+ if (format === 12) {
387
+ if (hour > 12) {
388
+ res = `${minute} PM`;
389
+ }
390
+ else {
391
+ res = `${minute} AM`;
392
+ }
393
+ }
394
+ if (minute.toString().length === 1) {
395
+ res = '0'.concat(res);
396
+ }
397
+ return res;
398
+ }
399
+ /**
400
+ * Gets the Time object from the given date.
401
+ *
402
+ * @param value - The date to get the time object from.
403
+ * @returns The Time object build from the date value.
404
+ */
405
+ static getTimeFromDate(value) {
406
+ if (!value) {
407
+ return undefined;
408
+ }
409
+ else {
410
+ return {
411
+ hours: new Date(value).getHours(),
412
+ minutes: new Date(value).getMinutes()
413
+ };
414
+ }
415
+ }
416
+ /**
417
+ * Gets the dates between the two given gates. Does additional filtering based on the provided DateRange metadata.
418
+ *
419
+ * @param startDate - The start date.
420
+ * @param endDate - The end date.
421
+ * @param filter - The custom filter from the metadata.
422
+ * @returns All dates between the two provided dates. Includes start and end date.
423
+ */
424
+ static getDatesBetween(startDate, endDate, filter) {
425
+ const res = [];
426
+ while (startDate.getFullYear() < endDate.getFullYear()
427
+ || startDate.getMonth() < endDate.getMonth()
428
+ || startDate.getDate() <= endDate.getDate()) {
429
+ res.push(new Date(startDate));
430
+ startDate.setTime(startDate.getTime() + DAY_IN_MS);
431
+ }
432
+ if (filter) {
433
+ return res.filter(d => filter(d));
434
+ }
435
+ else {
436
+ return res;
437
+ }
438
+ }
439
+ /**
440
+ * Get all valid times for the dropdown of a datetime property.
441
+ *
442
+ * @param date - The date of the datetime.
443
+ * @param times - All given times to filter.
444
+ * @param min - The function that defines the minimum time.
445
+ * @param max - The function that defines the maximum time.
446
+ * @param filter - A filter function to do more specific time filtering. This could be e.g. The removal of lunch breaks.
447
+ * @returns All valid dropdown values for the datetime property.
448
+ */
449
+ static getValidTimesForDropdown(date, times, min, max, filter) {
450
+ if (min) {
451
+ const minTime = min(date);
452
+ times = times.filter(t => !t.value
453
+ || t.value.hours > minTime.hours
454
+ || (t.value.hours === minTime.hours
455
+ && t.value.minutes >= minTime.minutes));
456
+ }
457
+ if (max) {
458
+ const maxTime = max(date);
459
+ times = times.filter(t => !t.value
460
+ || t.value.hours < maxTime.hours
461
+ || (t.value.hours === maxTime.hours
462
+ && t.value.minutes <= maxTime.minutes));
463
+ }
464
+ if (filter) {
465
+ times = times.filter(t => !t.value || filter(t.value));
466
+ }
467
+ return times;
468
+ }
469
+ /**
470
+ * Checks if the time object has processable hours and minutes properties.
471
+ * Doesn't check custom validators like min/max from the metadata configuration.
472
+ *
473
+ * @param time - The time to check.
474
+ * @returns Whether or not the time object is unprocessable.
475
+ */
476
+ static timeIsUnprocessable(time) {
477
+ if (!time
478
+ || time.hours == null
479
+ || typeof time.hours !== 'number'
480
+ || Number.isNaN(time.hours)
481
+ || time.minutes == null
482
+ || typeof time.minutes !== 'number'
483
+ || Number.isNaN(time.minutes)) {
484
+ return true;
485
+ }
486
+ return false;
487
+ }
488
+ }
489
+ /**
490
+ * The default filter function to user when none was provided by the user.
491
+ */
492
+ DateUtilities.defaultDateFilter = () => true;
493
+
494
+ /**
495
+ * Provides functionality regarding files.
496
+ */
497
+ class FileUtilities {
498
+ /**
499
+ * Gets the accept value for the html input.
500
+ *
501
+ * @param mimeTypes - The mimeTypes to get the accept string from.
502
+ * @returns A comma separated string of all the provided mime types.
503
+ */
504
+ static getAcceptString(mimeTypes) {
505
+ if (!(mimeTypes === null || mimeTypes === void 0 ? void 0 : mimeTypes.length)) {
506
+ return '*';
507
+ }
508
+ return mimeTypes.join(', ');
509
+ }
510
+ // TODO: Find a way to use blobs with jest
511
+ /* istanbul ignore next */
512
+ /**
513
+ * Reads a url to display the given file.
514
+ *
515
+ * @param file - The file to get the url from.
516
+ * @returns A promise of the url. Undefined if no file was provided.
517
+ */
518
+ static getDataURLFromFile(file) {
519
+ return __awaiter(this, void 0, void 0, function* () {
520
+ if (!file) {
521
+ return undefined;
522
+ }
523
+ return new Promise((resolve, reject) => {
524
+ const reader = new FileReader();
525
+ reader.onload = e => { var _a; return resolve((_a = e.target) === null || _a === void 0 ? void 0 : _a.result); };
526
+ reader.onerror = e => reject(e);
527
+ reader.readAsDataURL(file);
528
+ });
529
+ });
530
+ }
531
+ // TODO: Find a way to use blobs with jest
532
+ /* istanbul ignore next */
533
+ /**
534
+ * Gets a file from the given url.
535
+ *
536
+ * @param url - The url to get the file from.
537
+ * @returns A promise of the File.
538
+ */
539
+ static getFileFromUrl(url) {
540
+ return __awaiter(this, void 0, void 0, function* () {
541
+ const res = yield fetch(url);
542
+ if (!res.ok) {
543
+ // TODO make error more robust
544
+ throw new Error(`Error fetching the file from the url ${url}`);
545
+ }
546
+ return yield res.blob();
547
+ });
548
+ }
549
+ // TODO: Find a way to use blobs with jest
550
+ /* istanbul ignore next */
551
+ /**
552
+ * Gets the file data with the blob from the given File Data.
553
+ *
554
+ * @param data - The File Data to get the file data with blob from.
555
+ * @returns FileDataWithFile.
556
+ */
557
+ static getFileData(data) {
558
+ return __awaiter(this, void 0, void 0, function* () {
559
+ if (data.file) {
560
+ return {
561
+ file: data.file,
562
+ name: data.name,
563
+ url: data.url,
564
+ type: data.type,
565
+ size: data.size
566
+ };
567
+ }
568
+ else {
569
+ return {
570
+ file: yield FileUtilities.getFileFromUrl(data.url),
571
+ name: data.name,
572
+ url: data.url,
573
+ type: data.type,
574
+ size: data.size
575
+ };
576
+ }
577
+ });
578
+ }
579
+ /**
580
+ * Checks if the given file has a valid mime type.
581
+ *
582
+ * @param type - The type of the file to check.
583
+ * @param allowedMimeTypes - The allowed mime types.
584
+ * @returns Whether or not the given file has a valid mime type.
585
+ */
586
+ static isMimeTypeValid(type, allowedMimeTypes) {
587
+ if (allowedMimeTypes.includes('*')) {
588
+ return true;
589
+ }
590
+ for (const t of allowedMimeTypes) {
591
+ if (t === type) {
592
+ return true;
593
+ }
594
+ if (t.endsWith('*') && type.startsWith(t.split('*')[0])) {
595
+ return true;
596
+ }
597
+ }
598
+ return false;
599
+ }
600
+ /**
601
+ * Transform the given value to Megabytes.
602
+ *
603
+ * @param value - The original value.
604
+ * @param unit - If the value is B, KB or GB.
605
+ * @returns The given value as bytes.
606
+ */
607
+ static transformToMegaBytes(value, unit) {
608
+ const bytes = this.transformToBytes(value, unit);
609
+ return bytes / 1000000;
610
+ }
611
+ static transformToBytes(value, unit) {
612
+ switch (unit) {
613
+ case 'B':
614
+ return value;
615
+ case 'KB':
616
+ return value * 1000;
617
+ case 'GB':
618
+ return value * 1000000000;
619
+ }
620
+ }
185
621
  }
186
- __decorate([
187
- string({
188
- omitForCreate: true,
189
- omitForUpdate: true,
190
- display: false,
191
- displayStyle: 'line',
192
- displayName: 'ID',
193
- required: true
194
- }),
195
- __metadata("design:type", String)
196
- ], Entity.prototype, "id", void 0);
197
622
 
198
- var _a;
199
623
  /**
200
624
  * Contains HelperMethods around handling Entities and their property-metadata.
201
625
  */
@@ -232,6 +656,26 @@ class EntityUtilities {
232
656
  }
233
657
  return res;
234
658
  }
659
+ /**
660
+ * Gets all properties on the given entity which are files.
661
+ *
662
+ * @param entity - The entity to check for file properties.
663
+ * @param omit - Whether to leave out values that are omitted for create or delete.
664
+ * @returns The keys of all file properties on the given entity.
665
+ */
666
+ static getFileProperties(entity, omit) {
667
+ const res = [];
668
+ for (const key of EntityUtilities.keysOf(entity)) {
669
+ const type = EntityUtilities.getPropertyType(entity, key);
670
+ if (type === DecoratorTypes.FILE_DEFAULT || type === DecoratorTypes.FILE_IMAGE) {
671
+ const metadata = EntityUtilities.getPropertyMetadata(entity, key);
672
+ if (!(metadata.omitForCreate && omit === 'create') && !(metadata.omitForUpdate && omit === 'update')) {
673
+ res.push(key);
674
+ }
675
+ }
676
+ }
677
+ return res;
678
+ }
235
679
  /**
236
680
  * Gets the metadata included in an property.
237
681
  *
@@ -244,16 +688,11 @@ class EntityUtilities {
244
688
  static getPropertyMetadata(entity, propertyKey,
245
689
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
246
690
  type) {
247
- try {
248
- const metadata = Reflect.getMetadata('metadata', entity, propertyKey);
249
- if (!metadata) {
250
- throw new Error(`Could not find metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
251
- }
252
- return metadata;
253
- }
254
- catch (error) {
691
+ const metadata = ReflectUtilities.getMetadata('metadata', entity, propertyKey);
692
+ if (metadata == null) {
255
693
  throw new Error(`Could not find metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
256
694
  }
695
+ return metadata;
257
696
  }
258
697
  /**
259
698
  * Gets the type of the property-metadata.
@@ -265,8 +704,8 @@ class EntityUtilities {
265
704
  */
266
705
  static getPropertyType(entity, propertyKey) {
267
706
  try {
268
- const propertyType = Reflect.getMetadata('type', entity, propertyKey);
269
- if (!propertyType) {
707
+ const propertyType = ReflectUtilities.getMetadata('type', entity, propertyKey);
708
+ if (propertyType == null) {
270
709
  throw new Error(`Could not find type metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
271
710
  }
272
711
  return propertyType;
@@ -287,13 +726,11 @@ class EntityUtilities {
287
726
  static new(target, entity) {
288
727
  for (const key in target) {
289
728
  const type = EntityUtilities.getPropertyType(target, key);
290
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
291
- let value = entity ? Reflect.get(entity, key) : undefined;
729
+ let value = entity ? ReflectUtilities.get(entity, key) : undefined;
292
730
  switch (type) {
293
731
  case DecoratorTypes.OBJECT:
294
732
  const objectMetadata = EntityUtilities.getPropertyMetadata(target, key, DecoratorTypes.OBJECT);
295
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
296
- value = new objectMetadata.type(value);
733
+ value = new objectMetadata.EntityClass(value);
297
734
  break;
298
735
  case DecoratorTypes.ARRAY:
299
736
  const inputArray = value;
@@ -310,7 +747,7 @@ class EntityUtilities {
310
747
  default:
311
748
  break;
312
749
  }
313
- Reflect.set(target, key, value);
750
+ ReflectUtilities.set(target, key, value);
314
751
  }
315
752
  }
316
753
  /**
@@ -323,7 +760,7 @@ class EntityUtilities {
323
760
  */
324
761
  static isEntityValid(entity, omit) {
325
762
  for (const key in entity) {
326
- if (!this.isPropertyValid(entity, key, omit)) {
763
+ if (!EntityUtilities.isPropertyValid(entity, key, omit)) {
327
764
  return false;
328
765
  }
329
766
  }
@@ -339,76 +776,107 @@ class EntityUtilities {
339
776
  * @throws Throws when it extracts an unknown metadata type.
340
777
  */
341
778
  static isPropertyValid(entity, key, omit) {
342
- const type = this.getPropertyType(entity, key);
343
- const metadata = this.getPropertyMetadata(entity, key, type);
344
- const metadataDefaultString = metadata;
345
- const metadataTextboxString = metadata;
346
- const metadataDefaultNumber = metadata;
347
- const objectProperty = entity[key];
348
- const metadataEntityArray = metadata;
349
- const arrayItems = entity[key];
779
+ const type = EntityUtilities.getPropertyType(entity, key);
780
+ const metadata = EntityUtilities.getPropertyMetadata(entity, key, type);
350
781
  if (metadata.omitForCreate && omit === 'create') {
351
782
  return true;
352
783
  }
353
784
  if (metadata.omitForUpdate && omit === 'update') {
354
785
  return true;
355
786
  }
356
- if (metadata.required && !entity[key]) {
787
+ if (metadata.required && entity[key] == null) {
357
788
  return false;
358
789
  }
359
790
  switch (type) {
360
791
  case DecoratorTypes.BOOLEAN_DROPDOWN:
792
+ break;
361
793
  case DecoratorTypes.BOOLEAN_CHECKBOX:
362
794
  case DecoratorTypes.BOOLEAN_TOGGLE:
363
- return true;
795
+ const entityBoolean = entity[key];
796
+ const booleanMetadata = metadata;
797
+ if (!EntityUtilities.isBooleanValid(entityBoolean, booleanMetadata)) {
798
+ return false;
799
+ }
800
+ break;
364
801
  case DecoratorTypes.STRING_DROPDOWN:
365
- return true;
802
+ break;
366
803
  case DecoratorTypes.STRING:
367
804
  case DecoratorTypes.STRING_AUTOCOMPLETE:
368
- if (metadataDefaultString.maxLength
369
- && entity[key].length > metadataDefaultString.maxLength) {
370
- return false;
371
- }
372
- if (metadataDefaultString.minLength
373
- && entity[key].length < metadataDefaultString.minLength) {
374
- return false;
375
- }
376
- if (metadataDefaultString.regex
377
- && !entity[key].match(metadataDefaultString.regex)) {
805
+ const entityString = entity[key];
806
+ const stringMetadata = metadata;
807
+ if (!EntityUtilities.isStringValid(entityString, stringMetadata)) {
378
808
  return false;
379
809
  }
380
810
  break;
381
811
  case DecoratorTypes.STRING_TEXTBOX:
382
- if (metadataTextboxString.maxLength
383
- && entity[key].length > metadataTextboxString.maxLength) {
384
- return false;
385
- }
386
- if (metadataTextboxString.minLength
387
- && entity[key].length < metadataTextboxString.minLength) {
812
+ const entityTextbox = entity[key];
813
+ const textboxMetadata = metadata;
814
+ if (!EntityUtilities.isTextboxValid(entityTextbox, textboxMetadata)) {
388
815
  return false;
389
816
  }
390
817
  break;
391
818
  case DecoratorTypes.NUMBER_DROPDOWN:
392
819
  return true;
393
820
  case DecoratorTypes.NUMBER:
394
- if (metadataDefaultNumber.max && entity[key] > metadataDefaultNumber.max) {
395
- return false;
396
- }
397
- if (metadataDefaultNumber.min && entity[key] < metadataDefaultNumber.min) {
821
+ const entityNumber = entity[key];
822
+ const numberMetadata = metadata;
823
+ if (!EntityUtilities.isNumberValid(entityNumber, numberMetadata)) {
398
824
  return false;
399
825
  }
400
826
  break;
401
827
  case DecoratorTypes.OBJECT:
402
- for (const parameterKey in objectProperty) {
403
- if (!this.isPropertyValid(objectProperty, parameterKey, omit)) {
828
+ const entityObject = entity[key];
829
+ for (const parameterKey in entityObject) {
830
+ if (!EntityUtilities.isPropertyValid(entityObject, parameterKey, omit)) {
404
831
  return false;
405
832
  }
406
833
  }
407
834
  break;
408
835
  case DecoratorTypes.ARRAY_STRING_CHIPS:
409
836
  case DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS:
837
+ case DecoratorTypes.ARRAY_DATE:
838
+ case DecoratorTypes.ARRAY_DATE_TIME:
839
+ case DecoratorTypes.ARRAY_DATE_RANGE:
410
840
  case DecoratorTypes.ARRAY:
411
- if (metadataEntityArray.required && !arrayItems.length) {
841
+ const entityArray = entity[key];
842
+ const arrayMetadata = metadata;
843
+ if (arrayMetadata.required && !entityArray.length) {
844
+ return false;
845
+ }
846
+ break;
847
+ case DecoratorTypes.DATE:
848
+ const entityDate = new Date(entity[key]);
849
+ const dateMetadata = metadata;
850
+ if (!EntityUtilities.isDateValid(entityDate, dateMetadata)) {
851
+ return false;
852
+ }
853
+ break;
854
+ case DecoratorTypes.DATE_RANGE:
855
+ const entityDateRange = LodashUtilities.cloneDeep(entity[key]);
856
+ const dateRangeMetadata = metadata;
857
+ if (!EntityUtilities.isDateRangeValid(entityDateRange, dateRangeMetadata)) {
858
+ return false;
859
+ }
860
+ break;
861
+ case DecoratorTypes.DATE_TIME:
862
+ const entityDateTime = new Date(entity[key]);
863
+ const dateTimeMetadata = metadata;
864
+ if (!EntityUtilities.isDateTimeValid(entityDateTime, dateTimeMetadata)) {
865
+ return false;
866
+ }
867
+ break;
868
+ case DecoratorTypes.FILE_DEFAULT:
869
+ case DecoratorTypes.FILE_IMAGE:
870
+ const entityFile = entity[key];
871
+ const entityFileMetadata = metadata;
872
+ if (!EntityUtilities.isFileDataValid(entityFile, entityFileMetadata)) {
873
+ return false;
874
+ }
875
+ break;
876
+ case DecoratorTypes.CUSTOM:
877
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
878
+ const customMetadata = metadata;
879
+ if (!customMetadata.isValid(entity[key], omit)) {
412
880
  return false;
413
881
  }
414
882
  break;
@@ -417,51 +885,326 @@ class EntityUtilities {
417
885
  }
418
886
  return true;
419
887
  }
420
- /**
421
- * Checks if an entity is "dirty" (if its values have changed).
422
- *
423
- * @param entity - The entity after all changes.
424
- * @param entityPriorChanges - The entity before the changes.
425
- * @returns Whether or not the entity is dirty.
426
- */
427
- static dirty(entity, entityPriorChanges) {
428
- if (!entityPriorChanges) {
888
+ static isBooleanValid(value, metadata) {
889
+ if (metadata.required && !value) {
429
890
  return false;
430
891
  }
431
- else {
432
- const diff = this.difference(entity, entityPriorChanges);
433
- if (JSON.stringify(diff) === '{}') {
434
- return false;
435
- }
436
- else {
437
- return true;
438
- }
439
- }
892
+ return true;
440
893
  }
441
- /**
442
- * Compares two Entities and returns their difference in an object.
443
- *
444
- * @param entity - The first entity to compare.
445
- * @param entityPriorChanges - The second entity to compare.
446
- * @returns The difference between the two Entities in form of a Partial.
447
- */
448
- static difference(entity, entityPriorChanges) {
449
- const res = {};
450
- for (const key in entity) {
451
- if (!isEqual(entity[key], entityPriorChanges[key])) {
452
- res[key] = entity[key];
453
- }
894
+ static isStringValid(value, metadata) {
895
+ if (metadata.maxLength && value.length > metadata.maxLength) {
896
+ return false;
454
897
  }
455
- return res;
456
- }
457
- //TODO X Y
458
- /**
459
- * Compare function for sorting entity keys by their order value.
460
- *
898
+ if (metadata.minLength && value.length < metadata.minLength) {
899
+ return false;
900
+ }
901
+ if (metadata.regex && !value.match(metadata.regex)) {
902
+ return false;
903
+ }
904
+ return true;
905
+ }
906
+ static isTextboxValid(value, metadata) {
907
+ if (metadata.maxLength && value.length > metadata.maxLength) {
908
+ return false;
909
+ }
910
+ if (metadata.minLength && value.length < metadata.minLength) {
911
+ return false;
912
+ }
913
+ return true;
914
+ }
915
+ static isNumberValid(value, metadata) {
916
+ if (metadata.max && value > metadata.max) {
917
+ return false;
918
+ }
919
+ if (metadata.min && value < metadata.min) {
920
+ return false;
921
+ }
922
+ return true;
923
+ }
924
+ static isDateValid(value, metadata) {
925
+ if (metadata.min && value.getTime() < metadata.min(value).getTime()) {
926
+ return false;
927
+ }
928
+ if (metadata.max && value.getTime() > metadata.max(value).getTime()) {
929
+ return false;
930
+ }
931
+ if (metadata.filter && !metadata.filter(value)) {
932
+ return false;
933
+ }
934
+ return true;
935
+ }
936
+ static isDateRangeValid(value, metadata) {
937
+ if (metadata.required) {
938
+ if (!value.start) {
939
+ return false;
940
+ }
941
+ if (!value.end) {
942
+ return false;
943
+ }
944
+ }
945
+ value.start = new Date(value.start);
946
+ value.end = new Date(value.end);
947
+ if (metadata.minStart && value.start.getTime() < metadata.minStart(value.start).getTime()) {
948
+ return false;
949
+ }
950
+ if (metadata.maxStart && value.start.getTime() > metadata.maxStart(value.start).getTime()) {
951
+ return false;
952
+ }
953
+ if (metadata.minEnd && value.end.getTime() < metadata.minEnd(value.end).getTime()) {
954
+ return false;
955
+ }
956
+ if (metadata.maxEnd && value.end.getTime() > metadata.maxEnd(value.end).getTime()) {
957
+ return false;
958
+ }
959
+ if (metadata.filter) {
960
+ if (!metadata.filter(value.start)) {
961
+ return false;
962
+ }
963
+ if (!metadata.filter(value.end)) {
964
+ return false;
965
+ }
966
+ if (value.values) {
967
+ for (const date of value.values) {
968
+ if (!metadata.filter(date)) {
969
+ return false;
970
+ }
971
+ }
972
+ }
973
+ }
974
+ return true;
975
+ }
976
+ static isDateTimeValid(value, metadata) {
977
+ if (metadata.minDate && value.getTime() < metadata.minDate(value).getTime()) {
978
+ return false;
979
+ }
980
+ if (metadata.maxDate && value.getTime() > metadata.maxDate(value).getTime()) {
981
+ return false;
982
+ }
983
+ if (metadata.filterDate && !metadata.filterDate(value)) {
984
+ return false;
985
+ }
986
+ const time = {
987
+ hours: value.getHours(),
988
+ minutes: value.getMinutes()
989
+ };
990
+ if (metadata.minTime) {
991
+ const minTime = metadata.minTime(value);
992
+ if (!(time.hours > minTime.hours
993
+ || (time.hours === minTime.hours
994
+ && time.minutes >= minTime.minutes))) {
995
+ return false;
996
+ }
997
+ }
998
+ if (metadata.maxTime) {
999
+ const maxTime = metadata.maxTime(value);
1000
+ if (!(time.hours < maxTime.hours
1001
+ || (time.hours === maxTime.hours
1002
+ && time.minutes <= maxTime.minutes))) {
1003
+ return false;
1004
+ }
1005
+ }
1006
+ if (metadata.filterTime) {
1007
+ if (!metadata.filterTime(time)) {
1008
+ return false;
1009
+ }
1010
+ }
1011
+ return true;
1012
+ }
1013
+ static isFileDataValid(value, metadata) {
1014
+ const files = metadata.multiple ? value : [value];
1015
+ const maxSize = metadata.maxSize * 1000000;
1016
+ const maxSizeTotal = metadata.maxSizeTotal * 1000000;
1017
+ let fileSizeTotal = 0;
1018
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
1019
+ for (let i = 0; i < files.length; i++) {
1020
+ if (!files[i].name || !files[i].file && !files[i].url) {
1021
+ return false;
1022
+ }
1023
+ if (!FileUtilities.isMimeTypeValid(files[i].type, metadata.allowedMimeTypes)) {
1024
+ return false;
1025
+ }
1026
+ if (files[i].size > maxSize) {
1027
+ return false;
1028
+ }
1029
+ fileSizeTotal += files[i].size;
1030
+ if (fileSizeTotal > maxSizeTotal) {
1031
+ return false;
1032
+ }
1033
+ }
1034
+ return true;
1035
+ }
1036
+ /**
1037
+ * Checks if an entity is "dirty" (if its values have changed).
1038
+ *
1039
+ * @param entity - The entity after all changes.
1040
+ * @param entityPriorChanges - The entity before the changes.
1041
+ * @returns Whether or not the entity is dirty.
1042
+ */
1043
+ static dirty(entity, entityPriorChanges) {
1044
+ return __awaiter(this, void 0, void 0, function* () {
1045
+ if (!entityPriorChanges) {
1046
+ return false;
1047
+ }
1048
+ else {
1049
+ const differences = yield EntityUtilities.differencesForDirty(entity, entityPriorChanges);
1050
+ return differences.length ? true : false;
1051
+ }
1052
+ });
1053
+ }
1054
+ static differencesForDirty(entity, entityPriorChanges) {
1055
+ return __awaiter(this, void 0, void 0, function* () {
1056
+ const res = [];
1057
+ for (const key in entity) {
1058
+ const metadata = EntityUtilities.getPropertyMetadata(entity, key);
1059
+ const type = EntityUtilities.getPropertyType(entity, key);
1060
+ if (!(yield EntityUtilities.isEqual(entity[key], entityPriorChanges[key], metadata, type))) {
1061
+ res.push({
1062
+ key: key,
1063
+ before: entityPriorChanges[key],
1064
+ after: entity[key]
1065
+ });
1066
+ }
1067
+ }
1068
+ return res;
1069
+ });
1070
+ }
1071
+ /**
1072
+ * Compares two Entities and returns their difference in an object.
1073
+ *
1074
+ * @param entity - The first entity to compare.
1075
+ * @param entityPriorChanges - The second entity to compare.
1076
+ * @returns The difference between the two Entities in form of a Partial.
1077
+ */
1078
+ static difference(entity, entityPriorChanges) {
1079
+ return __awaiter(this, void 0, void 0, function* () {
1080
+ const res = {};
1081
+ for (const key in entity) {
1082
+ const metadata = EntityUtilities.getPropertyMetadata(entity, key);
1083
+ const type = EntityUtilities.getPropertyType(entity, key);
1084
+ if (!(yield EntityUtilities.isEqual(entity[key], entityPriorChanges[key], metadata, type))) {
1085
+ res[key] = entity[key];
1086
+ }
1087
+ }
1088
+ return res;
1089
+ });
1090
+ }
1091
+ /**
1092
+ * Checks if two given values are equal.
1093
+ * It uses the isEqual method from LodashUtilities and extends it with functionality regarding Dates.
1094
+ *
1095
+ * @param value - The updated value.
1096
+ * @param valuePriorChanges - The value before any changes.
1097
+ * @param metadata - The metadata of the property.
1098
+ * @param type - The type of the property.
1099
+ * @returns Whether or not the given values are equal.
1100
+ */
1101
+ static isEqual(value, valuePriorChanges, metadata, type) {
1102
+ return __awaiter(this, void 0, void 0, function* () {
1103
+ switch (type) {
1104
+ case DecoratorTypes.DATE_RANGE:
1105
+ return EntityUtilities.isEqualDateRange(value, valuePriorChanges, metadata.filter);
1106
+ case DecoratorTypes.DATE:
1107
+ return EntityUtilities.isEqualDate(value, valuePriorChanges);
1108
+ case DecoratorTypes.DATE_TIME:
1109
+ return EntityUtilities.isEqualDateTime(value, valuePriorChanges);
1110
+ case DecoratorTypes.ARRAY_DATE:
1111
+ case DecoratorTypes.ARRAY_DATE_TIME:
1112
+ return EntityUtilities.isEqualArrayDate(value, valuePriorChanges);
1113
+ case DecoratorTypes.ARRAY_DATE_RANGE:
1114
+ return EntityUtilities.isEqualArrayDateRange(value, valuePriorChanges, metadata.filter);
1115
+ case DecoratorTypes.FILE_IMAGE:
1116
+ case DecoratorTypes.FILE_DEFAULT:
1117
+ return EntityUtilities.isEqualFile(value, valuePriorChanges, metadata.multiple);
1118
+ case DecoratorTypes.CUSTOM:
1119
+ // eslint-disable-next-line max-len, @typescript-eslint/no-explicit-any
1120
+ return EntityUtilities.isEqualCustom(value, valuePriorChanges, metadata);
1121
+ default:
1122
+ return LodashUtilities.isEqual(value, valuePriorChanges);
1123
+ }
1124
+ });
1125
+ }
1126
+ static isEqualArrayDate(value, valuePriorChanges) {
1127
+ const newValue = value.map(v => new Date(v)).sort();
1128
+ const newValuePriorChanges = valuePriorChanges.map(v => new Date(v)).sort();
1129
+ return LodashUtilities.isEqual(newValue, newValuePriorChanges);
1130
+ }
1131
+ static isEqualArrayDateRange(value, valuePriorChanges, filter) {
1132
+ const dateRanges = value.sort();
1133
+ const dateRangesPriorChanges = valuePriorChanges.sort();
1134
+ if (dateRanges.length !== dateRangesPriorChanges.length) {
1135
+ return false;
1136
+ }
1137
+ for (let i = 0; i < dateRanges.length; i++) {
1138
+ if (!EntityUtilities.isEqualDateRange(dateRanges[i], dateRangesPriorChanges[i], filter)) {
1139
+ return false;
1140
+ }
1141
+ }
1142
+ return true;
1143
+ }
1144
+ static isEqualDateTime(value, valuePriorChanges) {
1145
+ const date = new Date(value);
1146
+ const datePriorChanges = new Date(valuePriorChanges);
1147
+ return LodashUtilities.isEqual(date, datePriorChanges);
1148
+ }
1149
+ static isEqualDate(value, valuePriorChanges) {
1150
+ const date = new Date(value);
1151
+ const datePriorChanges = new Date(valuePriorChanges);
1152
+ date.setHours(0, 0, 0, 0);
1153
+ datePriorChanges.setHours(0, 0, 0, 0);
1154
+ return LodashUtilities.isEqual(date, datePriorChanges);
1155
+ }
1156
+ static isEqualDateRange(value, valuePriorChanges, filter) {
1157
+ const dateRange = LodashUtilities.cloneDeep(value);
1158
+ dateRange.start = new Date(value.start);
1159
+ dateRange.end = new Date(value.end);
1160
+ dateRange.values = DateUtilities.getDatesBetween(dateRange.start, dateRange.end, filter);
1161
+ const dateRangePriorChanges = LodashUtilities.cloneDeep(valuePriorChanges);
1162
+ dateRangePriorChanges.start = new Date(valuePriorChanges.start);
1163
+ dateRangePriorChanges.end = new Date(valuePriorChanges.end);
1164
+ dateRangePriorChanges.values = DateUtilities.getDatesBetween(dateRangePriorChanges.start, dateRangePriorChanges.end, filter);
1165
+ return LodashUtilities.isEqual(dateRange, dateRangePriorChanges);
1166
+ }
1167
+ // TODO: Find a way to use blobs with jest
1168
+ /* istanbul ignore next */
1169
+ static isEqualFile(value, valuePriorChanges, multiple) {
1170
+ var _a, _b, _c, _d, _e, _f;
1171
+ return __awaiter(this, void 0, void 0, function* () {
1172
+ const files = multiple ? value.sort() : [value].sort();
1173
+ const filesPriorChanges = multiple ? valuePriorChanges.sort() : [valuePriorChanges].sort();
1174
+ if (files.length !== filesPriorChanges.length) {
1175
+ return false;
1176
+ }
1177
+ for (let i = 0; i < files.length; i++) {
1178
+ // checks this before actually getting any files due to performance reasons.
1179
+ if (!LodashUtilities.isEqual((_a = files[i]) === null || _a === void 0 ? void 0 : _a.name, (_b = filesPriorChanges[i]) === null || _b === void 0 ? void 0 : _b.name)
1180
+ || !LodashUtilities.isEqual((_c = files[i]) === null || _c === void 0 ? void 0 : _c.url, (_d = filesPriorChanges[i]) === null || _d === void 0 ? void 0 : _d.url)) {
1181
+ return false;
1182
+ }
1183
+ files[i] = filesPriorChanges[i].file && !files[i].file ? yield FileUtilities.getFileData(files[i]) : files[i];
1184
+ // eslint-disable-next-line max-len
1185
+ filesPriorChanges[i] = files[i].file && !filesPriorChanges[i].file ? yield FileUtilities.getFileData(filesPriorChanges[i]) : filesPriorChanges[i];
1186
+ if (!LodashUtilities.isEqual(yield ((_e = files[i].file) === null || _e === void 0 ? void 0 : _e.text()), yield ((_f = filesPriorChanges[i].file) === null || _f === void 0 ? void 0 : _f.text()))) {
1187
+ return false;
1188
+ }
1189
+ }
1190
+ return true;
1191
+ });
1192
+ }
1193
+ static isEqualCustom(value, valuePriorChanges,
1194
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1195
+ metadata) {
1196
+ if (!metadata.isEqual(value, valuePriorChanges, metadata)) {
1197
+ return false;
1198
+ }
1199
+ return true;
1200
+ }
1201
+ /**
1202
+ * Compare function for sorting entity keys by their order value.
1203
+ *
461
1204
  * @param a - First key of entity.
462
1205
  * @param b - Second key of entity.
463
1206
  * @param entity - Current entity (used to get metadata of entity keys).
464
- * @returns 0 if both values have the same order, a negative value if X, a positive value if Y.
1207
+ * @returns 0 if both values have the same order, a negative value if 'a' comes before 'b', a positive value if 'a' comes behind 'b'.
465
1208
  */
466
1209
  static compareOrder(a, b, entity) {
467
1210
  const metadataA = EntityUtilities.getPropertyMetadata(entity, a);
@@ -475,7 +1218,7 @@ class EntityUtilities {
475
1218
  else if (metadataB.position.order === -1) {
476
1219
  return -1;
477
1220
  }
478
- return ((metadataA.position.order) - (metadataB.position.order));
1221
+ return metadataA.position.order - metadataB.position.order;
479
1222
  }
480
1223
  /**
481
1224
  * Gets the bootstrap column values for "lg", "md", "sm".
@@ -504,7 +1247,7 @@ class EntityUtilities {
504
1247
  */
505
1248
  static resetChangesOnEntity(entity, entityPriorChanges) {
506
1249
  for (const key in entityPriorChanges) {
507
- Reflect.set(entity, key, Reflect.get(entityPriorChanges, key));
1250
+ ReflectUtilities.set(entity, key, ReflectUtilities.get(entityPriorChanges, key));
508
1251
  }
509
1252
  }
510
1253
  /**
@@ -552,7 +1295,7 @@ class EntityUtilities {
552
1295
  * @returns An array of keys of the entity.
553
1296
  */
554
1297
  static keysOf(entity, hideOmitForCreate = false, hideOmitForEdit = false) {
555
- let keys = Reflect.ownKeys(entity);
1298
+ let keys = ReflectUtilities.ownKeys(entity);
556
1299
  if (hideOmitForCreate) {
557
1300
  const omitForCreateKeys = EntityUtilities.getOmitForCreate(entity);
558
1301
  keys = keys.filter(k => !omitForCreateKeys.includes(k));
@@ -564,11 +1307,30 @@ class EntityUtilities {
564
1307
  return keys;
565
1308
  }
566
1309
  }
567
- _a = EntityUtilities;
568
1310
  // eslint-disable-next-line @typescript-eslint/member-ordering, jsdoc/require-jsdoc
569
- EntityUtilities.construct = _a.new;
1311
+ EntityUtilities.construct = EntityUtilities.new;
570
1312
  // eslint-disable-next-line @typescript-eslint/member-ordering, jsdoc/require-jsdoc
571
- EntityUtilities.build = _a.new;
1313
+ EntityUtilities.build = EntityUtilities.new;
1314
+
1315
+ /**
1316
+ * A base Entity class with a builtin id.
1317
+ */
1318
+ class Entity {
1319
+ constructor(entity) {
1320
+ EntityUtilities.new(this, entity);
1321
+ }
1322
+ }
1323
+ __decorate([
1324
+ string({
1325
+ omitForCreate: true,
1326
+ omitForUpdate: true,
1327
+ display: false,
1328
+ displayStyle: 'line',
1329
+ displayName: 'ID',
1330
+ required: true
1331
+ }),
1332
+ __metadata("design:type", String)
1333
+ ], Entity.prototype, "id", void 0);
572
1334
 
573
1335
  /**
574
1336
  * A generic EntityService class.
@@ -579,6 +1341,12 @@ EntityUtilities.build = _a.new;
579
1341
  class EntityService {
580
1342
  constructor(http) {
581
1343
  this.http = http;
1344
+ /**
1345
+ * The key which holds the id value.
1346
+ *
1347
+ * @default 'id'
1348
+ */
1349
+ this.idKey = 'id';
582
1350
  /**
583
1351
  * A subject of all the entity values.
584
1352
  * Can be subscribed to when you want to do a specific thing whenever the entities change.
@@ -602,7 +1370,58 @@ class EntityService {
602
1370
  */
603
1371
  create(entity) {
604
1372
  return __awaiter(this, void 0, void 0, function* () {
605
- const body = omit(entity, EntityUtilities.getOmitForCreate(entity));
1373
+ const body = LodashUtilities.omit(entity, EntityUtilities.getOmitForCreate(entity));
1374
+ const filePropertyKeys = EntityUtilities.getFileProperties(entity);
1375
+ if (!filePropertyKeys.length) {
1376
+ return yield this.createWithJson(body);
1377
+ }
1378
+ else {
1379
+ return yield this.createWithFormData(body, filePropertyKeys, entity);
1380
+ }
1381
+ });
1382
+ }
1383
+ // TODO: Find a way to use blobs with jest
1384
+ /* istanbul ignore next */
1385
+ /**
1386
+ * Creates the entity with form data when the entity contains files in contrast to creating it with a normal json body.
1387
+ * All file values are stored inside their respective property key and their name.
1388
+ * Form data is able to handle setting multiple files to the same key.
1389
+ *
1390
+ * @param body - The body Of the request.
1391
+ * @param filePropertyKeys - All property keys that are files and need to be added to the form data.
1392
+ * @param entity - The entity to create. This is needed in addition to the body because the body doesn't contain any metadata.
1393
+ * @returns The created entity from the server.
1394
+ */
1395
+ createWithFormData(body, filePropertyKeys, entity) {
1396
+ return __awaiter(this, void 0, void 0, function* () {
1397
+ const formData = new FormData();
1398
+ formData.append('body', JSON.stringify(LodashUtilities.omit(body, filePropertyKeys)));
1399
+ for (const key of filePropertyKeys) {
1400
+ if (EntityUtilities.getPropertyMetadata(entity, key, DecoratorTypes.FILE_DEFAULT).multiple) {
1401
+ const fileDataValues = body[key];
1402
+ for (const value of fileDataValues) {
1403
+ formData.append(key, (yield FileUtilities.getFileData(value)).file, value.name);
1404
+ }
1405
+ }
1406
+ else {
1407
+ const fileData = body[key];
1408
+ formData.append(key, (yield FileUtilities.getFileData(fileData)).file, fileData.name);
1409
+ }
1410
+ }
1411
+ const e = yield firstValueFrom(this.http.post(this.baseUrl, formData));
1412
+ this.entities.push(e);
1413
+ this.entitiesSubject.next(this.entities);
1414
+ return e;
1415
+ });
1416
+ }
1417
+ /**
1418
+ * Creates the entity with a normal json body in contrast to creating it with form data when the entity contains files.
1419
+ *
1420
+ * @param body - The body Of the request.
1421
+ * @returns The created entity from the server.
1422
+ */
1423
+ createWithJson(body) {
1424
+ return __awaiter(this, void 0, void 0, function* () {
606
1425
  const e = yield firstValueFrom(this.http.post(this.baseUrl, body));
607
1426
  this.entities.push(e);
608
1427
  this.entitiesSubject.next(this.entities);
@@ -631,21 +1450,74 @@ class EntityService {
631
1450
  */
632
1451
  update(entity, entityPriorChanges) {
633
1452
  return __awaiter(this, void 0, void 0, function* () {
634
- const reqBody = omit(EntityUtilities.difference(entity, entityPriorChanges), EntityUtilities.getOmitForUpdate(entity));
635
- const updatedEntity = yield firstValueFrom(this.http.patch(`${this.baseUrl}/${entityPriorChanges.id}`, omitBy(reqBody, isNil)));
636
- this.entities[this.entities.findIndex((e) => e.id === entityPriorChanges.id)] = updatedEntity;
1453
+ const body = LodashUtilities.omit(yield EntityUtilities.difference(entity, entityPriorChanges), EntityUtilities.getOmitForUpdate(entity));
1454
+ const filePropertyKeys = EntityUtilities.getFileProperties(entityPriorChanges);
1455
+ if (!filePropertyKeys.length) {
1456
+ yield this.updateWithJson(body, entityPriorChanges[this.idKey]);
1457
+ }
1458
+ else {
1459
+ yield this.updateWithFormData(body, filePropertyKeys, entity, entityPriorChanges[this.idKey]);
1460
+ }
1461
+ });
1462
+ }
1463
+ // TODO: Find a way to use blobs with jest
1464
+ /* istanbul ignore next */
1465
+ /**
1466
+ * Updates the entity with form data when the entity contains files in contrast to creating it with a normal json body.
1467
+ * All file values are stored inside their respective property key and their name.
1468
+ * Form data is able to handle setting multiple files to the same key.
1469
+ *
1470
+ * @param body - The request body. Already contains only properties that have changed.
1471
+ * @param filePropertyKeys - The keys of all properties which are files and need to separately be appended to the form data.
1472
+ * @param entity - The original entity. Is needed to get the metadata of all the files.
1473
+ * @param id - The id of the entity to update.
1474
+ */
1475
+ updateWithFormData(body, filePropertyKeys, entity, id) {
1476
+ return __awaiter(this, void 0, void 0, function* () {
1477
+ const formData = new FormData();
1478
+ formData.append('body', JSON.stringify(LodashUtilities.omitBy(body, LodashUtilities.isNil)));
1479
+ for (const key of filePropertyKeys) {
1480
+ if (EntityUtilities.getPropertyMetadata(entity, key, DecoratorTypes.FILE_DEFAULT).multiple) {
1481
+ // eslint-disable-next-line max-len
1482
+ const fileDataValues = body[key];
1483
+ for (const value of fileDataValues) {
1484
+ formData.append(key, (yield FileUtilities.getFileData(value)).file, value.name);
1485
+ }
1486
+ }
1487
+ else {
1488
+ // eslint-disable-next-line max-len
1489
+ const fileData = body[key];
1490
+ formData.append(key, (yield FileUtilities.getFileData(fileData)).file, fileData.name);
1491
+ }
1492
+ }
1493
+ const updatedEntity = yield firstValueFrom(this.http.patch(`${this.baseUrl}/${id}`, formData));
1494
+ this.entities[this.entities.findIndex(e => e[this.idKey] === id)] = updatedEntity;
1495
+ this.entitiesSubject.next(this.entities);
1496
+ });
1497
+ }
1498
+ /**
1499
+ * Updates the entity with a normal json body in contrast to updating it with form data when the entity contains files.
1500
+ *
1501
+ * @param body - The body of the Request. Has already removed all unnecessary values.
1502
+ * @param id - The id of the entity to update.
1503
+ */
1504
+ updateWithJson(body, id) {
1505
+ return __awaiter(this, void 0, void 0, function* () {
1506
+ const updatedEntity = yield firstValueFrom(this.http.patch(`${this.baseUrl}/${id}`, LodashUtilities.omitBy(body, LodashUtilities.isNil)));
1507
+ this.entities[this.entities.findIndex(e => e[this.idKey] === id)] = updatedEntity;
637
1508
  this.entitiesSubject.next(this.entities);
638
1509
  });
639
1510
  }
640
1511
  /**
641
1512
  * Deletes a specific Entity.
642
1513
  *
643
- * @param id - The id of the element to delete.
1514
+ * @param entity - The entity to delete.
644
1515
  */
645
- delete(id) {
1516
+ delete(entity) {
646
1517
  return __awaiter(this, void 0, void 0, function* () {
647
- yield firstValueFrom(this.http.delete(`${this.baseUrl}/${id}`));
648
- this.entities.splice(this.entities.findIndex((e) => e.id === id), 1);
1518
+ yield firstValueFrom(this.http.delete(`${this.baseUrl}/${entity[this.idKey]}`));
1519
+ // the == comparison instead of === is to catch ids that are numbers.
1520
+ this.entities.splice(this.entities.findIndex(e => e[this.idKey] === entity[this.idKey]), 1);
649
1521
  this.entitiesSubject.next(this.entities);
650
1522
  });
651
1523
  }
@@ -670,7 +1542,6 @@ class BaseBuilder {
670
1542
  validateInput(data) {
671
1543
  // By default, no validation is done
672
1544
  }
673
- ;
674
1545
  /**
675
1546
  * Sets the value for the given key if no user value was provided.
676
1547
  *
@@ -679,7 +1550,7 @@ class BaseBuilder {
679
1550
  * @returns The Builder.
680
1551
  */
681
1552
  withDefault(key, value) {
682
- if (!this.inputData || !this.inputData[key]) {
1553
+ if (this.inputData == null || this.inputData[key] == null) {
683
1554
  this.data[key] = value;
684
1555
  }
685
1556
  return this;
@@ -717,18 +1588,19 @@ class ConfirmDialogDataBuilder extends BaseBuilder {
717
1588
  }
718
1589
  // eslint-disable-next-line jsdoc/require-jsdoc
719
1590
  generateBaseData(data) {
720
- return new ConfirmDialogDataInternal((data === null || data === void 0 ? void 0 : data.text) ? data.text : ['Do you really want to do this?'], (data === null || data === void 0 ? void 0 : data.type) ? data.type : 'default', (data === null || data === void 0 ? void 0 : data.confirmButtonLabel) ? data.confirmButtonLabel : 'Confirm', (data === null || data === void 0 ? void 0 : data.cancelButtonLabel) ? data.cancelButtonLabel : 'Cancel', (data === null || data === void 0 ? void 0 : data.title) ? data.title : 'Confirmation', (data === null || data === void 0 ? void 0 : data.requireConfirmation) ? data.requireConfirmation : false, data === null || data === void 0 ? void 0 : data.confirmationText);
1591
+ var _a, _b, _c, _d, _e, _f;
1592
+ return new ConfirmDialogDataInternal((_a = data === null || data === void 0 ? void 0 : data.text) !== null && _a !== void 0 ? _a : ['Do you really want to do this?'], (_b = data === null || data === void 0 ? void 0 : data.type) !== null && _b !== void 0 ? _b : 'default', (_c = data === null || data === void 0 ? void 0 : data.confirmButtonLabel) !== null && _c !== void 0 ? _c : 'Confirm', (_d = data === null || data === void 0 ? void 0 : data.cancelButtonLabel) !== null && _d !== void 0 ? _d : 'Cancel', (_e = data === null || data === void 0 ? void 0 : data.title) !== null && _e !== void 0 ? _e : 'Confirmation', (_f = data === null || data === void 0 ? void 0 : data.requireConfirmation) !== null && _f !== void 0 ? _f : false, data === null || data === void 0 ? void 0 : data.confirmationText);
721
1593
  }
722
1594
  // eslint-disable-next-line jsdoc/require-jsdoc
723
1595
  validateInput(data) {
724
1596
  if (!data) {
725
1597
  return;
726
1598
  }
727
- if (data.requireConfirmation && !data.confirmationText) {
1599
+ if (data.requireConfirmation === true && !data.confirmationText) {
728
1600
  throw new Error(`Missing required Input data "confirmationText".
729
1601
  You can only omit this value when "requireConfirmation" is false.`);
730
1602
  }
731
- if (!data.requireConfirmation && data.confirmationText) {
1603
+ if (data.requireConfirmation !== true && data.confirmationText) {
732
1604
  throw new Error('The "confirmationText" will never be shown because "requireConfirmation" is not set to true');
733
1605
  }
734
1606
  if (data.type === 'info-only' && data.cancelButtonLabel) {
@@ -766,10 +1638,10 @@ class NgxMatEntityConfirmDialogComponent {
766
1638
  }
767
1639
  }
768
1640
  NgxMatEntityConfirmDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityConfirmDialogComponent, deps: [{ token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
769
- NgxMatEntityConfirmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityConfirmDialogComponent, selector: "ngx-mat-entity-confirm-dialog", ngImport: i0, template: "<h2 mat-dialog-title *ngIf=\"data.title\">{{data.title}}</h2>\n\n<mat-dialog-content>\n <p *ngFor=\"let paragraph of data.text\">{{paragraph}}</p>\n <div *ngIf=\"data.requireConfirmation\" class=\"checkbox-wrapper\">\n <mat-checkbox [(ngModel)]=\"confirm\" name=\"confirm\">\n {{data.confirmationText}}\n </mat-checkbox>\n </div>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button *ngIf=\"data.type === 'delete'\" mat-raised-button color=\"warn\" (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel}}\n </button>\n <button *ngIf=\"data.type !== 'delete'\" mat-raised-button (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: [".checkbox-wrapper{min-height:50px;display:flex}.checkbox-wrapper>mat-checkbox{align-self:center}mat-dialog-actions{display:flex;justify-content:space-between}\n"], components: [{ type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i13.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i13.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
1641
+ NgxMatEntityConfirmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityConfirmDialogComponent, selector: "ngx-mat-entity-confirm-dialog", ngImport: i0, template: "<h2 mat-dialog-title *ngIf=\"data.title\">{{data.title}}</h2>\n\n<mat-dialog-content>\n <p *ngFor=\"let paragraph of data.text\">{{paragraph}}</p>\n <div *ngIf=\"data.requireConfirmation\" class=\"checkbox-wrapper\">\n <mat-checkbox [(ngModel)]=\"confirm\" name=\"confirm\">\n {{data.confirmationText}}\n </mat-checkbox>\n </div>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button *ngIf=\"data.type === 'delete'\" mat-raised-button color=\"warn\" (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel}}\n </button>\n <button *ngIf=\"data.type !== 'delete'\" mat-raised-button (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel}}\n </button>\n <button *ngIf=\"data.type !== 'info-only'\" mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: [".checkbox-wrapper{min-height:50px;display:flex}.checkbox-wrapper>mat-checkbox{align-self:center}mat-dialog-actions{display:flex;justify-content:space-between}\n"], components: [{ type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
770
1642
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityConfirmDialogComponent, decorators: [{
771
1643
  type: Component,
772
- args: [{ selector: 'ngx-mat-entity-confirm-dialog', template: "<h2 mat-dialog-title *ngIf=\"data.title\">{{data.title}}</h2>\n\n<mat-dialog-content>\n <p *ngFor=\"let paragraph of data.text\">{{paragraph}}</p>\n <div *ngIf=\"data.requireConfirmation\" class=\"checkbox-wrapper\">\n <mat-checkbox [(ngModel)]=\"confirm\" name=\"confirm\">\n {{data.confirmationText}}\n </mat-checkbox>\n </div>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button *ngIf=\"data.type === 'delete'\" mat-raised-button color=\"warn\" (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel}}\n </button>\n <button *ngIf=\"data.type !== 'delete'\" mat-raised-button (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: [".checkbox-wrapper{min-height:50px;display:flex}.checkbox-wrapper>mat-checkbox{align-self:center}mat-dialog-actions{display:flex;justify-content:space-between}\n"] }]
1644
+ args: [{ selector: 'ngx-mat-entity-confirm-dialog', template: "<h2 mat-dialog-title *ngIf=\"data.title\">{{data.title}}</h2>\n\n<mat-dialog-content>\n <p *ngFor=\"let paragraph of data.text\">{{paragraph}}</p>\n <div *ngIf=\"data.requireConfirmation\" class=\"checkbox-wrapper\">\n <mat-checkbox [(ngModel)]=\"confirm\" name=\"confirm\">\n {{data.confirmationText}}\n </mat-checkbox>\n </div>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button *ngIf=\"data.type === 'delete'\" mat-raised-button color=\"warn\" (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel}}\n </button>\n <button *ngIf=\"data.type !== 'delete'\" mat-raised-button (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel}}\n </button>\n <button *ngIf=\"data.type !== 'info-only'\" mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: [".checkbox-wrapper{min-height:50px;display:flex}.checkbox-wrapper>mat-checkbox{align-self:center}mat-dialog-actions{display:flex;justify-content:space-between}\n"] }]
773
1645
  }], ctorParameters: function () {
774
1646
  return [{ type: i1.MatDialogRef }, { type: undefined, decorators: [{
775
1647
  type: Inject,
@@ -849,12 +1721,13 @@ class CreateDialogDataBuilder extends BaseBuilder {
849
1721
  }
850
1722
  // eslint-disable-next-line jsdoc/require-jsdoc
851
1723
  generateBaseData(data) {
1724
+ var _a, _b, _c, _d;
852
1725
  const confirmCreateDialogData = new ConfirmDialogDataBuilder(data === null || data === void 0 ? void 0 : data.confirmCreateDialogData)
853
1726
  .withDefault('confirmButtonLabel', 'create')
854
1727
  .withDefault('text', ['Do you really want to create this entity?'])
855
1728
  .withDefault('title', 'Create')
856
1729
  .getResult();
857
- return new CreateDialogDataInternal((data === null || data === void 0 ? void 0 : data.title) ? data.title : 'Create', (data === null || data === void 0 ? void 0 : data.createButtonLabel) ? data.createButtonLabel : 'Create', (data === null || data === void 0 ? void 0 : data.cancelButtonLabel) ? data.cancelButtonLabel : 'Cancel', (data === null || data === void 0 ? void 0 : data.createRequiresConfirmDialog) ? data.createRequiresConfirmDialog : false, confirmCreateDialogData);
1730
+ return new CreateDialogDataInternal((_a = data === null || data === void 0 ? void 0 : data.title) !== null && _a !== void 0 ? _a : 'Create', (_b = data === null || data === void 0 ? void 0 : data.createButtonLabel) !== null && _b !== void 0 ? _b : 'Create', (_c = data === null || data === void 0 ? void 0 : data.cancelButtonLabel) !== null && _c !== void 0 ? _c : 'Cancel', (_d = data === null || data === void 0 ? void 0 : data.createRequiresConfirmDialog) !== null && _d !== void 0 ? _d : false, confirmCreateDialogData);
858
1731
  }
859
1732
  }
860
1733
 
@@ -877,139 +1750,1162 @@ class AddArrayItemDialogDataBuilder extends BaseBuilder {
877
1750
  }
878
1751
  // eslint-disable-next-line jsdoc/require-jsdoc
879
1752
  generateBaseData(data) {
1753
+ var _a;
880
1754
  const createDialogData = new CreateDialogDataBuilder(data.createDialogData)
881
1755
  .withDefault('createButtonLabel', 'Add')
882
1756
  .withDefault('title', 'Add to array')
883
1757
  .getResult();
884
- return new AddArrayItemDialogDataInternal(data.entity, createDialogData, data.getValidationErrorMessage ? data.getValidationErrorMessage : getValidationErrorMessage);
1758
+ return new AddArrayItemDialogDataInternal(data.entity, createDialogData, (_a = data.getValidationErrorMessage) !== null && _a !== void 0 ? _a : getValidationErrorMessage);
885
1759
  }
886
1760
  }
887
1761
 
888
1762
  /**
889
- * The default input component. It gets the metadata of the property from the given @Input "entity" and @Input "propertyKey"
890
- * and displays the input field accordingly.
891
- *
892
- * You can also define a method that generates error-messages and if the input should be hidden when its metadata says
893
- * that it should be omitted for creating or updating.
894
- * The last part being mostly relevant if you want to use this component inside an ngFor.
1763
+ * The abstract base class of any ngx-mat-entity input.
895
1764
  */
896
- class NgxMatEntityInputComponent {
897
- constructor(dialog) {
898
- this.dialog = dialog;
899
- this.chipsInput = '';
900
- this.selection = new SelectionModel(true, []);
901
- this.DecoratorTypes = DecoratorTypes;
902
- this.EntityUtilities = EntityUtilities;
903
- this.getWidth = EntityUtilities.getWidth;
1765
+ // eslint-disable-next-line max-len
1766
+ class NgxMatEntityBaseInputComponent {
1767
+ constructor() {
1768
+ this.inputChangeEvent = new EventEmitter();
1769
+ }
1770
+ ngOnInit() {
1771
+ this.metadata = EntityUtilities.getPropertyMetadata(this.entity, this.key);
904
1772
  }
905
1773
  /**
906
- * This is needed for the inputs to work inside an ngFor.
907
- *
908
- * @param index - The index of the element in the ngFor.
909
- * @returns The index.
1774
+ * Should emit when the input has changed. This is needed to trigger validation and dirty checks.
910
1775
  */
911
- trackByFn(index) {
912
- return index;
1776
+ emitChange() {
1777
+ this.inputChangeEvent.emit();
913
1778
  }
1779
+ }
1780
+ NgxMatEntityBaseInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityBaseInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1781
+ NgxMatEntityBaseInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityBaseInputComponent, selector: "ngx-mat-entity-base-input", inputs: { entity: "entity", key: "key", getValidationErrorMessage: "getValidationErrorMessage" }, outputs: { inputChangeEvent: "inputChangeEvent" }, ngImport: i0, template: '', isInline: true });
1782
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityBaseInputComponent, decorators: [{
1783
+ type: Component,
1784
+ args: [{
1785
+ selector: 'ngx-mat-entity-base-input',
1786
+ template: ''
1787
+ }]
1788
+ }], propDecorators: { entity: [{
1789
+ type: Input
1790
+ }], key: [{
1791
+ type: Input
1792
+ }], getValidationErrorMessage: [{
1793
+ type: Input
1794
+ }], inputChangeEvent: [{
1795
+ type: Output
1796
+ }] } });
1797
+
1798
+ /* eslint-disable jsdoc/require-jsdoc */
1799
+ class StringInputComponent extends NgxMatEntityBaseInputComponent {
1800
+ }
1801
+ StringInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1802
+ StringInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: StringInputComponent, selector: "string-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n (ngModelChange)=\"emitChange()\"\n />\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i3$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i3$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i3$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
1803
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringInputComponent, decorators: [{
1804
+ type: Component,
1805
+ args: [{ selector: 'string-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n (ngModelChange)=\"emitChange()\"\n />\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
1806
+ }] });
1807
+
1808
+ /* eslint-disable jsdoc/require-jsdoc */
1809
+ class StringTextboxInputComponent extends NgxMatEntityBaseInputComponent {
1810
+ }
1811
+ StringTextboxInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringTextboxInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1812
+ StringTextboxInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: StringTextboxInputComponent, selector: "string-textbox-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <textarea\n matInput\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"10\"\n [required]=\"metadata.required\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n (ngModelChange)=\"emitChange()\"\n >\n </textarea>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i3$2.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i3$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i3$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
1813
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringTextboxInputComponent, decorators: [{
1814
+ type: Component,
1815
+ args: [{ selector: 'string-textbox-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <textarea\n matInput\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"10\"\n [required]=\"metadata.required\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n (ngModelChange)=\"emitChange()\"\n >\n </textarea>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
1816
+ }] });
1817
+
1818
+ /* eslint-disable jsdoc/require-jsdoc */
1819
+ class StringAutocompleteInputComponent extends NgxMatEntityBaseInputComponent {
914
1820
  ngOnInit() {
915
- var _a;
916
- if (!this.entity) {
917
- throw new Error('Missing required Input data "entity"');
918
- }
919
- if (!this.propertyKey) {
920
- throw new Error('Missing required Input data "propertyKey"');
921
- }
922
- this.type = EntityUtilities.getPropertyType(this.entity, this.propertyKey);
923
- this.metadata = EntityUtilities.getPropertyMetadata(this.entity, this.propertyKey, this.type);
924
- this.metadataDefaultString = this.metadata;
925
- this.metadataTextboxString = this.metadata;
926
- this.metadataAutocompleteString = this.metadata;
927
- this.autocompleteStrings = this.metadataAutocompleteString.autocompleteValues;
928
- this.filteredAutocompleteStrings = cloneDeep(this.autocompleteStrings);
929
- this.metadataDropdownString = this.metadata;
930
- this.metadataDropdownBoolean = this.metadata;
931
- if ((this.type === DecoratorTypes.BOOLEAN_CHECKBOX || this.type === DecoratorTypes.BOOLEAN_TOGGLE)
932
- && this.entity[this.propertyKey] === undefined) {
933
- this.entity[this.propertyKey] = false;
934
- }
935
- this.metadataDefaultNumber = this.metadata;
936
- this.metadataDropdownNumber = this.metadata;
937
- this.metadataDefaultObject = this.metadata;
938
- this.objectProperty = this.entity[this.propertyKey];
939
- if (this.type === DecoratorTypes.OBJECT) {
940
- this.objectPropertyRows = EntityUtilities.getEntityRows(this.objectProperty, this.hideOmitForCreate, this.hideOmitForEdit);
1821
+ super.ngOnInit();
1822
+ this.autocompleteStrings = this.metadata.autocompleteValues;
1823
+ this.filteredAutocompleteStrings = LodashUtilities.cloneDeep(this.autocompleteStrings);
1824
+ }
1825
+ /**
1826
+ * Dynamically filters the Autocomplete options when the user inputs something.
1827
+ *
1828
+ * @param input - The input of the user.
1829
+ */
1830
+ filterAutocompleteStrings(input) {
1831
+ const inputString = input;
1832
+ if (inputString) {
1833
+ const filterValue = inputString.toLowerCase();
1834
+ this.filteredAutocompleteStrings = this.autocompleteStrings.filter(s => s.toLowerCase().includes(filterValue));
1835
+ }
1836
+ }
1837
+ }
1838
+ StringAutocompleteInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringAutocompleteInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1839
+ StringAutocompleteInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: StringAutocompleteInputComponent, selector: "string-autocomplete-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matAutocomplete]=\"auto\"\n (keyup)=\"filterAutocompleteStrings(entity[key])\"\n [required]=\"metadata.required\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n (ngModelChange)=\"emitChange()\"\n />\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let value of filteredAutocompleteStrings\" [value]=\"value\">\n {{value}}\n </mat-option>\n </mat-autocomplete>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$1.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { type: i3$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i3$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i3$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i3$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
1840
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringAutocompleteInputComponent, decorators: [{
1841
+ type: Component,
1842
+ args: [{ selector: 'string-autocomplete-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matAutocomplete]=\"auto\"\n (keyup)=\"filterAutocompleteStrings(entity[key])\"\n [required]=\"metadata.required\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n (ngModelChange)=\"emitChange()\"\n />\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let value of filteredAutocompleteStrings\" [value]=\"value\">\n {{value}}\n </mat-option>\n </mat-autocomplete>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
1843
+ }] });
1844
+
1845
+ /* eslint-disable jsdoc/require-jsdoc */
1846
+ class StringDropdownInputComponent extends NgxMatEntityBaseInputComponent {
1847
+ }
1848
+ StringDropdownInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringDropdownInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1849
+ StringDropdownInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: StringDropdownInputComponent, selector: "string-dropdown-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select (ngModelChange)=\"emitChange()\" [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\" #model=\"ngModel\" [required]=\"metadata.required\">\n <mat-option *ngFor=\"let value of metadata.dropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
1850
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringDropdownInputComponent, decorators: [{
1851
+ type: Component,
1852
+ args: [{ selector: 'string-dropdown-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select (ngModelChange)=\"emitChange()\" [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\" #model=\"ngModel\" [required]=\"metadata.required\">\n <mat-option *ngFor=\"let value of metadata.dropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
1853
+ }] });
1854
+
1855
+ /* eslint-disable jsdoc/require-jsdoc */
1856
+ class BooleanCheckboxInputComponent extends NgxMatEntityBaseInputComponent {
1857
+ ngOnInit() {
1858
+ super.ngOnInit();
1859
+ if (this.entity[this.key] == null) {
1860
+ this.entity[this.key] = false;
1861
+ }
1862
+ }
1863
+ }
1864
+ BooleanCheckboxInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BooleanCheckboxInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1865
+ BooleanCheckboxInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: BooleanCheckboxInputComponent, selector: "boolean-checkbox-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-checkbox (ngModelChange)=\"emitChange()\" (click)=\"model.control.markAsTouched()\" [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\"></mat-checkbox>\n <!-- hidden input is needed so that the checkbox can be used inside a mat-form-field -->\n <input matInput hidden\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString() + 'Helper'\"\n #model=\"ngModel\"\n [pattern]=\"metadata.required ? 'true' : '[\\\\s\\\\S]*'\"\n [required]=\"metadata.required\">\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["::ng-deep .hideUnderline .mat-form-field-underline{opacity:0%}mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
1866
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BooleanCheckboxInputComponent, decorators: [{
1867
+ type: Component,
1868
+ args: [{ selector: 'boolean-checkbox-input', template: "<mat-form-field class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-checkbox (ngModelChange)=\"emitChange()\" (click)=\"model.control.markAsTouched()\" [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\"></mat-checkbox>\n <!-- hidden input is needed so that the checkbox can be used inside a mat-form-field -->\n <input matInput hidden\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString() + 'Helper'\"\n #model=\"ngModel\"\n [pattern]=\"metadata.required ? 'true' : '[\\\\s\\\\S]*'\"\n [required]=\"metadata.required\">\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["::ng-deep .hideUnderline .mat-form-field-underline{opacity:0%}mat-form-field{width:100%}\n"] }]
1869
+ }] });
1870
+
1871
+ /* eslint-disable jsdoc/require-jsdoc */
1872
+ class BooleanToggleInputComponent extends NgxMatEntityBaseInputComponent {
1873
+ ngOnInit() {
1874
+ super.ngOnInit();
1875
+ if (this.entity[this.key] == null) {
1876
+ this.entity[this.key] = false;
1877
+ }
1878
+ }
1879
+ }
1880
+ BooleanToggleInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BooleanToggleInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1881
+ BooleanToggleInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: BooleanToggleInputComponent, selector: "boolean-toggle-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-slide-toggle (click)=\"model.control.markAsTouched()\" [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\"></mat-slide-toggle>\n <!-- hidden input is needed so that the toggle can be used inside a mat-form-field -->\n <input matInput hidden\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString() + 'Helper'\"\n #model=\"ngModel\"\n [pattern]=\"metadata.required ? 'true' : '[\\\\s\\\\S]*'\"\n [required]=\"metadata.required\"\n (ngModelChange)=\"emitChange\"\n >\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["::ng-deep .hideUnderline .mat-form-field-underline{opacity:0%}mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex", "name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "checked"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
1882
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BooleanToggleInputComponent, decorators: [{
1883
+ type: Component,
1884
+ args: [{ selector: 'boolean-toggle-input', template: "<mat-form-field class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-slide-toggle (click)=\"model.control.markAsTouched()\" [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\"></mat-slide-toggle>\n <!-- hidden input is needed so that the toggle can be used inside a mat-form-field -->\n <input matInput hidden\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString() + 'Helper'\"\n #model=\"ngModel\"\n [pattern]=\"metadata.required ? 'true' : '[\\\\s\\\\S]*'\"\n [required]=\"metadata.required\"\n (ngModelChange)=\"emitChange\"\n >\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["::ng-deep .hideUnderline .mat-form-field-underline{opacity:0%}mat-form-field{width:100%}\n"] }]
1885
+ }] });
1886
+
1887
+ /* eslint-disable jsdoc/require-jsdoc */
1888
+ class BooleanDropdownInputComponent extends NgxMatEntityBaseInputComponent {
1889
+ }
1890
+ BooleanDropdownInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BooleanDropdownInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1891
+ BooleanDropdownInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: BooleanDropdownInputComponent, selector: "boolean-dropdown-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select (ngModelChange)=\"emitChange()\" [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\" #model=\"ngModel\" [required]=\"metadata.required\">\n <mat-option [value]=\"undefined\">-</mat-option>\n <mat-option [value]=\"true\">{{metadata.dropdownTrue}}</mat-option>\n <mat-option [value]=\"false\">{{metadata.dropdownFalse}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
1892
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BooleanDropdownInputComponent, decorators: [{
1893
+ type: Component,
1894
+ args: [{ selector: 'boolean-dropdown-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select (ngModelChange)=\"emitChange()\" [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\" #model=\"ngModel\" [required]=\"metadata.required\">\n <mat-option [value]=\"undefined\">-</mat-option>\n <mat-option [value]=\"true\">{{metadata.dropdownTrue}}</mat-option>\n <mat-option [value]=\"false\">{{metadata.dropdownFalse}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
1895
+ }] });
1896
+
1897
+ /* eslint-disable jsdoc/require-jsdoc */
1898
+ class NumberInputComponent extends NgxMatEntityBaseInputComponent {
1899
+ }
1900
+ NumberInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NumberInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1901
+ NumberInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NumberInputComponent, selector: "number-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n type=\"number\"\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ?? null\"\n [max]=\"metadata.max ?? null\"\n (ngModelChange)=\"emitChange()\"\n />\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i3$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i3$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i3$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
1902
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NumberInputComponent, decorators: [{
1903
+ type: Component,
1904
+ args: [{ selector: 'number-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n type=\"number\"\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ?? null\"\n [max]=\"metadata.max ?? null\"\n (ngModelChange)=\"emitChange()\"\n />\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
1905
+ }] });
1906
+
1907
+ /* eslint-disable jsdoc/require-jsdoc */
1908
+ class NumberDropdownInputComponent extends NgxMatEntityBaseInputComponent {
1909
+ }
1910
+ NumberDropdownInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NumberDropdownInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1911
+ NumberDropdownInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NumberDropdownInputComponent, selector: "number-dropdown-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select (ngModelChange)=\"emitChange()\" [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\" #model=\"ngModel\" [required]=\"metadata.required\">\n <mat-option *ngFor=\"let value of metadata.dropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
1912
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NumberDropdownInputComponent, decorators: [{
1913
+ type: Component,
1914
+ args: [{ selector: 'number-dropdown-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select (ngModelChange)=\"emitChange()\" [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\" #model=\"ngModel\" [required]=\"metadata.required\">\n <mat-option *ngFor=\"let value of metadata.dropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
1915
+ }] });
1916
+
1917
+ /**
1918
+ * The base data needed for all arrays that are displayed as a table.
1919
+ */
1920
+ class ArrayTableComponent extends NgxMatEntityBaseInputComponent {
1921
+ constructor(matDialog) {
1922
+ super();
1923
+ this.matDialog = matDialog;
1924
+ this.input = undefined;
1925
+ this.dataSource = new MatTableDataSource();
1926
+ this.selection = new SelectionModel(true, []);
1927
+ }
1928
+ ngOnInit() {
1929
+ super.ngOnInit();
1930
+ if (this.entity[this.key] == null) {
1931
+ this.entity[this.key] = [];
1932
+ }
1933
+ this.arrayValues = this.entity[this.key];
1934
+ const givenDisplayColumns = this.metadata.displayColumns.map((v) => v.displayName);
1935
+ if (givenDisplayColumns.find(s => s === 'select')) {
1936
+ throw new Error(`The name "select" for a display column is reserved.
1937
+ Please choose a different name.`);
1938
+ }
1939
+ this.displayedColumns = ['select'].concat(givenDisplayColumns);
1940
+ this.dataSource.data = this.arrayValues;
1941
+ }
1942
+ /**
1943
+ * Toggles all array-items in the table.
1944
+ *
1945
+ */
1946
+ masterToggle() {
1947
+ if (this.isAllSelected()) {
1948
+ this.selection.clear();
1949
+ }
1950
+ else {
1951
+ this.dataSource.data.forEach(row => this.selection.select(row));
1952
+ }
1953
+ }
1954
+ /**
1955
+ * Checks if all array-items in the table have been selected.
1956
+ * This is needed to display the "masterToggle"-checkbox correctly.
1957
+ *
1958
+ * @returns Whether or not all array-items in the table have been selected.
1959
+ */
1960
+ isAllSelected() {
1961
+ const numSelected = this.selection.selected.length;
1962
+ const numRows = this.dataSource.data.length;
1963
+ return numSelected === numRows;
1964
+ }
1965
+ /**
1966
+ * Tries to add an item to the array.
1967
+ */
1968
+ add() {
1969
+ if (this.input != null) {
1970
+ if (!this.metadata.allowDuplicates
1971
+ && this.arrayValues.find((v) => __awaiter(this, void 0, void 0, function* () { return yield EntityUtilities.isEqual(this.input, v, this.metadata, this.metadata.itemType); })) != null) {
1972
+ this.matDialog.open(NgxMatEntityConfirmDialogComponent, {
1973
+ data: this.metadata.duplicatesErrorDialog,
1974
+ autoFocus: false,
1975
+ restoreFocus: false
1976
+ });
1977
+ return;
1978
+ }
1979
+ this.arrayValues.push(LodashUtilities.cloneDeep(this.input));
1980
+ this.dataSource.data = this.arrayValues;
1981
+ this.resetInput();
1982
+ this.emitChange();
1983
+ }
1984
+ }
1985
+ /**
1986
+ * Is split up from the add method to override this functionality more easily.
1987
+ */
1988
+ resetInput() {
1989
+ this.input = undefined;
1990
+ }
1991
+ /**
1992
+ * Removes all selected entries from the entity array.
1993
+ */
1994
+ remove() {
1995
+ this.selection.selected.forEach(s => {
1996
+ this.arrayValues.splice(this.arrayValues.indexOf(s), 1);
1997
+ });
1998
+ this.dataSource.data = this.arrayValues;
1999
+ this.selection.clear();
2000
+ this.emitChange();
2001
+ }
2002
+ }
2003
+ ArrayTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayTableComponent, deps: [{ token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
2004
+ ArrayTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ArrayTableComponent, selector: "ngx-mat-entity-array-table", usesInheritance: true, ngImport: i0, template: '', isInline: true });
2005
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayTableComponent, decorators: [{
2006
+ type: Component,
2007
+ args: [{
2008
+ selector: 'ngx-mat-entity-array-table',
2009
+ template: ''
2010
+ }]
2011
+ }], ctorParameters: function () { return [{ type: i1.MatDialog }]; } });
2012
+
2013
+ /* eslint-disable jsdoc/require-jsdoc */
2014
+ class ArrayDateInputComponent extends ArrayTableComponent {
2015
+ constructor() {
2016
+ super(...arguments);
2017
+ this.DateUtilities = DateUtilities;
2018
+ }
2019
+ }
2020
+ ArrayDateInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayDateInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2021
+ ArrayDateInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ArrayDateInputComponent, selector: "array-date-input", usesInheritance: true, ngImport: i0, template: "<div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"input\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ? metadata.min(input) : undefined\"\n [max]=\"metadata.max ? metadata.max(input) : undefined\"\n [matDatepickerFilter]=\"metadata.filter ?? DateUtilities.defaultDateFilter\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n \n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"model.errors\"\n (click)=\"add()\">\n {{metadata.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadata.removeButtonLabel}}\n </button>\n </div>\n\n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadata.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <div class=\"array-error\" *ngIf=\"metadata.required && !dataSource.data.length\">\n {{metadata.missingErrorMessage}}\n </div>\n</div>", styles: ["mat-form-field{width:100%}.buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.mat-column-select{flex:0 0 75px}.array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i2$4.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i4$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i4$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2$4.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }, { type: i4$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i4$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i4$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i4$2.MatCellDef, selector: "[matCellDef]" }, { type: i4$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i4$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2022
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayDateInputComponent, decorators: [{
2023
+ type: Component,
2024
+ args: [{ selector: 'array-date-input', template: "<div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"input\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ? metadata.min(input) : undefined\"\n [max]=\"metadata.max ? metadata.max(input) : undefined\"\n [matDatepickerFilter]=\"metadata.filter ?? DateUtilities.defaultDateFilter\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n \n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"model.errors\"\n (click)=\"add()\">\n {{metadata.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadata.removeButtonLabel}}\n </button>\n </div>\n\n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadata.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <div class=\"array-error\" *ngIf=\"metadata.required && !dataSource.data.length\">\n {{metadata.missingErrorMessage}}\n </div>\n</div>", styles: ["mat-form-field{width:100%}.buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.mat-column-select{flex:0 0 75px}.array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"] }]
2025
+ }] });
2026
+
2027
+ /* eslint-disable jsdoc/require-jsdoc */
2028
+ class ArrayDateTimeInputComponent extends ArrayTableComponent {
2029
+ constructor() {
2030
+ super(...arguments);
2031
+ this.DateUtilities = DateUtilities;
2032
+ }
2033
+ ngOnInit() {
2034
+ super.ngOnInit();
2035
+ this.time = DateUtilities.getTimeFromDate(this.entity[this.key]);
2036
+ this.timeDropdownValues = this.metadata.times;
2037
+ if (this.entity[this.key] != null) {
2038
+ this.dateTime = new Date(this.entity[this.key]);
2039
+ }
2040
+ }
2041
+ resetInput() {
2042
+ this.input = undefined;
2043
+ this.time = undefined;
2044
+ }
2045
+ /**
2046
+ * Adds a date time to the array.
2047
+ */
2048
+ addDateTime() {
2049
+ if (this.input && this.time) {
2050
+ this.input = new Date(this.input);
2051
+ this.input.setHours(this.time.hours, this.time.minutes, 0, 0);
2052
+ this.add();
2053
+ }
2054
+ }
2055
+ }
2056
+ ArrayDateTimeInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayDateTimeInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2057
+ ArrayDateTimeInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ArrayDateTimeInputComponent, selector: "array-date-time-input", usesInheritance: true, ngImport: i0, template: "<div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n \n <div class=\"date-time\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"input\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minDate ? metadata.minDate(input) : undefined\"\n [max]=\"metadata.maxDate ? metadata.maxDate(input) : undefined\"\n [matDatepickerFilter]=\"metadata.filterDate ?? DateUtilities.defaultDateFilter\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n <mat-form-field class=\"timepicker\">\n <mat-label>{{metadata.timeDisplayName}}</mat-label>\n <mat-select\n [(ngModel)]=\"time\"\n [name]=\"key.toString() + 'time'\"\n #timeModel=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-option *ngFor=\"let validTime of DateUtilities.getValidTimesForDropdown(\n DateUtilities.asDate(input),\n metadata.times,\n metadata.minTime,\n metadata.maxTime,\n metadata.filterTime\n )\"\n [value]=\"validTime.value\"\n >\n {{validTime.displayName}}\n </mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(timeModel)}}</mat-error>\n </mat-form-field>\n </div>\n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"model.errors || timeModel.errors || DateUtilities.timeIsUnprocessable(time)\"\n (click)=\"addDateTime()\">\n {{metadata.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadata.removeButtonLabel}}\n </button>\n </div>\n\n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadata.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <div class=\"array-error\" *ngIf=\"metadata.required && !dataSource.data.length\">\n {{metadata.missingErrorMessage}}\n </div>\n</div>", styles: ["mat-form-field{width:100%}.buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.mat-column-select{flex:0 0 75px}.array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}.date-time{display:flex;align-items:baseline}.date-time .timepicker{margin-left:10px}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i2$4.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { type: i2$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i4$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i4$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2$4.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i4$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i4$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i4$2.MatCellDef, selector: "[matCellDef]" }, { type: i4$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i4$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i4$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2058
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayDateTimeInputComponent, decorators: [{
2059
+ type: Component,
2060
+ args: [{ selector: 'array-date-time-input', template: "<div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n \n <div class=\"date-time\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"input\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minDate ? metadata.minDate(input) : undefined\"\n [max]=\"metadata.maxDate ? metadata.maxDate(input) : undefined\"\n [matDatepickerFilter]=\"metadata.filterDate ?? DateUtilities.defaultDateFilter\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n <mat-form-field class=\"timepicker\">\n <mat-label>{{metadata.timeDisplayName}}</mat-label>\n <mat-select\n [(ngModel)]=\"time\"\n [name]=\"key.toString() + 'time'\"\n #timeModel=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-option *ngFor=\"let validTime of DateUtilities.getValidTimesForDropdown(\n DateUtilities.asDate(input),\n metadata.times,\n metadata.minTime,\n metadata.maxTime,\n metadata.filterTime\n )\"\n [value]=\"validTime.value\"\n >\n {{validTime.displayName}}\n </mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(timeModel)}}</mat-error>\n </mat-form-field>\n </div>\n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"model.errors || timeModel.errors || DateUtilities.timeIsUnprocessable(time)\"\n (click)=\"addDateTime()\">\n {{metadata.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadata.removeButtonLabel}}\n </button>\n </div>\n\n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadata.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <div class=\"array-error\" *ngIf=\"metadata.required && !dataSource.data.length\">\n {{metadata.missingErrorMessage}}\n </div>\n</div>", styles: ["mat-form-field{width:100%}.buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.mat-column-select{flex:0 0 75px}.array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}.date-time{display:flex;align-items:baseline}.date-time .timepicker{margin-left:10px}\n"] }]
2061
+ }] });
2062
+
2063
+ /* eslint-disable jsdoc/require-jsdoc */
2064
+ class ArrayDateRangeInputComponent extends ArrayTableComponent {
2065
+ constructor() {
2066
+ super(...arguments);
2067
+ this.DateUtilities = DateUtilities;
2068
+ }
2069
+ ngOnInit() {
2070
+ super.ngOnInit();
2071
+ this.input = {
2072
+ start: undefined,
2073
+ end: undefined,
2074
+ values: undefined
2075
+ };
2076
+ }
2077
+ /**
2078
+ * Adds a DateRange to the array.
2079
+ */
2080
+ addDateRange() {
2081
+ if (this.input && this.dateRangeStart && this.dateRangeEnd) {
2082
+ this.input.start = new Date(this.dateRangeStart);
2083
+ this.input.end = new Date(this.dateRangeEnd);
2084
+ const values = DateUtilities.getDatesBetween(this.input.start, this.input.end, this.metadata.filter);
2085
+ this.input.values = values.length ? values : undefined;
2086
+ this.add();
2087
+ }
2088
+ }
2089
+ resetInput() {
2090
+ this.input = undefined;
2091
+ this.dateRangeStart = undefined;
2092
+ this.dateRangeEnd = undefined;
2093
+ }
2094
+ }
2095
+ ArrayDateRangeInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayDateRangeInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2096
+ ArrayDateRangeInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ArrayDateRangeInputComponent, selector: "array-date-range-input", usesInheritance: true, ngImport: i0, template: "<div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n \n <mat-date-range-input [rangePicker]=\"picker\" [required]=\"metadata.required\" [dateFilter]=\"metadata.filter ? metadata.filter : DateUtilities.defaultDateFilter\">\n <input matStartDate\n [(ngModel)]=\"dateRangeStart\"\n [name]=\"key.toString() + 'start'\"\n #startModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minStart ? metadata.minStart(input?.start) : undefined\"\n [max]=\"metadata.maxStart ? metadata.maxStart(input?.start) : undefined\"\n [placeholder]=\"metadata.placeholderStart\"\n >\n <input matEndDate\n [(ngModel)]=\"dateRangeEnd\"\n [name]=\"key.toString() + 'end'\"\n #endModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minEnd ? metadata.minEnd(input?.end) : undefined\"\n [max]=\"metadata.maxEnd ? metadata.maxEnd(input?.end) : undefined\"\n [placeholder]=\"metadata.placeholderEnd\"\n >\n </mat-date-range-input>\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-date-range-picker #picker></mat-date-range-picker>\n\n <mat-error *ngIf=\"startModel.errors\">{{getValidationErrorMessage(startModel)}}</mat-error>\n <mat-error *ngIf=\"!startModel.errors && endModel.errors\">{{getValidationErrorMessage(endModel)}}</mat-error>\n </mat-form-field>\n \n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"startModel.errors || endModel.errors\"\n (click)=\"addDateRange()\">\n {{metadata.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadata.removeButtonLabel}}\n </button>\n </div>\n\n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadata.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <div class=\"array-error\" *ngIf=\"metadata.required && !dataSource.data.length\">\n {{metadata.missingErrorMessage}}\n </div>\n</div>", styles: ["mat-form-field{width:100%}.buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.mat-column-select{flex:0 0 75px}.array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$4.MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { type: i2$4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i2$4.MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i4$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i4$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i2$4.MatStartDate, selector: "input[matStartDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2$4.MatEndDate, selector: "input[matEndDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }, { type: i4$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i4$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i4$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i4$2.MatCellDef, selector: "[matCellDef]" }, { type: i4$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i4$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }] });
2097
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayDateRangeInputComponent, decorators: [{
2098
+ type: Component,
2099
+ args: [{ selector: 'array-date-range-input', template: "<div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n \n <mat-date-range-input [rangePicker]=\"picker\" [required]=\"metadata.required\" [dateFilter]=\"metadata.filter ? metadata.filter : DateUtilities.defaultDateFilter\">\n <input matStartDate\n [(ngModel)]=\"dateRangeStart\"\n [name]=\"key.toString() + 'start'\"\n #startModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minStart ? metadata.minStart(input?.start) : undefined\"\n [max]=\"metadata.maxStart ? metadata.maxStart(input?.start) : undefined\"\n [placeholder]=\"metadata.placeholderStart\"\n >\n <input matEndDate\n [(ngModel)]=\"dateRangeEnd\"\n [name]=\"key.toString() + 'end'\"\n #endModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minEnd ? metadata.minEnd(input?.end) : undefined\"\n [max]=\"metadata.maxEnd ? metadata.maxEnd(input?.end) : undefined\"\n [placeholder]=\"metadata.placeholderEnd\"\n >\n </mat-date-range-input>\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-date-range-picker #picker></mat-date-range-picker>\n\n <mat-error *ngIf=\"startModel.errors\">{{getValidationErrorMessage(startModel)}}</mat-error>\n <mat-error *ngIf=\"!startModel.errors && endModel.errors\">{{getValidationErrorMessage(endModel)}}</mat-error>\n </mat-form-field>\n \n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"startModel.errors || endModel.errors\"\n (click)=\"addDateRange()\">\n {{metadata.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadata.removeButtonLabel}}\n </button>\n </div>\n\n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadata.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <div class=\"array-error\" *ngIf=\"metadata.required && !dataSource.data.length\">\n {{metadata.missingErrorMessage}}\n </div>\n</div>", styles: ["mat-form-field{width:100%}.buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.mat-column-select{flex:0 0 75px}.array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"] }]
2100
+ }] });
2101
+
2102
+ /* eslint-disable jsdoc/require-jsdoc */
2103
+ class ArrayStringChipsInputComponent extends NgxMatEntityBaseInputComponent {
2104
+ constructor() {
2105
+ super(...arguments);
2106
+ this.chipsInput = '';
2107
+ }
2108
+ ngOnInit() {
2109
+ var _a;
2110
+ super.ngOnInit();
2111
+ if ((_a = this.entity[this.key]) === null || _a === void 0 ? void 0 : _a.length) {
2112
+ this.stringChipsArrayValues = this.entity[this.key];
2113
+ }
2114
+ }
2115
+ /**
2116
+ * Handles adding strings to the chipsArray.
2117
+ * Checks validation and also creates a new array if it is undefined.
2118
+ * This is needed because two things are validated: The array itself
2119
+ * and the contents of the array. And we need a way to display an
2120
+ * mat-error. As the only validation for the array is whether or not
2121
+ * it contains values, we can set it to undefined when the last element is removed
2122
+ * (removeStringChipArrayValue). That way we can use the "required" validator.
2123
+ *
2124
+ * @param event - The event that fires when a new chip is completed.
2125
+ */
2126
+ addStringChipArrayValue(event) {
2127
+ var _a;
2128
+ const value = (event.value || '').trim();
2129
+ if (value) {
2130
+ if (this.metadata.minLength && value.length < this.metadata.minLength) {
2131
+ return;
2132
+ }
2133
+ if (this.metadata.maxLength && value.length > this.metadata.maxLength) {
2134
+ return;
2135
+ }
2136
+ if (this.metadata.regex && !value.match(this.metadata.regex)) {
2137
+ return;
2138
+ }
2139
+ if (!this.stringChipsArrayValues) {
2140
+ if (this.entity[this.key] == null) {
2141
+ this.entity[this.key] = [];
2142
+ }
2143
+ this.stringChipsArrayValues = this.entity[this.key];
2144
+ }
2145
+ this.stringChipsArrayValues.push(value);
2146
+ }
2147
+ (_a = event.chipInput) === null || _a === void 0 ? void 0 : _a.clear();
2148
+ }
2149
+ /**
2150
+ * Removes the given value from the array.
2151
+ * Sets the array to undefined if it is now empty.
2152
+ * This is needed because two things are validated: The array itself
2153
+ * and the contents of the array. And we need a way to display an
2154
+ * mat-error. As the only validation for the array is whether or not
2155
+ * it is empty, setting it to undefined here enables us to use the "required" validator.
2156
+ *
2157
+ * @param value - The string to remove from the array.
2158
+ */
2159
+ removeStringChipArrayValue(value) {
2160
+ var _a, _b;
2161
+ (_a = this.stringChipsArrayValues) === null || _a === void 0 ? void 0 : _a.splice(this.stringChipsArrayValues.indexOf(value), 1);
2162
+ if (!((_b = this.stringChipsArrayValues) === null || _b === void 0 ? void 0 : _b.length)) {
2163
+ this.entity[this.key] = undefined;
2164
+ this.stringChipsArrayValues = this.entity[this.key];
2165
+ }
2166
+ }
2167
+ /**
2168
+ * Handles adding a string to the array when an autocomplete value has been selected.
2169
+ *
2170
+ * @param event - The autocomplete selected event.
2171
+ * @param chipsInput - The element where the user typed the value.
2172
+ */
2173
+ selected(event, chipsInput) {
2174
+ const value = (event.option.viewValue || '').trim();
2175
+ if (this.metadata.minLength && value.length < this.metadata.minLength) {
2176
+ return;
2177
+ }
2178
+ if (this.metadata.maxLength && value.length > this.metadata.maxLength) {
2179
+ return;
2180
+ }
2181
+ if (this.metadata.regex && !value.match(this.metadata.regex)) {
2182
+ return;
2183
+ }
2184
+ if (!this.stringChipsArrayValues) {
2185
+ if (this.entity[this.key] == null) {
2186
+ this.entity[this.key] = [];
2187
+ }
2188
+ this.stringChipsArrayValues = this.entity[this.key];
2189
+ }
2190
+ this.stringChipsArrayValues.push(value);
2191
+ chipsInput.value = '';
2192
+ }
2193
+ }
2194
+ ArrayStringChipsInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayStringChipsInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2195
+ ArrayStringChipsInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ArrayStringChipsInputComponent, selector: "array-string-chips-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n (ngModelChange)=\"emitChange()\"\n [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip *ngFor=\"let value of stringChipsArrayValues\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input matInput\n [matChipInputFor]=\"chipList\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addStringChipArrayValue($event)\"\n [(ngModel)]=\"chipsInput\" [name]=\"key.toString()\" #chipsModel=\"ngModel\"\n [minlength]='metadata.minLength ?? null'\n [maxlength]='metadata.maxLength ?? null'\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n >\n <mat-error *ngIf=\"chipsModel.errors\">{{getValidationErrorMessage(chipsModel)}}</mat-error>\n </mat-chip-list>\n <mat-error *ngIf=\"!chipsModel.errors\">{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$5.MatChipList, selector: "mat-chip-list", inputs: ["errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2$5.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { type: i2$5.MatChipRemove, selector: "[matChipRemove]" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i2$5.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i3$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i3$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
2196
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayStringChipsInputComponent, decorators: [{
2197
+ type: Component,
2198
+ args: [{ selector: 'array-string-chips-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n (ngModelChange)=\"emitChange()\"\n [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip *ngFor=\"let value of stringChipsArrayValues\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input matInput\n [matChipInputFor]=\"chipList\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addStringChipArrayValue($event)\"\n [(ngModel)]=\"chipsInput\" [name]=\"key.toString()\" #chipsModel=\"ngModel\"\n [minlength]='metadata.minLength ?? null'\n [maxlength]='metadata.maxLength ?? null'\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n >\n <mat-error *ngIf=\"chipsModel.errors\">{{getValidationErrorMessage(chipsModel)}}</mat-error>\n </mat-chip-list>\n <mat-error *ngIf=\"!chipsModel.errors\">{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
2199
+ }] });
2200
+
2201
+ /* eslint-disable jsdoc/require-jsdoc */
2202
+ class ArrayStringAutocompleteChipsComponent extends NgxMatEntityBaseInputComponent {
2203
+ constructor() {
2204
+ super(...arguments);
2205
+ this.chipsInput = '';
2206
+ }
2207
+ ngOnInit() {
2208
+ var _a;
2209
+ super.ngOnInit();
2210
+ this.filteredAutocompleteStrings = LodashUtilities.cloneDeep(this.metadata.autocompleteValues);
2211
+ if ((_a = this.entity[this.key]) === null || _a === void 0 ? void 0 : _a.length) {
2212
+ this.stringChipsArrayValues = this.entity[this.key];
2213
+ }
2214
+ }
2215
+ /**
2216
+ * Handles adding strings to the chipsArray.
2217
+ * Checks validation and also creates a new array if it is undefined.
2218
+ * This is needed because two things are validated: The array itself
2219
+ * and the contents of the array. And we need a way to display an
2220
+ * mat-error. As the only validation for the array is whether or not
2221
+ * it contains values, we can set it to undefined when the last element is removed
2222
+ * (removeStringChipArrayValue). That way we can use the "required" validator.
2223
+ *
2224
+ * @param event - The event that fires when a new chip is completed.
2225
+ */
2226
+ addStringChipArrayValue(event) {
2227
+ var _a;
2228
+ const value = (event.value || '').trim();
2229
+ if (value) {
2230
+ if (this.metadata.minLength && value.length < this.metadata.minLength) {
2231
+ return;
2232
+ }
2233
+ if (this.metadata.maxLength && value.length > this.metadata.maxLength) {
2234
+ return;
2235
+ }
2236
+ if (this.metadata.regex && !value.match(this.metadata.regex)) {
2237
+ return;
2238
+ }
2239
+ if (!this.stringChipsArrayValues) {
2240
+ if (this.entity[this.key] == null) {
2241
+ this.entity[this.key] = [];
2242
+ }
2243
+ this.stringChipsArrayValues = this.entity[this.key];
2244
+ }
2245
+ this.stringChipsArrayValues.push(value);
2246
+ }
2247
+ (_a = event.chipInput) === null || _a === void 0 ? void 0 : _a.clear();
2248
+ }
2249
+ /**
2250
+ * Removes the given value from the array.
2251
+ * Sets the array to undefined if it is now empty.
2252
+ * This is needed because two things are validated: The array itself
2253
+ * and the contents of the array. And we need a way to display an
2254
+ * mat-error. As the only validation for the array is whether or not
2255
+ * it is empty, setting it to undefined here enables us to use the "required" validator.
2256
+ *
2257
+ * @param value - The string to remove from the array.
2258
+ */
2259
+ removeStringChipArrayValue(value) {
2260
+ var _a, _b;
2261
+ (_a = this.stringChipsArrayValues) === null || _a === void 0 ? void 0 : _a.splice(this.stringChipsArrayValues.indexOf(value), 1);
2262
+ if (!((_b = this.stringChipsArrayValues) === null || _b === void 0 ? void 0 : _b.length)) {
2263
+ this.entity[this.key] = undefined;
2264
+ this.stringChipsArrayValues = this.entity[this.key];
2265
+ }
2266
+ }
2267
+ /**
2268
+ * Handles adding a string to the array when an autocomplete value has been selected.
2269
+ *
2270
+ * @param event - The autocomplete selected event.
2271
+ * @param chipsInput - The element where the user typed the value.
2272
+ */
2273
+ selected(event, chipsInput) {
2274
+ const value = (event.option.viewValue || '').trim();
2275
+ if (this.metadata.minLength && value.length < this.metadata.minLength) {
2276
+ return;
2277
+ }
2278
+ if (this.metadata.maxLength && value.length > this.metadata.maxLength) {
2279
+ return;
941
2280
  }
942
- this.metadataEntityArray = this.metadata;
943
- if (this.type === DecoratorTypes.ARRAY) {
944
- if (!this.entity[this.propertyKey]) {
945
- this.entity[this.propertyKey] = [];
2281
+ if (this.metadata.regex && !value.match(this.metadata.regex)) {
2282
+ return;
2283
+ }
2284
+ if (!this.stringChipsArrayValues) {
2285
+ if (this.entity[this.key] == null) {
2286
+ this.entity[this.key] = [];
2287
+ }
2288
+ this.stringChipsArrayValues = this.entity[this.key];
2289
+ }
2290
+ this.stringChipsArrayValues.push(value);
2291
+ chipsInput.value = '';
2292
+ }
2293
+ /**
2294
+ * Dynamically filters the Autocomplete options when the user inputs something.
2295
+ *
2296
+ * @param input - The input of the user.
2297
+ */
2298
+ filterAutocompleteStrings(input) {
2299
+ if (input != null) {
2300
+ const filterValue = input.toLowerCase();
2301
+ this.filteredAutocompleteStrings = this.metadata.autocompleteValues.filter(s => s.toLowerCase().includes(filterValue));
2302
+ }
2303
+ }
2304
+ }
2305
+ ArrayStringAutocompleteChipsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayStringAutocompleteChipsComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2306
+ ArrayStringAutocompleteChipsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ArrayStringAutocompleteChipsComponent, selector: "array-string-autocomplete-chips", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n (ngModelChange)=\"emitChange()\"\n [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip *ngFor=\"let value of stringChipsArrayValues\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input matInput\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addStringChipArrayValue($event)\"\n (keyup)=\"filterAutocompleteStrings(chipsInput)\"\n [(ngModel)]=\"chipsInput\" [name]=\"key.toString()\" #chipsModel=\"ngModel\"\n #chipsElement\n [minlength]='metadata.minLength ?? null'\n [maxlength]='metadata.maxLength ?? null'\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n >\n <mat-error *ngIf=\"chipsModel.errors\">{{getValidationErrorMessage(chipsModel)}}</mat-error>\n </mat-chip-list>\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event, chipsElement)\">\n <mat-option *ngFor=\"let value of metadata.autocompleteValues\" [value]=\"value\">\n {{value}}\n </mat-option>\n </mat-autocomplete>\n <mat-error *ngIf=\"!chipsModel.errors\">{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$5.MatChipList, selector: "mat-chip-list", inputs: ["errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { type: i2$1.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { type: i3$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2$5.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { type: i2$5.MatChipRemove, selector: "[matChipRemove]" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i2$5.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { type: i2$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i3$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i3$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
2307
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayStringAutocompleteChipsComponent, decorators: [{
2308
+ type: Component,
2309
+ args: [{ selector: 'array-string-autocomplete-chips', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n (ngModelChange)=\"emitChange()\"\n [(ngModel)]=\"entity[key]\" [name]=\"key.toString()\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip *ngFor=\"let value of stringChipsArrayValues\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input matInput\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addStringChipArrayValue($event)\"\n (keyup)=\"filterAutocompleteStrings(chipsInput)\"\n [(ngModel)]=\"chipsInput\" [name]=\"key.toString()\" #chipsModel=\"ngModel\"\n #chipsElement\n [minlength]='metadata.minLength ?? null'\n [maxlength]='metadata.maxLength ?? null'\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n >\n <mat-error *ngIf=\"chipsModel.errors\">{{getValidationErrorMessage(chipsModel)}}</mat-error>\n </mat-chip-list>\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event, chipsElement)\">\n <mat-option *ngFor=\"let value of metadata.autocompleteValues\" [value]=\"value\">\n {{value}}\n </mat-option>\n </mat-autocomplete>\n <mat-error *ngIf=\"!chipsModel.errors\">{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
2310
+ }] });
2311
+
2312
+ /* eslint-disable jsdoc/require-jsdoc */
2313
+ class DateInputComponent extends NgxMatEntityBaseInputComponent {
2314
+ constructor() {
2315
+ super(...arguments);
2316
+ this.DateUtilities = DateUtilities;
2317
+ this.defaultDateFilter = () => true;
2318
+ }
2319
+ }
2320
+ DateInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2321
+ DateInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: DateInputComponent, selector: "date-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n (ngModelChange)=\"emitChange()\"\n matInput\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ? metadata.min(DateUtilities.asDate(entity[key])) : undefined\"\n [max]=\"metadata.max ? metadata.max(DateUtilities.asDate(entity[key])) : undefined\"\n [matDatepickerFilter]=\"metadata.filter ?? defaultDateFilter\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i2$4.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2$4.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
2322
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateInputComponent, decorators: [{
2323
+ type: Component,
2324
+ args: [{ selector: 'date-input', template: "<mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n (ngModelChange)=\"emitChange()\"\n matInput\n [(ngModel)]=\"entity[key]\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ? metadata.min(DateUtilities.asDate(entity[key])) : undefined\"\n [max]=\"metadata.max ? metadata.max(DateUtilities.asDate(entity[key])) : undefined\"\n [matDatepickerFilter]=\"metadata.filter ?? defaultDateFilter\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
2325
+ }] });
2326
+
2327
+ /* eslint-disable jsdoc/require-jsdoc */
2328
+ const EMPTY_DATERANGE = {
2329
+ start: undefined,
2330
+ end: undefined,
2331
+ values: undefined
2332
+ };
2333
+ class DateRangeInputComponent extends NgxMatEntityBaseInputComponent {
2334
+ constructor() {
2335
+ super(...arguments);
2336
+ this.defaultDateFilter = () => true;
2337
+ }
2338
+ ngOnInit() {
2339
+ var _a;
2340
+ super.ngOnInit();
2341
+ this.dateRange = (_a = LodashUtilities.cloneDeep(this.entity[this.key])) !== null && _a !== void 0 ? _a : EMPTY_DATERANGE;
2342
+ this.dateRangeStart = new Date(this.dateRange.start);
2343
+ this.dateRangeEnd = new Date(this.dateRange.end);
2344
+ this.setDateRangeValues();
2345
+ }
2346
+ /**
2347
+ * Updates the date range values based on the start and end date.
2348
+ */
2349
+ setDateRangeValues() {
2350
+ if (this.dateRangeStart && this.dateRangeEnd) {
2351
+ this.dateRange.start = new Date(this.dateRangeStart);
2352
+ this.dateRange.end = new Date(this.dateRangeEnd);
2353
+ const values = DateUtilities.getDatesBetween(new Date(this.dateRange.start), new Date(this.dateRange.end), this.metadata.filter);
2354
+ this.dateRange.values = values.length ? values : undefined;
2355
+ }
2356
+ else {
2357
+ this.dateRange.values = undefined;
2358
+ }
2359
+ this.entity[this.key] = this.dateRange;
2360
+ this.emitChange();
2361
+ }
2362
+ }
2363
+ DateRangeInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateRangeInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2364
+ DateRangeInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: DateRangeInputComponent, selector: "date-range-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n \n <mat-date-range-input [rangePicker]=\"picker\" [required]=\"metadata.required\" [dateFilter]=\"metadata.filter ?? defaultDateFilter\">\n <input matStartDate\n [(ngModel)]=\"dateRangeStart\"\n [name]=\"key.toString() + 'start'\"\n #startModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minStart ? metadata.minStart(dateRange.start) : undefined\"\n [max]=\"metadata.maxStart ? metadata.maxStart(dateRange.start) : undefined\"\n [placeholder]=\"metadata.placeholderStart\"\n (ngModelChange)=\"setDateRangeValues()\"\n >\n <input matEndDate\n [(ngModel)]=\"dateRangeEnd\"\n [name]=\"key.toString() + 'end'\"\n #endModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minEnd ? metadata.minEnd(dateRange.end) : undefined\"\n [max]=\"metadata.maxEnd ? metadata.maxEnd(dateRange.end) : undefined\"\n [placeholder]=\"metadata.placeholderEnd\"\n (ngModelChange)=\"setDateRangeValues()\"\n >\n </mat-date-range-input>\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-date-range-picker #picker></mat-date-range-picker>\n\n <mat-error *ngIf=\"startModel.errors\">{{getValidationErrorMessage(startModel)}}</mat-error>\n <mat-error *ngIf=\"!startModel.errors && endModel.errors\">{{getValidationErrorMessage(endModel)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$4.MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { type: i2$4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i2$4.MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i2$4.MatStartDate, selector: "input[matStartDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2$4.MatEndDate, selector: "input[matEndDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
2365
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateRangeInputComponent, decorators: [{
2366
+ type: Component,
2367
+ args: [{ selector: 'date-range-input', template: "<mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n \n <mat-date-range-input [rangePicker]=\"picker\" [required]=\"metadata.required\" [dateFilter]=\"metadata.filter ?? defaultDateFilter\">\n <input matStartDate\n [(ngModel)]=\"dateRangeStart\"\n [name]=\"key.toString() + 'start'\"\n #startModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minStart ? metadata.minStart(dateRange.start) : undefined\"\n [max]=\"metadata.maxStart ? metadata.maxStart(dateRange.start) : undefined\"\n [placeholder]=\"metadata.placeholderStart\"\n (ngModelChange)=\"setDateRangeValues()\"\n >\n <input matEndDate\n [(ngModel)]=\"dateRangeEnd\"\n [name]=\"key.toString() + 'end'\"\n #endModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minEnd ? metadata.minEnd(dateRange.end) : undefined\"\n [max]=\"metadata.maxEnd ? metadata.maxEnd(dateRange.end) : undefined\"\n [placeholder]=\"metadata.placeholderEnd\"\n (ngModelChange)=\"setDateRangeValues()\"\n >\n </mat-date-range-input>\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-date-range-picker #picker></mat-date-range-picker>\n\n <mat-error *ngIf=\"startModel.errors\">{{getValidationErrorMessage(startModel)}}</mat-error>\n <mat-error *ngIf=\"!startModel.errors && endModel.errors\">{{getValidationErrorMessage(endModel)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
2368
+ }] });
2369
+
2370
+ /* eslint-disable jsdoc/require-jsdoc */
2371
+ class DateTimeInputComponent extends NgxMatEntityBaseInputComponent {
2372
+ constructor() {
2373
+ super(...arguments);
2374
+ this.DateUtilities = DateUtilities;
2375
+ this.defaultDateFilter = () => true;
2376
+ }
2377
+ ngOnInit() {
2378
+ super.ngOnInit();
2379
+ this.time = DateUtilities.getTimeFromDate(this.entity[this.key]);
2380
+ this.timeDropdownValues = this.metadata.times;
2381
+ if (this.entity[this.key] != null) {
2382
+ this.dateTime = new Date(this.entity[this.key]);
2383
+ }
2384
+ }
2385
+ /**
2386
+ * Checks if two times are equal. Is needed for the dropdown.
2387
+ *
2388
+ * @param time1 - The first time to compare.
2389
+ * @param time2 - The second time to compare.
2390
+ * @returns Whether or not the time objects are the same.
2391
+ */
2392
+ compareTimes(time1, time2) {
2393
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
2394
+ return time1 && time2 && time1.hours === time2.hours && time1.minutes === time2.minutes;
2395
+ }
2396
+ /**
2397
+ * Sets the time on a datetime property.
2398
+ */
2399
+ setTime() {
2400
+ var _a, _b;
2401
+ if (!this.dateTime) {
2402
+ this.entity[this.key] = undefined;
2403
+ this.emitChange();
2404
+ return;
2405
+ }
2406
+ this.entity[this.key] = new Date(this.dateTime);
2407
+ if (((_a = this.time) === null || _a === void 0 ? void 0 : _a.hours) != null && ((_b = this.time) === null || _b === void 0 ? void 0 : _b.minutes) != null) {
2408
+ this.entity[this.key].setHours(this.time.hours, this.time.minutes, 0, 0);
2409
+ }
2410
+ else {
2411
+ this.entity[this.key].setHours(0, 0, 0, 0);
2412
+ }
2413
+ this.emitChange();
2414
+ }
2415
+ }
2416
+ DateTimeInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateTimeInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2417
+ DateTimeInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: DateTimeInputComponent, selector: "date-time-input", usesInheritance: true, ngImport: i0, template: "<div class=\"date-time\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"dateTime\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minDate ? metadata.minDate(dateTime) : undefined\"\n [max]=\"metadata.maxDate ? metadata.maxDate(dateTime) : undefined\"\n [matDatepickerFilter]=\"metadata.filterDate ?? defaultDateFilter\"\n (dateInput)=\"setTime()\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n <mat-form-field class=\"timepicker\">\n <mat-label>{{metadata.timeDisplayName}}</mat-label>\n <mat-select\n [(ngModel)]=\"time\"\n [name]=\"key.toString() + 'time'\"\n #timeModel=\"ngModel\"\n [required]=\"metadata.required\"\n [compareWith]=\"compareTimes\"\n (ngModelChange)=\"setTime()\"\n >\n <mat-option *ngFor=\"let validTime of DateUtilities.getValidTimesForDropdown(\n DateUtilities.asDate(entity[key]),\n metadata.times,\n metadata.minTime,\n metadata.maxTime,\n metadata.filterTime\n )\"\n [value]=\"validTime.value\"\n >\n {{validTime.displayName}}\n </mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(timeModel)}}</mat-error>\n </mat-form-field>\n</div>", styles: ["mat-form-field{width:100%}.date-time{display:flex;align-items:baseline}.date-time .timepicker{margin-left:10px}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i2$4.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { type: i2$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2$4.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
2418
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateTimeInputComponent, decorators: [{
2419
+ type: Component,
2420
+ args: [{ selector: 'date-time-input', template: "<div class=\"date-time\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"dateTime\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minDate ? metadata.minDate(dateTime) : undefined\"\n [max]=\"metadata.maxDate ? metadata.maxDate(dateTime) : undefined\"\n [matDatepickerFilter]=\"metadata.filterDate ?? defaultDateFilter\"\n (dateInput)=\"setTime()\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n <mat-form-field class=\"timepicker\">\n <mat-label>{{metadata.timeDisplayName}}</mat-label>\n <mat-select\n [(ngModel)]=\"time\"\n [name]=\"key.toString() + 'time'\"\n #timeModel=\"ngModel\"\n [required]=\"metadata.required\"\n [compareWith]=\"compareTimes\"\n (ngModelChange)=\"setTime()\"\n >\n <mat-option *ngFor=\"let validTime of DateUtilities.getValidTimesForDropdown(\n DateUtilities.asDate(entity[key]),\n metadata.times,\n metadata.minTime,\n metadata.maxTime,\n metadata.filterTime\n )\"\n [value]=\"validTime.value\"\n >\n {{validTime.displayName}}\n </mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(timeModel)}}</mat-error>\n </mat-form-field>\n</div>", styles: ["mat-form-field{width:100%}.date-time{display:flex;align-items:baseline}.date-time .timepicker{margin-left:10px}\n"] }]
2421
+ }] });
2422
+
2423
+ /**
2424
+ * Adds drag and drop functionality to an element.
2425
+ */
2426
+ class DragDropDirective {
2427
+ constructor() {
2428
+ /**
2429
+ * Emits the dropped files to the parent.
2430
+ */
2431
+ this.files = new EventEmitter();
2432
+ }
2433
+ /**
2434
+ * Prevents the event default.
2435
+ *
2436
+ * @param evt - The Event when dragged files hover over the parent.
2437
+ */
2438
+ onDragOver(evt) {
2439
+ evt.preventDefault();
2440
+ evt.stopPropagation();
2441
+ }
2442
+ /**
2443
+ * Prevents the event default.
2444
+ *
2445
+ * @param evt - The Event when dragged files leave the parent.
2446
+ */
2447
+ onDragLeave(evt) {
2448
+ evt.preventDefault();
2449
+ evt.stopPropagation();
2450
+ }
2451
+ /**
2452
+ * Prevents the event default and emits the dropped files with the output.
2453
+ *
2454
+ * @param evt - The Event when files are dropped.
2455
+ */
2456
+ onDrop(evt) {
2457
+ evt.preventDefault();
2458
+ evt.stopPropagation();
2459
+ if (evt.dataTransfer && evt.dataTransfer.files.length > 0) {
2460
+ this.files.emit(Array.from(evt.dataTransfer.files));
2461
+ }
2462
+ }
2463
+ }
2464
+ DragDropDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DragDropDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2465
+ DragDropDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: DragDropDirective, selector: "[dragDrop]", outputs: { files: "files" }, host: { listeners: { "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "drop": "onDrop($event)" } }, ngImport: i0 });
2466
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DragDropDirective, decorators: [{
2467
+ type: Directive,
2468
+ args: [{
2469
+ // eslint-disable-next-line @angular-eslint/directive-selector
2470
+ selector: '[dragDrop]'
2471
+ }]
2472
+ }], ctorParameters: function () { return []; }, propDecorators: { files: [{
2473
+ type: Output
2474
+ }], onDragOver: [{
2475
+ type: HostListener,
2476
+ args: ['dragover', ['$event']]
2477
+ }], onDragLeave: [{
2478
+ type: HostListener,
2479
+ args: ['dragleave', ['$event']]
2480
+ }], onDrop: [{
2481
+ type: HostListener,
2482
+ args: ['drop', ['$event']]
2483
+ }] } });
2484
+
2485
+ class FileInputComponent {
2486
+ constructor(dialog) {
2487
+ this.dialog = dialog;
2488
+ this.FileUtilities = FileUtilities;
2489
+ this.fileDataChangeEvent = new EventEmitter();
2490
+ }
2491
+ ngOnInit() {
2492
+ var _a;
2493
+ return __awaiter(this, void 0, void 0, function* () {
2494
+ this.metadata = EntityUtilities.getPropertyMetadata(this.entity, this.key, DecoratorTypes.FILE_DEFAULT);
2495
+ if (this.metadata.multiple) {
2496
+ this.initMultiFile();
946
2497
  }
947
- this.entityArrayValues = this.entity[this.propertyKey];
948
- if (this.metadataEntityArray.createInline === undefined) {
949
- this.metadataEntityArray.createInline = true;
2498
+ else {
2499
+ this.initSingleFile();
950
2500
  }
951
- if (!this.metadataEntityArray.createInline && !this.metadataEntityArray.createDialogData) {
952
- this.metadataEntityArray.createDialogData = {
953
- title: 'Add'
954
- };
2501
+ this.fileDataChangeEvent.emit((_a = this.singleFileData) !== null && _a !== void 0 ? _a : this.multiFileData);
2502
+ });
2503
+ }
2504
+ initMultiFile() {
2505
+ this.multiFileData = this.entity[this.key];
2506
+ if (this.multiFileData) {
2507
+ this.filenames = this.multiFileData.map(f => f.name);
2508
+ }
2509
+ }
2510
+ initSingleFile() {
2511
+ this.singleFileData = this.entity[this.key];
2512
+ if (this.singleFileData) {
2513
+ this.filenames = LodashUtilities.cloneDeep([this.singleFileData.name]);
2514
+ }
2515
+ }
2516
+ setFileFromInput(event) {
2517
+ var _a;
2518
+ return __awaiter(this, void 0, void 0, function* () {
2519
+ const files = (_a = event.target.files) !== null && _a !== void 0 ? _a : [];
2520
+ yield this.setFile(Array.from(files));
2521
+ });
2522
+ }
2523
+ setFile(files) {
2524
+ var _a;
2525
+ return __awaiter(this, void 0, void 0, function* () {
2526
+ // validation done inline
2527
+ if (files.find(f => !FileUtilities.isMimeTypeValid(f.type, this.metadata.allowedMimeTypes))) {
2528
+ this.dialog.open(NgxMatEntityConfirmDialogComponent, {
2529
+ data: this.metadata.mimeTypeErrorDialog,
2530
+ autoFocus: false,
2531
+ restoreFocus: false
2532
+ });
2533
+ this.resetFileInputs();
2534
+ return;
955
2535
  }
956
- // TODO
957
- const givenDisplayColumns = this.metadataEntityArray.displayColumns.map((v) => v.displayName);
958
- if (givenDisplayColumns.find((s) => s === 'select')) {
959
- throw new Error(`The name "select" for a display column is reserved.
960
- Please choose a different name.`);
2536
+ if (files.find(f => f.size > (this.metadata.maxSize * 1000000))) {
2537
+ this.dialog.open(NgxMatEntityConfirmDialogComponent, {
2538
+ data: this.metadata.maxSizeErrorDialog,
2539
+ autoFocus: false,
2540
+ restoreFocus: false
2541
+ });
2542
+ this.resetFileInputs();
2543
+ return;
961
2544
  }
962
- this.displayedColumns = ['select'].concat(givenDisplayColumns);
963
- this.dataSource = new MatTableDataSource();
964
- this.dataSource.data = this.entityArrayValues;
965
- this.arrayItem = new this.metadataEntityArray.EntityClass();
966
- this.arrayItemInlineRows = EntityUtilities.getEntityRows(this.arrayItem, this.hideOmitForCreate === false ? false : true, this.hideOmitForEdit ? true : false);
967
- this.arrayItemPriorChanges = cloneDeep(this.arrayItem);
968
- this.dialogInputData = {
969
- entity: this.arrayItem,
970
- createDialogData: this.metadataEntityArray.createDialogData,
971
- getValidationErrorMessage: this.getValidationErrorMessage
2545
+ let fileSizeTotal = 0;
2546
+ for (const file of files) {
2547
+ fileSizeTotal += file.size;
2548
+ }
2549
+ if (fileSizeTotal > (this.metadata.maxSizeTotal * 1000000)) {
2550
+ this.dialog.open(NgxMatEntityConfirmDialogComponent, {
2551
+ data: this.metadata.maxSizeTotalErrorDialog,
2552
+ autoFocus: false,
2553
+ restoreFocus: false
2554
+ });
2555
+ this.resetFileInputs();
2556
+ return;
2557
+ }
2558
+ if (this.metadata.multiple) {
2559
+ yield this.setMultiFile(Array.from(files));
2560
+ }
2561
+ else {
2562
+ yield this.setSingleFile(files[0]);
2563
+ }
2564
+ this.fileDataChangeEvent.emit((_a = this.singleFileData) !== null && _a !== void 0 ? _a : this.multiFileData);
2565
+ });
2566
+ }
2567
+ resetFileInputs() {
2568
+ this.filenames = undefined;
2569
+ this.singleFileData = undefined;
2570
+ this.multiFileData = undefined;
2571
+ this.fileDataChangeEvent.emit();
2572
+ }
2573
+ setMultiFile(files) {
2574
+ return __awaiter(this, void 0, void 0, function* () {
2575
+ const data = [];
2576
+ for (const file of files) {
2577
+ const fileData = {
2578
+ file: file,
2579
+ name: file.name,
2580
+ type: file.type,
2581
+ size: file.size
2582
+ };
2583
+ data.push(fileData);
2584
+ }
2585
+ this.multiFileData = LodashUtilities.cloneDeep(data);
2586
+ this.filenames = this.multiFileData.map(f => f.name);
2587
+ });
2588
+ }
2589
+ setSingleFile(file) {
2590
+ return __awaiter(this, void 0, void 0, function* () {
2591
+ this.singleFileData = {
2592
+ file: file,
2593
+ name: file.name,
2594
+ type: file.type,
2595
+ size: file.size
972
2596
  };
973
- this.dialogData = new AddArrayItemDialogDataBuilder(this.dialogInputData).getResult();
974
- this.arrayItemDialogRows = EntityUtilities.getEntityRows(this.dialogData.entity, true);
975
- }
976
- this.metadataStringChipsArray = this.metadata;
977
- if ((this.type === DecoratorTypes.ARRAY_STRING_CHIPS || this.type === DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS)
978
- && ((_a = this.entity[this.propertyKey]) === null || _a === void 0 ? void 0 : _a.length)) {
979
- this.stringChipsArrayValues = this.entity[this.propertyKey];
2597
+ this.filenames = LodashUtilities.cloneDeep([this.singleFileData.name]);
2598
+ });
2599
+ }
2600
+ removeFile(name) {
2601
+ var _a, _b, _c, _d, _e, _f;
2602
+ if (this.metadata.multiple) {
2603
+ (_a = this.filenames) === null || _a === void 0 ? void 0 : _a.splice(this.filenames.indexOf(name), 1);
2604
+ if (!((_b = this.filenames) === null || _b === void 0 ? void 0 : _b.length)) {
2605
+ this.filenames = undefined;
2606
+ }
2607
+ const fileDataToRemove = (_c = this.multiFileData) === null || _c === void 0 ? void 0 : _c.find(f => f.name === name);
2608
+ (_d = this.multiFileData) === null || _d === void 0 ? void 0 : _d.splice(this.multiFileData.indexOf(fileDataToRemove), 1);
2609
+ if (!((_e = this.multiFileData) === null || _e === void 0 ? void 0 : _e.length)) {
2610
+ this.multiFileData = undefined;
2611
+ }
980
2612
  }
981
- this.metadataAutocompleteStringChipsArray = this.metadata;
982
- if (!this.getValidationErrorMessage) {
983
- this.getValidationErrorMessage = getValidationErrorMessage;
2613
+ else {
2614
+ this.filenames = undefined;
2615
+ this.singleFileData = undefined;
984
2616
  }
2617
+ this.fileDataChangeEvent.emit((_f = this.singleFileData) !== null && _f !== void 0 ? _f : this.multiFileData);
2618
+ }
2619
+ }
2620
+ FileInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FileInputComponent, deps: [{ token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
2621
+ FileInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: FileInputComponent, selector: "file-input", inputs: { entity: "entity", key: "key", getValidationErrorMessage: "getValidationErrorMessage" }, 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\" (click)=\"fileInput.click()\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n [(ngModel)]=\"filenames\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip *ngFor=\"let name of filenames\" (removed)=\"removeFile(name)\">\n {{name}}\n <button matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input [matChipInputFor]=\"chipList\" [readonly]=\"true\">\n </mat-chip-list>\n <button mat-icon-button matSuffix>\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\" class=\"dropdown\" dragDrop (files)=\"setFile($event)\">\n <i class=\"fas fa-file-arrow-up\"></i>\n</div>", styles: ["mat-form-field{width:100%}input:hover,mat-form-field:hover{cursor:pointer}i{color:#757575}.dropdown{display:flex;align-items:center;justify-content:center;height:200px;border:2px dashed #757575;border-radius:15px;margin-top:5px;margin-bottom:5px}.dropdown i{font-size:30px}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$5.MatChipList, selector: "mat-chip-list", inputs: ["errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2$5.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { type: i2$5.MatChipRemove, selector: "[matChipRemove]" }, { type: i2$5.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: DragDropDirective, selector: "[dragDrop]", outputs: ["files"] }] });
2622
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FileInputComponent, decorators: [{
2623
+ type: Component,
2624
+ 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\" (click)=\"fileInput.click()\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n [(ngModel)]=\"filenames\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip *ngFor=\"let name of filenames\" (removed)=\"removeFile(name)\">\n {{name}}\n <button matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input [matChipInputFor]=\"chipList\" [readonly]=\"true\">\n </mat-chip-list>\n <button mat-icon-button matSuffix>\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\" class=\"dropdown\" dragDrop (files)=\"setFile($event)\">\n <i class=\"fas fa-file-arrow-up\"></i>\n</div>", styles: ["mat-form-field{width:100%}input:hover,mat-form-field:hover{cursor:pointer}i{color:#757575}.dropdown{display:flex;align-items:center;justify-content:center;height:200px;border:2px dashed #757575;border-radius:15px;margin-top:5px;margin-bottom:5px}.dropdown i{font-size:30px}\n"] }]
2625
+ }], ctorParameters: function () { return [{ type: i1.MatDialog }]; }, propDecorators: { entity: [{
2626
+ type: Input
2627
+ }], key: [{
2628
+ type: Input
2629
+ }], getValidationErrorMessage: [{
2630
+ type: Input
2631
+ }], fileDataChangeEvent: [{
2632
+ type: Output
2633
+ }] } });
2634
+
2635
+ class FileDefaultInputComponent extends NgxMatEntityBaseInputComponent {
2636
+ constructor() {
2637
+ super(...arguments);
2638
+ this.FileUtilities = FileUtilities;
2639
+ }
2640
+ refreshFileData(fileData) {
2641
+ return __awaiter(this, void 0, void 0, function* () {
2642
+ this.entity[this.key] = fileData;
2643
+ this.emitChange();
2644
+ });
2645
+ }
2646
+ }
2647
+ FileDefaultInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FileDefaultInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2648
+ FileDefaultInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: FileDefaultInputComponent, selector: "file-default-input", usesInheritance: true, ngImport: i0, template: "<div *ngIf=\"metadata.dragAndDrop\" class=\"file-input mat-elevation-z8\">\n <file-input (fileDataChangeEvent)=\"refreshFileData($event)\" [entity]=\"entity\" [key]=\"key\" [getValidationErrorMessage]=\"getValidationErrorMessage\"></file-input>\n</div>\n\n<div *ngIf=\"!metadata.dragAndDrop\">\n <file-input (fileDataChangeEvent)=\"refreshFileData($event)\" [entity]=\"entity\" [key]=\"key\" [getValidationErrorMessage]=\"getValidationErrorMessage\"></file-input>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}\n"], components: [{ type: FileInputComponent, selector: "file-input", inputs: ["entity", "key", "getValidationErrorMessage"], outputs: ["fileDataChangeEvent"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2649
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FileDefaultInputComponent, decorators: [{
2650
+ type: Component,
2651
+ args: [{ selector: 'file-default-input', template: "<div *ngIf=\"metadata.dragAndDrop\" class=\"file-input mat-elevation-z8\">\n <file-input (fileDataChangeEvent)=\"refreshFileData($event)\" [entity]=\"entity\" [key]=\"key\" [getValidationErrorMessage]=\"getValidationErrorMessage\"></file-input>\n</div>\n\n<div *ngIf=\"!metadata.dragAndDrop\">\n <file-input (fileDataChangeEvent)=\"refreshFileData($event)\" [entity]=\"entity\" [key]=\"key\" [getValidationErrorMessage]=\"getValidationErrorMessage\"></file-input>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}\n"] }]
2652
+ }] });
2653
+
2654
+ // eslint-disable-next-line max-len
2655
+ const placeholder = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAAMgCAMAAAAEPmswAAAANlBMVEXx8/XCy9LFztXu8PPs7/Lp7e/W3OHL0tnZ3+PN1NrS2d7i5urn6u7f5OjI0Nfc4ebP1tzk6excnoRZAAAXh0lEQVR42uzUAQ0AAAzDoN+/6eloAiK4B4gQFpAhLCBDWECGsIAMYQEZwgIyhAVkCAvIEBaQISwgQ1hAhrCADGEBGcICMoQFZAgLyBAWkCEsIENYQIawgAxhARnCAjKEBWQIC8gQFpAhLCBDWECGsIAMYQEZwgIyhAVkCAvIEBaQISwgQ1hAhrCADGEBGcICMoQFZAgLyBAWkCEsIENYQIawgAxhARnCAjKEBWQIC8gQFpAhLGDs1AEJAAAAgKD/r9sR6Ag3hAVsCAvYEBawISxgQ1jAhrCADWEBG8ICNoQFbAgL2BAWsCEsYENYwIawgA1hARvCAjaEBWwIC9gQFrAhLGBDWMCGsIANYQEbwgI2hAVsCAvYEBawISxgQ1jAhrCADWEBG8ICNoQFbAgL2BAWsCEsYENYwIawgA1hARvCAjaEBWwIC9gQFrAhLGBDWMCGsIANYQEbwgI2hAVsCAvYEBbETh2QAAAAAAj6/7odgY6QDWEBG8ICNoQFbAgL2BAWsCEsYENYwIawgA1hARvCAjaEBWwIC9gQFrAhLGBDWMCGsIANYQEbwgI2hAVsCAvYEBawISxgQ1jAhrCADWEBG8ICNoQFbAgL2BAWsCEsYENYwIawgA1hARvCAjaEBWwIC9gQFrAhLGBDWMCGsIANYQEbwgI2hAVsCAvYEBawISxgQ1jAhrCADWEBG8ICNoRF7NQBCQAAAICg/6/bEegIYUNYwIawgA1hARvCAjaEBWwIC9gQFrAhLGBDWMCGsIANYQEbwgI2hAVsCAvYEBawISxgQ1jAhrCADWEBG8ICNoQFbAgL2BAWsCEsYENYwIawgA1hARvCAjaEBWwIC9gQFrAhLGBDWMCGsIANYQEbwgI2hAVsCAvYEBawISxgQ1jAhrCADWEBG8ICNoQFbAgL2BAWsCEsYENYwIawgA1hxc6dJtcKAgEURgREwGn/m32Vd1Op/Ih3cO72fIs4BU0rADEIFgAxCBYAMQgWADEIFgAxCBbwm+3bFOKQ8zSV4r13zvky5a4bYgxjYyuch2ABD7ZJMRdnXnIlDyE1FY5HsADbhmFy5lM+x7GvcCSChXtrQufNCnXpQlvhIAQLt2XHONVmE2VIzLaOQLBwT230ZlsuBy6IeyNYuB+bOmd24TpOWrsiWLiZJhazKz8w09oNwcKd9NGbA9SZg9Y+CBZuw4ZijlMiE63tESzcg02TOZqnWVsjWLiDpqvNKXxkI35LBAv6pWJO5APzrM0QLChnozNnm5jBb4RgQbU2m0uoO3YdtkCwoFjy5jp85Ji1GsGCWpfK1X95rLAKwYJS4XK54pi1HsGCSuH8SfucjkWH5QgWFLpwrr6UVGEZggV10rVz9cVxM1yGYEGZthgJ6oHPdhYgWFClv8jeFcOsfRAsKGIHI8rENumHCBb0iLWRhvn7ZwgWtGgvuXj1kidZHyBY0MF2RiqS9T6CBRWCvNsgyVqAYEGBRsYqA8lajWBBPGlvg38rvBi+gWBBuvb6i+3vmdjLeolgQTYdx6tvme33FwgWRBO6yzBr4BvDpwgWJNN0vHqo+Sz6GYIFuRplx6sHx4PhPIIFsaJRigfDWQQLQvXid6+Yvn+OYEGmUfRq+2uMsv5EsCCSvmk7o6x3ECwIpPo6yCLpEwQL8iTl10G2smYRLIij/zrIvXAOwYIwvcrlq1kT74W/ESzIMmr51Plddazwg2BBlGDux7NH+oNgQRK5/0Fm+L4JgvWPvbvRSRiGAjBaBoqK+PP+L2s0xGSj3QiQ9I57zkN86brblvVItn1l8/2cYLEar1mmGWoOFlm/BIu1yLh9ZZE1IVisRNLtK4usEcFiFYbvwtYiS7BYg7zb7WPfFlmCRXj7bNOiFlkNgkV8j373lZ2siwkW4SX/PTi1+9pkJljEluhyhgsdMy+yBIvQDoWpXeLThYJFYMYZ6vJe4SBYxDWkuAv5Gu9Z78kSLMIajF8ZcBgRLOL6MH5l731MsAhrb/zK3vuEYBFV6ttk7L3XCRZBvRUcLpwSLGLSK3PvFYJFSHrls7BGsIhIr3wWVgkWATnu7G9hnWARj175LGwQLMLRK5+FLYJFNHp1jd1+k4NgEYpeXel5k4JgEYleXe24yUCwCESvXDkzR7CIxPzVTbYJxt4FizD0ynzDPMEiDr3yCtgCwSKMr8Ltnh58I0uwiOG1cA/bxz6oI1iE4L4+E1nLBIsY3IdsIusCgkUI3pu4q/fH3XoXLPob9OqXo4VLBIsAvD944tnCBYJFAN53PjFDukCw6O9Q+GPrfYlg0d2x8M+tfrMEi94+CyOm3tsEi65cKDNl6n2OYNGTA89Vpt5bBIuOHCCs8rOwSbDoaW9gtMbPwhbBohsD7k1+FjYIFv0MBkbb/CysESx6MTA6z8nCCsGiEwNYS7xOcU6w6OWlsMB4ww9794LdJgyEUXgwAsfFL/a/2Z4+T2zjWCMgnl/cbwttbxppNNwjWHgLBrByMN5wj2Ct4HztL+OxS621qTuOp/5a06HnItgw+v0uTRUI1qL2/dDao3b8qO+RRDkGGt5haGpAsJZzPbX2XDvUc/I5ExuwsrE4+QbBWsz+I9kr6VLR/XI5Nsq8SVdBsQjWIg6D5Rn5bxYbGpwYyPqPYC3iMFq+4+aTxSeevdg38xfBWsB5MJ+j/s+5Oc5cEDoxQvoPwZrvozW3SwWHCWX4RM67iX9Oh2DNc+isRFL/QVduNBRg6P0XgjVTv/nJYx9eEAYgXSyCNcNu2PpUjBMXhCEo/7AkWKVm78tM8jc2XqxEDkL4mQ7BKnZot35j48QFYRi6z3QIVqlru/kbGx8uCAORLRbBKvSD808nVoxGorrpnWCVuTIV48TKvlhEL30IVoEl1zlt5xyLlX2xaBaLYJU4J153+bCyLx7J5Q0Ey23hw+Ok+NfGiwP3iBSLRbAKDLaksdkCDtwDSnrLuwmWX29mDB57MOEelF6xCJbTGocx9R9jMeEelNxKP4Ll1tlvHGPl4psTgbVixSJYXr39wS+FuVgpE5lYsQiW0661FcgdJTiwUiY2rd8KCZbTyf7ipjAPO9yjk/o/FsHy2dstBt5fYEVDfErFIlg+g63j2FSLidHwhJ5bECyXs33GaMNLfDRVgk6xCJbLyT7jFOsVJkZFyBSLYHnsbD1C5wgOe4MElWIRLI/e7rFn+ws8eRYiUiyC5dHZelJTIZ4869C4KyRYDnu7x2TDF9gxqkWiWATL4WJrOjW14cmzFoViESyHZGtqm8rw5FmNwCsdgpXvbI8YxXqGJ8+C4heLYOXr7RE7G57gAEtS+I1+BCvfyaYwOzqFAyxR0YtFsPIle8Qh1iQOsGQFLxbByrazCQy7T2ICS1fsb+kQrGwHe4rPQN/iCaGy0MUiWNl6m8Kp+yN2YGmL/E1ogpXtYtMYHb3HDixxgYtFsLIN9gRb/G6xxF1e3AtrgpXtaM/w/vkzlrhXYGiCIljZOntAsKbsOMDSF7VYBCtbsrVV8ofBk5waBD1QreTfyPoIVh6e5NQi5kbJOv6NfAtbX9zLmVw8yanHT/buBDt1GIbCsJwRCOP+N/t62vNaphLbSZEs/98O2gOXyJFkk102BFYkAisGIzmeDMEeAitaK09REl5hJMcVg6MXHr4jb8EZVgRGcpyxl1gOviPv0stzrGv4MdLR4Iu5pZIEViQaR+cxkuOOucu/CKxIjObMYiTHIWsXUxBY0TbynPtevUiM5LhkbKEfgRWJ9TIz6GhwytZ6LAIrEgv8ZtDR4JWpZTMEViRWJM/ZCXyytGyGwIrFJRSvsGTUM0OHqwRWLK75eoUdDa7ZGYQmsOLt5CnO3EOgxd05M59NAisWV9W/MgpcszIITWAl6OUeR1ifaHH37xxMILASnOSBz5NNY/8ZGGBkSIfASjDKDZ8/YelY2lcFG0M6BFaKXh4w+UyLeyU6Cw2kBFaKQW75fHOc7CCogYUhHQIrRSN3aHMPtLjXw0CnIIGV5CT3vN8DN4eCsCb6L4YIrCRHuUYTVgi0uFdFvYGUwEpzkP/cPWxnocW9MkPQRGClGuUKPQ1sca/OOSgisJId5BsnWB/2gqqoNpASWMmaVv6ArTW00biXvkLtMaghsNIN8snXUWYeZp6rpNiORWBl2Mva+lAqZp5rtA9aCKxk36s1aWlg5rlWU1BCYOXYyQcKQmae63UKOgisLAcRoQWLgrBiQ1BBYGVpem8z8BkoCKt2DhoIrDzHztmWoXQUhHXT+dwSWJnGtvoDd2ae66ZSGRBYubbVX/ZMQVg5jXYsAivbueyzSyN/Pwo2hbcjsPJt25qfrygIodDcQGAtMHZlj5EuwFZkqBQIBNYSx16W6Ip9P0hBCJ3mBgJrkeYg+S7F9l9REEKpuYHAWmiobx4nBApCKDU3EFhLjb3k6As+vuKaHGhtbiCwlhvayh6vKAihdZEOgbWCZpI0l2L3i36ZBFD59SWwVjFOKXFVdDUYKAih101IYK0iIbKm0uMqNFyTA615WAJrNcdNL3O6TcGtV18oCKH4qpDAWtP21MnvukOxdw/+oCCE5qtCAmtlx2Hq5FE7DQ6erUKgIITqHDSB9Qea7XCaLvu+a7u+30+nYVtwT/stCkKovioksJCAgvAfe3eU6ygMBFG0GhtCSAxh/5udUWby8Z4COGCgI92ziJLLuBuc+6mQwEI+nozi9KlCAgu5KIQ4/VMhgYVMFEKc/6mQwEIeCiEcTBUSWMhDIYSDBaQEFrJQCOFhASmBhRwUQiwLve2LwEIetozCxb8KCSxk4LcT8DGjQ2BhGYUQTmZ0CCwsoxDCyYwOgYVFFEJ4mdEhsLCEQgg3MzoEFpZQCPGJ0XZDYGERhRCfGWwvBBaWUAjh6OKdwMI8CiE+drF9EFhYQCGEp4t3AgtzKIRwdfFOYGEOhRCuLt4JLMy6CvBz8U5gYU5VC/Dz4p3AwpxBgKNVMwQWJlEI4W3VDIGFGRRC+Fo1Q2BhCoUQ7na8E1iYdBHga8c7gYUJFEL4u3gnsDClFeDs4p3AwjsUQrj8uarsCP21a4Z0G+sYQwiSQoixvo9paJvHpTI4RCFEAVcrSrar/tEMY9SCeL+1zaM3OEIhhMPFDbK9VF07Bn2kTs2V45YPFEJ4XNwg20PfpKgJOallONtdgL/FDbLSqi7V2qpOHUetU1AI8eR0cYOsqKq7BRVybzlpHY5CiH+cvh+VlVN1o8oKt4ar+CNRCPHi8/2orJRrCtpDTA/DISiE2EeyUmRFVG3UfgKZdQAKIX7y+H5UVkA/BP1GZn0vCiGeHP74S7bZJek9Mus7NQL+8vh+VLZRlXSckC6GnfUCnhyOQcu2aYOOVTc80CqOQoj33O0flW3RRR0vJN5nlUUhxAR3Y9Cy9aqb8nHM+g59EPDi7hpLtloXdCKOWYVQCDHP1Ri0LJOf49VL3Rm2ohBiga9rLFkeX8er/yLNcBsKIXI4+o2ObAU//38KA7OGJY0CfvM0Bi1bofd00cHTrLUohDja3TaSfe4R5crIC/gVKIR/2Lvb5NRhGArD54RvCC3sf7N3Op07UyhJ7PQHsvU+W4BxIvlIQbkw2/zkMrFH+em/V6MgRKlIbSy50hDzX82RVYeCEMUitbHkOh9hP/60ozAsRkGIGoHaWHKVQ7D21YORI6sCkVGUC9PGkqcFTV9xZP0RBSGqRWljyb+1/J/myKrAllG8w2bwavKEwGnReXdyWXMoCPF2o1eTi719eLDUlYGdOa1kVdCvo9eSH/RwXkmbI0fWSxSEiOHmleRnTcWvpmz3RoWwYRX0afVuLLnI0FyLg1jWMwpCxHH3OnKJocUn8Ej3/QcKQoRy9Cryt/7OK7rvDygIEcvJa8hf+jyvaGX91HpcBZ1Z18aS7W7PK0kjq9+XnAS8wcUryO75vKIutE1BiJD2rifb7ut+8NmGupCCEBEdXE3dn1eSdtSFFISIZze4lvxf10soqQsnDJH3BaF3V9dSivNK2rKR9KWrgPc5u5LcyfzgogsfBPvtJuB96hcmK08/luY7BSGi2bmOMk2YMazT8Rs02vTpKvKks/pzNPr+hdGam2soWXuDhAOfyUEodSM68oRTr//mTxIOvV0Bo2l3V5BfO/R6XvGS1dAnRZDC3uWU8fro02AJFsI4uJhSfkNlx3UhM88Io2JER0nzz+mvC/vK2KFtV5dSigAWL1nMPCOyswspbzwn80tW3z1KNKd4REeJH75j3ulCIu6IZXQZ+dlHnofvJusKhyTv0GjI0UXU20bkOpeUKVIi7ojn5BJKXixsM6ZIOw+toEllIzpKeEGYPUWa7zdGC64uIJob2XrvaS5V0JizlynLBCGb/Ug0ILbN4EXK23BP2ntP1qREQ+5eJPaNfNmmyb2zowFx7b1ENGO/JSkLcxb9aMXBC5S74Z6uLMxa9KMNOy8Qz95MkSx2NCC2q+cpfcM90zh0n3v60ZObZ4nLox/ufZeFQ/aXaMS3EHgXl0d5ysK8t8Box8VzRPo5zW1h6ltgNGPvGSL9nOW2kAYWmjC7zE80sJIsT+ahhEaMniZqhSR7/f6xdy+4iQNBEEDdQYEA4Xf/y+5ukk2AYAkFKXKX3ztEWe6p6THAoouXGjUYYM1j5YyPEn2saszgX2EWK2cMsGhk/KHCwb/CTYtjJfFRopVDjRj8K8yh9m4pMr0c67bBAGsG/QZXCGlmrPA++FcY9ZwyyJr5Hg462tZNA/GDLK960dCmvhNYMxhk2cNBR7cK7wJrBoOs3QANneobgZU/yLKHg6aWdU1gxQ+ynALT1qquCKz0jTMao/T1WlcE1l121ZbGKI291CWBdZ/XrqN3A3daW9UFgZX90KqBO7091wWBFb0jy8Cd7g51TmAld0g13OlvXWcEVnCHVMOdABe3oAVW8Ojdon4S7OqLwModvdtzRoZjfRJYsaN3K2UIcfZTKLBSR+8OCImxrf8EVmjr3QEhQTb1QWBljt4dEJJk8VTvBFbm6N1DSETZ1juBFblwxpsThNnUG4GVuHBGoYE0Hz+FAivwsNCNZ/Js6x+B9VPbmiqP0pNoWX8JrLjDwpVCA4nefgoFVtph4d5KZDKdqkpgPWCxrslRwCLWskpgPWRyNwufrHAn1mJfAivqsFBekexUAivqZqGCO9GWAutRpwkdFtrYR7bFXmDlPGXvSS/SnQRWTL1BXpHPNY6Uu9AuPDMDatEhd6HlFdCl3iCvgC71BnkFdLkLbd4OdKk3yCugS71BXgFd6g367UCTeoP7zsAPHeoe9l8BU7CrX7WyXxRoUm9Yu6gA/GHvDnMThmEwgNZpF9LQUrj/ZfdvmmBMDEabSu8dIkrsz85O4g3VeQW8ZhjjPv+lAk3pa9whzgA0J8ePxBmABs3xZqP2ILCTVe/2LgI7aRYm04NA1+1iFvog3Q503S6ahZ6DwJe2FycnaQbgLY4p/lnVHQS+abj07noFXGl2TsfsIHCrydS76xVwq8lCViquV8D7fRwU24HdyPGa0aQzsJrpFM8bFa+ANfUlnnS+dADrGmo8oZobBLYwLKf4k1NRagc2M9UUD0rZWxDYVj8/cmalOotdAS2Yyhi/OBcpBqAh/WXJY4or6ZwXhxXQpGE6znMpOZdlmY+TVyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDJHhwIAAAAAAD5vzaCqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqwBwcCAAAAAED+r42gqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqirswYEAAAAAAJD/ayOoqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkp7cCAAAAAAIMjfepArAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgKcAnTNeiLeG1rEAAAAASUVORK5CYII=';
2656
+
2657
+ class FileImageInputComponent extends NgxMatEntityBaseInputComponent {
2658
+ constructor() {
2659
+ super(...arguments);
2660
+ this.FileUtilities = FileUtilities;
2661
+ this.imageIndex = 0;
2662
+ this.placeHolder = placeholder;
2663
+ }
2664
+ setSinglePreviewImage() {
2665
+ return __awaiter(this, void 0, void 0, function* () {
2666
+ let singleFileData = this.entity[this.key];
2667
+ if (singleFileData) {
2668
+ singleFileData = yield FileUtilities.getFileData(singleFileData);
2669
+ this.singlePreviewImage = yield FileUtilities.getDataURLFromFile(singleFileData.file);
2670
+ }
2671
+ else {
2672
+ this.singlePreviewImage = undefined;
2673
+ }
2674
+ });
2675
+ }
2676
+ setMultiPreviewImages(index) {
2677
+ return __awaiter(this, void 0, void 0, function* () {
2678
+ const multiFileData = this.entity[this.key];
2679
+ const previewImages = [];
2680
+ if (multiFileData === null || multiFileData === void 0 ? void 0 : multiFileData.length) {
2681
+ for (let i = 0; i < multiFileData.length; i++) {
2682
+ if (i === index) {
2683
+ multiFileData[index] = yield FileUtilities.getFileData(multiFileData[index]);
2684
+ previewImages.push(yield FileUtilities.getDataURLFromFile(multiFileData[index].file));
2685
+ }
2686
+ else {
2687
+ previewImages.push('empty');
2688
+ }
2689
+ }
2690
+ }
2691
+ this.multiPreviewImages = previewImages;
2692
+ });
2693
+ }
2694
+ refreshFileData(fileData) {
2695
+ return __awaiter(this, void 0, void 0, function* () {
2696
+ this.entity[this.key] = fileData;
2697
+ this.emitChange();
2698
+ if (this.metadata.multiple) {
2699
+ if (!(fileData === null || fileData === void 0 ? void 0 : fileData[this.imageIndex])) {
2700
+ this.imageIndex = 0;
2701
+ }
2702
+ yield this.setMultiPreviewImages(this.imageIndex);
2703
+ }
2704
+ else {
2705
+ yield this.setSinglePreviewImage();
2706
+ }
2707
+ });
2708
+ }
2709
+ prev() {
2710
+ return __awaiter(this, void 0, void 0, function* () {
2711
+ if (this.imageIndex > 0) {
2712
+ yield this.setMultiPreviewImages(this.imageIndex - 1);
2713
+ this.imageIndex--;
2714
+ }
2715
+ });
2716
+ }
2717
+ next() {
2718
+ var _a;
2719
+ return __awaiter(this, void 0, void 0, function* () {
2720
+ if (((_a = this.multiPreviewImages) === null || _a === void 0 ? void 0 : _a.length) && this.imageIndex !== (this.multiPreviewImages.length - 1)) {
2721
+ yield this.setMultiPreviewImages(this.imageIndex + 1);
2722
+ this.imageIndex++;
2723
+ }
2724
+ });
2725
+ }
2726
+ setIndex(index) {
2727
+ return __awaiter(this, void 0, void 0, function* () {
2728
+ yield this.setMultiPreviewImages(index);
2729
+ this.imageIndex = index;
2730
+ });
2731
+ }
2732
+ }
2733
+ FileImageInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FileImageInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2734
+ FileImageInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: FileImageInputComponent, selector: "file-image-input", usesInheritance: true, ngImport: i0, template: "<div *ngIf=\"!metadata.dragAndDrop && !metadata.preview\">\n <file-input (fileDataChangeEvent)=\"refreshFileData($event)\" [entity]=\"entity\" [key]=\"key\" [getValidationErrorMessage]=\"getValidationErrorMessage\"></file-input>\n</div>\n\n<div *ngIf=\"metadata.dragAndDrop || metadata.preview\" class=\"file-input mat-elevation-z8\">\n <file-input (fileDataChangeEvent)=\"refreshFileData($event)\" [entity]=\"entity\" [key]=\"key\" [getValidationErrorMessage]=\"getValidationErrorMessage\"></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()\" [class.disabled]=\"!multiPreviewImages || !multiPreviewImages.length || imageIndex === (multiPreviewImages.length - 1)\" class=\"next-button fa-solid fa-angle-right\"></i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && metadata.multiple\">\n <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 (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 (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 (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 mat-icon-button disabled>\n <i class=\"dot selected\"></i>\n <span class=\"image-index\">{{imageIndex + 1}}</span>\n </button>\n <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 (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 (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 (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 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}.image-preview .next-button{font-size:100px;margin-right:5px}.image-preview .prev-button:hover,.image-preview .next-button:hover{cursor:pointer}.image-preview .prev-button.disabled,.image-preview .next-button.disabled{color:#00000061}.image-preview .prev-button.disabled:hover,.image-preview .next-button.disabled:hover{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:#000000de}.preview-nav button .image-index{position:absolute;height:100%;width:100%;display:block;top:-11.5px;color:#fff}.preview-nav button:hover{background-color:#000}\n"], components: [{ type: FileInputComponent, selector: "file-input", inputs: ["entity", "key", "getValidationErrorMessage"], outputs: ["fileDataChangeEvent"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2735
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FileImageInputComponent, decorators: [{
2736
+ type: Component,
2737
+ args: [{ selector: 'file-image-input', template: "<div *ngIf=\"!metadata.dragAndDrop && !metadata.preview\">\n <file-input (fileDataChangeEvent)=\"refreshFileData($event)\" [entity]=\"entity\" [key]=\"key\" [getValidationErrorMessage]=\"getValidationErrorMessage\"></file-input>\n</div>\n\n<div *ngIf=\"metadata.dragAndDrop || metadata.preview\" class=\"file-input mat-elevation-z8\">\n <file-input (fileDataChangeEvent)=\"refreshFileData($event)\" [entity]=\"entity\" [key]=\"key\" [getValidationErrorMessage]=\"getValidationErrorMessage\"></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()\" [class.disabled]=\"!multiPreviewImages || !multiPreviewImages.length || imageIndex === (multiPreviewImages.length - 1)\" class=\"next-button fa-solid fa-angle-right\"></i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && metadata.multiple\">\n <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 (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 (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 (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 mat-icon-button disabled>\n <i class=\"dot selected\"></i>\n <span class=\"image-index\">{{imageIndex + 1}}</span>\n </button>\n <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 (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 (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 (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 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}.image-preview .next-button{font-size:100px;margin-right:5px}.image-preview .prev-button:hover,.image-preview .next-button:hover{cursor:pointer}.image-preview .prev-button.disabled,.image-preview .next-button.disabled{color:#00000061}.image-preview .prev-button.disabled:hover,.image-preview .next-button.disabled:hover{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:#000000de}.preview-nav button .image-index{position:absolute;height:100%;width:100%;display:block;top:-11.5px;color:#fff}.preview-nav button:hover{background-color:#000}\n"] }]
2738
+ }] });
2739
+
2740
+ /* eslint-disable jsdoc/require-jsdoc */
2741
+ class CustomInputComponent extends NgxMatEntityBaseInputComponent {
2742
+ constructor(viewContainerRef) {
2743
+ super();
2744
+ this.viewContainerRef = viewContainerRef;
2745
+ }
2746
+ ngOnInit() {
2747
+ super.ngOnInit();
2748
+ this.component = this.viewContainerRef.createComponent(this.metadata.component);
2749
+ this.component.instance.entity = this.entity;
2750
+ this.component.instance.key = this.key;
2751
+ this.component.instance.getValidationErrorMessage = this.getValidationErrorMessage;
2752
+ this.component.instance.inputChangeEvent.subscribe(this.inputChangeEvent);
2753
+ }
2754
+ }
2755
+ CustomInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: CustomInputComponent, deps: [{ token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
2756
+ CustomInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: CustomInputComponent, selector: "custom-input", usesInheritance: true, ngImport: i0, template: "", styles: [""] });
2757
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: CustomInputComponent, decorators: [{
2758
+ type: Component,
2759
+ args: [{ selector: 'custom-input', template: "", styles: [""] }]
2760
+ }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }]; } });
2761
+
2762
+ /**
2763
+ * The default input component. It gets the metadata of the property from the given @Input "entity" and @Input "propertyKey"
2764
+ * and displays the input field accordingly.
2765
+ *
2766
+ * You can also define a method that generates error-messages and if the input should be hidden when its metadata says
2767
+ * that it should be omitted for creating or updating.
2768
+ * The last part being mostly relevant if you want to use this component inside an ngFor.
2769
+ */
2770
+ class NgxMatEntityInputComponent {
2771
+ constructor(dialog) {
2772
+ this.dialog = dialog;
2773
+ this.inputChangeEvent = new EventEmitter();
2774
+ this.selection = new SelectionModel(true, []);
2775
+ this.isArrayItemValid = false;
2776
+ this.isDialogArrayItemValid = false;
2777
+ this.DecoratorTypes = DecoratorTypes;
2778
+ this.EntityUtilities = EntityUtilities;
2779
+ this.DateUtilities = DateUtilities;
985
2780
  }
986
2781
  /**
987
- * Tries to add an item to the array.
988
- * Does this either inline if the "createInline"-metadata is set to true
989
- * or in a separate dialog if it is set to false.
2782
+ * This is needed for the inputs to work inside an ngFor.
2783
+ *
2784
+ * @param index - The index of the element in the ngFor.
2785
+ * @returns The index.
990
2786
  */
991
- add() {
992
- if (this.metadataEntityArray.createInline) {
993
- this.entityArrayValues.push(cloneDeep(this.arrayItem));
994
- this.dataSource.data = this.entityArrayValues;
995
- EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
2787
+ trackByFn(index) {
2788
+ return index;
2789
+ }
2790
+ ngOnInit() {
2791
+ var _a;
2792
+ if (!this.entity) {
2793
+ throw new Error('Missing required Input data "entity"');
996
2794
  }
997
- else {
998
- this.addArrayItemDialogRef = this.dialog.open(this.addArrayItemDialog, {
999
- data: this.dialogData,
1000
- autoFocus: false,
1001
- restoreFocus: false
1002
- });
2795
+ this.internalEntity = this.entity;
2796
+ if (this.propertyKey == null) {
2797
+ throw new Error('Missing required Input data "propertyKey"');
1003
2798
  }
2799
+ this.internalPropertyKey = this.propertyKey;
2800
+ this.internalGetValidationErrorMessage = (_a = this.getValidationErrorMessage) !== null && _a !== void 0 ? _a : getValidationErrorMessage;
2801
+ this.type = EntityUtilities.getPropertyType(this.entity, this.propertyKey);
2802
+ this.metadata = EntityUtilities.getPropertyMetadata(this.entity, this.propertyKey, this.type);
2803
+ if (this.type === DecoratorTypes.OBJECT) {
2804
+ this.initObjectInput();
2805
+ }
2806
+ if (this.type === DecoratorTypes.ARRAY) {
2807
+ this.initEntityArray();
2808
+ }
2809
+ }
2810
+ initEntityArray() {
2811
+ var _a;
2812
+ this.metadataEntityArray = this.metadata;
2813
+ if (this.internalEntity[this.internalPropertyKey] == null) {
2814
+ this.internalEntity[this.internalPropertyKey] = [];
2815
+ }
2816
+ this.entityArrayValues = this.internalEntity[this.internalPropertyKey];
2817
+ if (!this.metadataEntityArray.createInline && !this.metadataEntityArray.createDialogData) {
2818
+ this.metadataEntityArray.createDialogData = {
2819
+ title: 'Add'
2820
+ };
2821
+ }
2822
+ const givenDisplayColumns = this.metadataEntityArray.displayColumns.map((v) => v.displayName);
2823
+ if (givenDisplayColumns.find(s => s === 'select')) {
2824
+ throw new Error(`The name "select" for a display column is reserved.
2825
+ Please choose a different name.`);
2826
+ }
2827
+ this.displayedColumns = ['select'].concat(givenDisplayColumns);
2828
+ this.dataSource = new MatTableDataSource();
2829
+ this.dataSource.data = this.entityArrayValues;
2830
+ this.arrayItem = new this.metadataEntityArray.EntityClass();
2831
+ this.arrayItemInlineRows = EntityUtilities.getEntityRows(this.arrayItem, (_a = this.hideOmitForCreate) !== null && _a !== void 0 ? _a : true, this.hideOmitForEdit);
2832
+ this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
2833
+ this.dialogInputData = {
2834
+ entity: this.arrayItem,
2835
+ createDialogData: this.metadataEntityArray.createDialogData,
2836
+ getValidationErrorMessage: this.getValidationErrorMessage
2837
+ };
2838
+ this.dialogData = new AddArrayItemDialogDataBuilder(this.dialogInputData).getResult();
2839
+ this.arrayItemDialogRows = EntityUtilities.getEntityRows(this.dialogData.entity, true);
2840
+ }
2841
+ initObjectInput() {
2842
+ this.metadataDefaultObject = this.metadata;
2843
+ this.objectProperty = this.internalEntity[this.internalPropertyKey];
2844
+ this.objectPropertyRows = EntityUtilities.getEntityRows(this.objectProperty, this.hideOmitForCreate, this.hideOmitForEdit);
2845
+ }
2846
+ /**
2847
+ * Checks if the arrayItem is valid.
2848
+ */
2849
+ checkIsArrayItemValid() {
2850
+ this.isArrayItemValid = EntityUtilities.isEntityValid(this.arrayItem, 'create');
2851
+ }
2852
+ /**
2853
+ * Checks if the arrayItem inside the dialog is valid.
2854
+ */
2855
+ checkIsDialogArrayItemValid() {
2856
+ this.isDialogArrayItemValid = EntityUtilities.isEntityValid(this.dialogData.entity, 'create');
2857
+ }
2858
+ /**
2859
+ * Emits that a the value has been changed.
2860
+ */
2861
+ emitChange() {
2862
+ this.inputChangeEvent.emit();
2863
+ }
2864
+ /**
2865
+ * Tries to add an item to the entity array.
2866
+ * Does this either inline if the "createInline"-metadata is set to true
2867
+ * or in a separate dialog if it is set to false.
2868
+ */
2869
+ addEntity() {
2870
+ return __awaiter(this, void 0, void 0, function* () {
2871
+ if (this.metadataEntityArray.createInline) {
2872
+ if (!this.metadataEntityArray.allowDuplicates) {
2873
+ for (const v of this.entityArrayValues) {
2874
+ if ((yield EntityUtilities.isEqual(this.arrayItem, v, this.metadata, this.metadataEntityArray.itemType))) {
2875
+ this.dialog.open(NgxMatEntityConfirmDialogComponent, {
2876
+ data: this.metadataEntityArray.duplicatesErrorDialog,
2877
+ autoFocus: false,
2878
+ restoreFocus: false
2879
+ });
2880
+ return;
2881
+ }
2882
+ }
2883
+ }
2884
+ this.entityArrayValues.push(LodashUtilities.cloneDeep(this.arrayItem));
2885
+ this.dataSource.data = this.entityArrayValues;
2886
+ EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
2887
+ this.checkIsArrayItemValid();
2888
+ this.emitChange();
2889
+ }
2890
+ else {
2891
+ this.addArrayItemDialogRef = this.dialog.open(this.addArrayItemDialog, {
2892
+ data: this.dialogData,
2893
+ autoFocus: false,
2894
+ restoreFocus: false
2895
+ });
2896
+ }
2897
+ });
1004
2898
  }
1005
2899
  /**
1006
2900
  * Adds the array item defined in the dialog.
1007
2901
  */
1008
2902
  addArrayItem() {
1009
2903
  this.addArrayItemDialogRef.close();
1010
- this.entityArrayValues.push(cloneDeep(this.arrayItem));
2904
+ this.entityArrayValues.push(LodashUtilities.cloneDeep(this.arrayItem));
1011
2905
  this.dataSource.data = this.entityArrayValues;
1012
2906
  EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
2907
+ this.checkIsArrayItemValid();
2908
+ this.emitChange();
1013
2909
  }
1014
2910
  /**
1015
2911
  * Cancels adding the array item defined in the dialog.
@@ -1017,130 +2913,59 @@ class NgxMatEntityInputComponent {
1017
2913
  cancelAddArrayItem() {
1018
2914
  this.addArrayItemDialogRef.close();
1019
2915
  EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
2916
+ this.emitChange();
1020
2917
  }
1021
2918
  /**
1022
- * Removes all selected entries from the array.
2919
+ * Removes all selected entries from the entity array.
2920
+ *
2921
+ * @param selection - The selection containing the items to remove.
2922
+ * @param values - The values of the dataSource.
2923
+ * @param dataSource - The dataSource.
1023
2924
  */
1024
- remove() {
1025
- this.selection.selected.forEach(s => {
1026
- this.entityArrayValues.splice(this.entityArrayValues.indexOf(s), 1);
2925
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2926
+ remove(selection, values, dataSource) {
2927
+ selection.selected.forEach(s => {
2928
+ values.splice(values.indexOf(s), 1);
1027
2929
  });
1028
- this.dataSource.data = this.entityArrayValues;
1029
- this.selection.clear();
2930
+ dataSource.data = values;
2931
+ selection.clear();
2932
+ this.emitChange();
1030
2933
  }
1031
2934
  /**
1032
2935
  * Toggles all array-items in the table.
2936
+ *
2937
+ * @param selection - The selection to toggle.
2938
+ * @param dataSource - The dataSource of the selection.
1033
2939
  */
1034
- masterToggle() {
1035
- if (this.isAllSelected()) {
1036
- this.selection.clear();
2940
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2941
+ masterToggle(selection, dataSource) {
2942
+ if (this.isAllSelected(selection, dataSource)) {
2943
+ selection.clear();
1037
2944
  }
1038
2945
  else {
1039
- this.dataSource.data.forEach((row) => this.selection.select(row));
2946
+ dataSource.data.forEach(row => selection.select(row));
1040
2947
  }
1041
2948
  }
1042
2949
  /**
1043
2950
  * Checks if all array-items in the table have been selected.
1044
2951
  * This is needed to display the "masterToggle"-checkbox correctly.
1045
2952
  *
2953
+ * @param selection - The selection to check.
2954
+ * @param dataSource - The dataSource of the selection.
1046
2955
  * @returns Whether or not all array-items in the table have been selected.
1047
2956
  */
1048
- isAllSelected() {
1049
- const numSelected = this.selection.selected.length;
1050
- const numRows = this.dataSource.data.length;
2957
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2958
+ isAllSelected(selection, dataSource) {
2959
+ const numSelected = selection.selected.length;
2960
+ const numRows = dataSource.data.length;
1051
2961
  return numSelected === numRows;
1052
2962
  }
1053
- /**
1054
- * Handles adding strings to the chipsArray.
1055
- * Checks validation and also creates a new array if it is undefined.
1056
- * This is needed because two things are validated: The array itself
1057
- * and the contents of the array. And we need a way to display an
1058
- * mat-error. As the only validation for the array is whether or not
1059
- * it contains values, we can set it to undefined when the last element is removed
1060
- * (removeStringChipArrayValue). That way we can use the "required" validator.
1061
- *
1062
- * @param event - The event that fires when a new chip is completed.
1063
- */
1064
- addStringChipArrayValue(event) {
1065
- const value = (event.value || '').trim();
1066
- if (value) {
1067
- if (this.metadataStringChipsArray.minLength && value.length < this.metadataStringChipsArray.minLength) {
1068
- return;
1069
- }
1070
- if (this.metadataStringChipsArray.maxLength && value.length > this.metadataStringChipsArray.maxLength) {
1071
- return;
1072
- }
1073
- if (this.metadataStringChipsArray.regex && !value.match(this.metadataStringChipsArray.regex)) {
1074
- return;
1075
- }
1076
- if (!this.stringChipsArrayValues) {
1077
- if (!this.entity[this.propertyKey]) {
1078
- this.entity[this.propertyKey] = [];
1079
- }
1080
- this.stringChipsArrayValues = this.entity[this.propertyKey];
1081
- }
1082
- this.stringChipsArrayValues.push(value);
1083
- }
1084
- event.chipInput.clear();
1085
- }
1086
- /**
1087
- * Removes the given value from the array.
1088
- * Sets the array to undefined if it is now empty.
1089
- * This is needed because two things are validated: The array itself
1090
- * and the contents of the array. And we need a way to display an
1091
- * mat-error. As the only validation for the array is whether or not
1092
- * it is empty, setting it to undefined here enables us to use the "required" validator.
1093
- *
1094
- * @param value - The string to remove from the array.
1095
- */
1096
- removeStringChipArrayValue(value) {
1097
- this.stringChipsArrayValues.splice(this.stringChipsArrayValues.indexOf(value), 1);
1098
- if (!this.stringChipsArrayValues.length) {
1099
- this.entity[this.propertyKey] = undefined;
1100
- this.stringChipsArrayValues = this.entity[this.propertyKey];
1101
- }
1102
- }
1103
- /**
1104
- * Handles adding a string to the array when an autocomplete value has been selected.
1105
- *
1106
- * @param event - The autocomplete selected event.
1107
- * @param chipsInput - The element where the user typed the value.
1108
- */
1109
- selected(event, chipsInput) {
1110
- const value = (event.option.viewValue || '').trim();
1111
- if (this.metadataStringChipsArray.minLength && value.length < this.metadataStringChipsArray.minLength) {
1112
- return;
1113
- }
1114
- if (this.metadataStringChipsArray.maxLength && value.length > this.metadataStringChipsArray.maxLength) {
1115
- return;
1116
- }
1117
- if (this.metadataStringChipsArray.regex && !value.match(this.metadataStringChipsArray.regex)) {
1118
- return;
1119
- }
1120
- if (!this.stringChipsArrayValues) {
1121
- if (!this.entity[this.propertyKey]) {
1122
- this.entity[this.propertyKey] = [];
1123
- }
1124
- this.stringChipsArrayValues = this.entity[this.propertyKey];
1125
- }
1126
- this.stringChipsArrayValues.push(value);
1127
- chipsInput.value = '';
1128
- }
1129
- /**
1130
- * Dynamically filters the Autocomplete options when the user inputs something.
1131
- *
1132
- * @param input - The input of the user.
1133
- */
1134
- filterAutocompleteStrings(input) {
1135
- const filterValue = input.toLowerCase();
1136
- this.filteredAutocompleteStrings = this.autocompleteStrings.filter(s => s.toLowerCase().includes(filterValue));
1137
- }
1138
2963
  }
1139
2964
  NgxMatEntityInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputComponent, deps: [{ token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
1140
- NgxMatEntityInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: { entity: "entity", propertyKey: "propertyKey", getValidationErrorMessage: "getValidationErrorMessage", hideOmitForCreate: "hideOmitForCreate", hideOmitForEdit: "hideOmitForEdit" }, viewQueries: [{ propertyName: "addArrayItemDialog", first: true, predicate: ["addArrayItemDialog"], descendants: true }], ngImport: i0, template: "<div [ngSwitch]=\"type\" *ngIf=\"!(hideOmitForCreate && metadata.omitForCreate) && !(hideOmitForEdit && metadata.omitForUpdate)\">\n <!-------------------------------------------->\n <!-----------------Strings-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.STRING\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [pattern]=\"metadataDefaultString.regex ? metadataDefaultString.regex : '[\\\\s\\\\S]*'\"\n [minlength]=\"metadataDefaultString.minLength ? metadataDefaultString.minLength : null\"\n [maxlength]=\"metadataDefaultString.maxLength ? metadataDefaultString.maxLength : null\"\n />\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.STRING_TEXTBOX\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <textarea\n matInput\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString()\"\n #model=\"ngModel\"\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"10\"\n [required]=\"metadata.required\"\n [minlength]=\"metadataTextboxString.minLength ? metadataTextboxString.minLength : null\"\n [maxlength]=\"metadataTextboxString.maxLength ? metadataTextboxString.maxLength : null\"\n >\n </textarea>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.STRING_AUTOCOMPLETE\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString()\"\n #model=\"ngModel\"\n [matAutocomplete]=\"auto\"\n (keyup)=\"filterAutocompleteStrings(entity[propertyKey])\"\n [required]=\"metadata.required\"\n [minlength]=\"metadataAutocompleteString.minLength ? metadataAutocompleteString.minLength : null\"\n [maxlength]=\"metadataAutocompleteString.maxLength ? metadataAutocompleteString.maxLength : null\"\n [pattern]=\"metadataAutocompleteString.regex ? metadataAutocompleteString.regex : '[\\\\s\\\\S]*'\"\n />\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let value of filteredAutocompleteStrings\" [value]=\"value\">\n {{value}}\n </mat-option>\n </mat-autocomplete>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.STRING_DROPDOWN\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\" [required]=\"metadata.required\">\n <mat-option *ngFor=\"let value of metadataDropdownString.dropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <!-------------------------------------------->\n <!-----------------Booleans------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_CHECKBOX\">\n <mat-form-field class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-checkbox (click)=\"model.control.markAsTouched()\" [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\"></mat-checkbox>\n <!-- hidden input is needed so that the checkbox can be used inside a mat-form-field -->\n <input matInput hidden\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString() + 'Helper'\"\n #model=\"ngModel\"\n [pattern]=\"metadata.required ? 'true' : '[\\\\s\\\\S]*'\"\n [required]=\"metadata.required\">\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <mat-form-field class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-slide-toggle (click)=\"model.control.markAsTouched()\" [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\"></mat-slide-toggle>\n <!-- hidden input is needed so that the toggle can be used inside a mat-form-field -->\n <input matInput hidden\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString() + 'Helper'\"\n #model=\"ngModel\"\n [pattern]=\"metadata.required ? 'true' : '[\\\\s\\\\S]*'\"\n [required]=\"metadata.required\">\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_DROPDOWN\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\" [required]=\"metadata.required\">\n <mat-option [value]=\"undefined\">-</mat-option>\n <mat-option [value]=\"true\">{{metadataDropdownBoolean.dropdownTrue}}</mat-option>\n <mat-option [value]=\"false\">{{metadataDropdownBoolean.dropdownFalse}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <!-------------------------------------------->\n <!------------------Numbers------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n type=\"number\"\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadataDefaultNumber.min ? metadataDefaultNumber.min : null\"\n [max]=\"metadataDefaultNumber.max ? metadataDefaultNumber.max : null\"\n />\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_DROPDOWN\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\" [required]=\"metadata.required\">\n <mat-option *ngFor=\"let value of metadataDropdownNumber.dropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Object------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.OBJECT\">\n <b>{{metadataDefaultObject.displayName}}</b>\n <!-- iterates over the object properties -->\n\n <div class=\"row\" *ngFor=\"let row of objectPropertyRows\">\n <!--\n displays another ngx-material-entity with the:\n object as the entity,\n the current key in the loop received by the keyvalue direction as the propertyKey\n and the getValidationErrorMessage of the current component\n -->\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n class=\"col-lg-{{getWidth(objectProperty, key, 'lg')}} col-md-{{getWidth(objectProperty, key, 'md')}} col-sm-{{getWidth(objectProperty, key, 'sm')}}\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div class=\"entityArray\" *ngSwitchCase=\"DecoratorTypes.ARRAY\">\n <div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n\n <div style=\"padding-bottom: 10px\">\n <b>{{metadataEntityArray.displayName}}</b>\n </div>\n <div *ngIf=\"metadataEntityArray.createInline\">\n <div class=\"row\" *ngFor=\"let row of arrayItemInlineRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n class=\"col-lg-{{getWidth(arrayItem, key, 'lg')}} col-md-{{getWidth(arrayItem, key, 'md')}} col-sm-{{getWidth(arrayItem, key, 'sm')}}\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n \n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"metadataEntityArray.createInline && !EntityUtilities.isEntityValid(arrayItem, 'create')\"\n (click)=\"add()\">\n {{metadataEntityArray.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadataEntityArray.removeButtonLabel}}\n </button>\n </div>\n \n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\" class=\"module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadataEntityArray.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n \n <div class=\"array-error\" *ngIf=\"metadataEntityArray.required && !dataSource.data.length\">\n {{metadataEntityArray.missingErrorMessage}}\n </div>\n </div>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_CHIPS\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip *ngFor=\"let value of stringChipsArrayValues\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove>\n <i class=\"{{metadataStringChipsArray.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input matInput\n [matChipInputFor]=\"chipList\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addStringChipArrayValue($event)\"\n [(ngModel)]=\"chipsInput\" [name]=\"propertyKey.toString()\" #chipsModel=\"ngModel\"\n [minlength]='metadataStringChipsArray.minLength ? metadataStringChipsArray.minLength : null'\n [maxlength]='metadataStringChipsArray.maxLength ? metadataStringChipsArray.maxLength : null'\n [pattern]=\"metadataStringChipsArray.regex ? metadataStringChipsArray.regex : '[\\\\s\\\\S]*'\"\n >\n <mat-error *ngIf=\"chipsModel.errors\">{{getValidationErrorMessage(chipsModel)}}</mat-error>\n </mat-chip-list>\n <mat-error *ngIf=\"!chipsModel.errors\">{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip *ngFor=\"let value of stringChipsArrayValues\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove>\n <i class=\"{{metadataStringChipsArray.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input matInput\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addStringChipArrayValue($event)\"\n (keyup)=\"filterAutocompleteStrings(chipsInput)\"\n [(ngModel)]=\"chipsInput\" [name]=\"propertyKey.toString()\" #chipsModel=\"ngModel\"\n #chipsElement\n [minlength]='metadataStringChipsArray.minLength ? metadataStringChipsArray.minLength : null'\n [maxlength]='metadataStringChipsArray.maxLength ? metadataStringChipsArray.maxLength : null'\n [pattern]=\"metadataStringChipsArray.regex ? metadataStringChipsArray.regex : '[\\\\s\\\\S]*'\"\n >\n <mat-error *ngIf=\"chipsModel.errors\">{{getValidationErrorMessage(chipsModel)}}</mat-error>\n </mat-chip-list>\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event, chipsElement)\">\n <mat-option *ngFor=\"let value of filteredAutocompleteStrings\" [value]=\"value\">\n {{value}}\n </mat-option>\n </mat-autocomplete>\n <mat-error *ngIf=\"!chipsModel.errors\">{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchDefault>ERROR: The type {{type}} is not known.</div>\n</div>\n\n<!--------------------------------------------------------->\n<!--------------------Add Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #addArrayItemDialog>\n <h2 mat-dialog-title>{{dialogData.createDialogData.title}}</h2>\n\n <mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"dialogData.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"dialogData.getValidationErrorMessage\"\n class=\"col-lg-{{getWidth(dialogData.entity, key, 'lg')}} col-md-{{getWidth(dialogData.entity, key, 'md')}} col-sm-{{getWidth(dialogData.entity, key, 'sm')}}\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n </mat-dialog-content>\n\n <mat-dialog-actions>\n <button mat-raised-button (click)=\"addArrayItem()\" [disabled]=\"!EntityUtilities.isEntityValid(dialogData.entity, 'create')\">\n {{dialogData.createDialogData.createButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancelAddArrayItem()\" class=\"cancel-button\">\n {{dialogData.createDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n\n</ng-template>", styles: ["mat-form-field{width:100%}::ng-deep .hideUnderline .mat-form-field-underline{opacity:0%}.entityArray .buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}.entityArray mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.entityArray .mat-column-select{flex:0 0 75px}.entityArray .array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"], components: [{ type: i2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i3$1.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { type: i4.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i5.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i7.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex", "name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "checked"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: ["entity", "propertyKey", "getValidationErrorMessage", "hideOmitForCreate", "hideOmitForEdit"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { type: i10.MatChipList, selector: "mat-chip-list", inputs: ["errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }], directives: [{ type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i11.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i11.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i2.MatLabel, selector: "mat-label" }, { type: i12.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i13.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i13.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i13.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i13.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i13.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i13.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i13.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i2.MatError, selector: "mat-error", inputs: ["id"] }, { type: i14.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { type: i3$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i13.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i13.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i13.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i9.MatCellDef, selector: "[matCellDef]" }, { type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { type: i10.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { type: i10.MatChipRemove, selector: "[matChipRemove]" }, { type: i10.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { type: i11.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i13.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i13.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i13.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
2965
+ NgxMatEntityInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: { entity: "entity", propertyKey: "propertyKey", getValidationErrorMessage: "getValidationErrorMessage", hideOmitForCreate: "hideOmitForCreate", hideOmitForEdit: "hideOmitForEdit" }, outputs: { inputChangeEvent: "inputChangeEvent" }, viewQueries: [{ propertyName: "addArrayItemDialog", first: true, predicate: ["addArrayItemDialog"], descendants: true }], ngImport: i0, template: "<div [ngSwitch]=\"type\" *ngIf=\"!(hideOmitForCreate && metadata.omitForCreate) && !(hideOmitForEdit && metadata.omitForUpdate)\">\n <!-------------------------------------------->\n <!-----------------Strings-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.STRING\">\n <string-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></string-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_TEXTBOX\">\n <string-textbox-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></string-textbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_AUTOCOMPLETE\">\n <string-autocomplete-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></string-autocomplete-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_DROPDOWN\">\n <string-dropdown-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></string-dropdown-input>\n </div>\n\n <!-------------------------------------------->\n <!-----------------Booleans------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_CHECKBOX\">\n <boolean-checkbox-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></boolean-checkbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <boolean-toggle-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></boolean-toggle-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_DROPDOWN\">\n <boolean-dropdown-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></boolean-dropdown-input>\n </div>\n\n <!-------------------------------------------->\n <!------------------Numbers------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER\">\n <number-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></number-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_DROPDOWN\">\n <number-dropdown-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></number-dropdown-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Object------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.OBJECT\">\n <b>{{metadataDefaultObject.displayName}}</b>\n <!-- iterates over the object properties -->\n <div class=\"row\" *ngFor=\"let row of objectPropertyRows\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n class=\"col-lg-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.getWidth(objectProperty, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div class=\"entityArray\" *ngSwitchCase=\"DecoratorTypes.ARRAY\">\n <div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n <div style=\"padding-bottom: 10px\">\n <b>{{metadataEntityArray.displayName}}</b>\n </div>\n <div *ngIf=\"metadataEntityArray.createInline\">\n <div class=\"row\" *ngFor=\"let row of arrayItemInlineRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n \n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"metadataEntityArray.createInline && !isArrayItemValid\"\n (click)=\"addEntity()\">\n {{metadataEntityArray.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove(selection, entityArrayValues, dataSource)\">\n {{metadataEntityArray.removeButtonLabel}}\n </button>\n </div>\n \n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle(selection, dataSource) : null\" [checked]=\"selection.hasValue() && isAllSelected(selection, dataSource)\" [indeterminate]=\"selection.hasValue() && !isAllSelected(selection, dataSource)\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadataEntityArray.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n \n <div class=\"array-error\" *ngIf=\"metadataEntityArray.required && !dataSource.data.length\">\n {{metadataEntityArray.missingErrorMessage}}\n </div>\n </div>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE\">\n <array-date-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></array-date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_TIME\">\n <array-date-time-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></array-date-time-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_RANGE\">\n <array-date-range-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></array-date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_CHIPS\">\n <array-string-chips-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></array-string-chips-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS\">\n <array-string-autocomplete-chips (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></array-string-autocomplete-chips>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Dates-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.DATE\">\n <date-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_RANGE\">\n <date-range-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_TIME\">\n <date-time-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></date-time-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Files-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.FILE_DEFAULT\">\n <file-default-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></file-default-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.FILE_IMAGE\">\n <file-image-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></file-image-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Custom------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.CUSTOM\">\n <custom-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></custom-input>\n </div>\n\n <div *ngSwitchDefault>ERROR: The type {{type}} is not known.</div>\n</div>\n\n<!--------------------------------------------------------->\n<!--------------------Add Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #addArrayItemDialog>\n <h2 mat-dialog-title>{{dialogData.createDialogData.title}}</h2>\n\n <mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"dialogData.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"dialogData.getValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(dialogData.entity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(dialogData.entity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(dialogData.entity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsDialogArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n </mat-dialog-content>\n\n <mat-dialog-actions>\n <button mat-raised-button (click)=\"addArrayItem()\" [disabled]=\"!isDialogArrayItemValid\">\n {{dialogData.createDialogData.createButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancelAddArrayItem()\" class=\"cancel-button\">\n {{dialogData.createDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n\n</ng-template>", styles: ["mat-form-field{width:100%}.entityArray .buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}.entityArray mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.entityArray .mat-column-select{flex:0 0 75px}.entityArray .array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"], components: [{ type: StringInputComponent, selector: "string-input" }, { type: StringTextboxInputComponent, selector: "string-textbox-input" }, { type: StringAutocompleteInputComponent, selector: "string-autocomplete-input" }, { type: StringDropdownInputComponent, selector: "string-dropdown-input" }, { type: BooleanCheckboxInputComponent, selector: "boolean-checkbox-input" }, { type: BooleanToggleInputComponent, selector: "boolean-toggle-input" }, { type: BooleanDropdownInputComponent, selector: "boolean-dropdown-input" }, { type: NumberInputComponent, selector: "number-input" }, { type: NumberDropdownInputComponent, selector: "number-dropdown-input" }, { type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: ["entity", "propertyKey", "getValidationErrorMessage", "hideOmitForCreate", "hideOmitForEdit"], outputs: ["inputChangeEvent"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i4$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i4$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { type: ArrayDateInputComponent, selector: "array-date-input" }, { type: ArrayDateTimeInputComponent, selector: "array-date-time-input" }, { type: ArrayDateRangeInputComponent, selector: "array-date-range-input" }, { type: ArrayStringChipsInputComponent, selector: "array-string-chips-input" }, { type: ArrayStringAutocompleteChipsComponent, selector: "array-string-autocomplete-chips" }, { type: DateInputComponent, selector: "date-input" }, { type: DateRangeInputComponent, selector: "date-range-input" }, { type: DateTimeInputComponent, selector: "date-time-input" }, { type: FileDefaultInputComponent, selector: "file-default-input" }, { type: FileImageInputComponent, selector: "file-image-input" }, { type: CustomInputComponent, selector: "custom-input" }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i4$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i4$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i4$2.MatCellDef, selector: "[matCellDef]" }, { type: i4$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i4$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i4$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { type: i4.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i3$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i3$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i3$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
1141
2966
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputComponent, decorators: [{
1142
2967
  type: Component,
1143
- args: [{ selector: 'ngx-mat-entity-input', template: "<div [ngSwitch]=\"type\" *ngIf=\"!(hideOmitForCreate && metadata.omitForCreate) && !(hideOmitForEdit && metadata.omitForUpdate)\">\n <!-------------------------------------------->\n <!-----------------Strings-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.STRING\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [pattern]=\"metadataDefaultString.regex ? metadataDefaultString.regex : '[\\\\s\\\\S]*'\"\n [minlength]=\"metadataDefaultString.minLength ? metadataDefaultString.minLength : null\"\n [maxlength]=\"metadataDefaultString.maxLength ? metadataDefaultString.maxLength : null\"\n />\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.STRING_TEXTBOX\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <textarea\n matInput\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString()\"\n #model=\"ngModel\"\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"10\"\n [required]=\"metadata.required\"\n [minlength]=\"metadataTextboxString.minLength ? metadataTextboxString.minLength : null\"\n [maxlength]=\"metadataTextboxString.maxLength ? metadataTextboxString.maxLength : null\"\n >\n </textarea>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.STRING_AUTOCOMPLETE\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString()\"\n #model=\"ngModel\"\n [matAutocomplete]=\"auto\"\n (keyup)=\"filterAutocompleteStrings(entity[propertyKey])\"\n [required]=\"metadata.required\"\n [minlength]=\"metadataAutocompleteString.minLength ? metadataAutocompleteString.minLength : null\"\n [maxlength]=\"metadataAutocompleteString.maxLength ? metadataAutocompleteString.maxLength : null\"\n [pattern]=\"metadataAutocompleteString.regex ? metadataAutocompleteString.regex : '[\\\\s\\\\S]*'\"\n />\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let value of filteredAutocompleteStrings\" [value]=\"value\">\n {{value}}\n </mat-option>\n </mat-autocomplete>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.STRING_DROPDOWN\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\" [required]=\"metadata.required\">\n <mat-option *ngFor=\"let value of metadataDropdownString.dropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <!-------------------------------------------->\n <!-----------------Booleans------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_CHECKBOX\">\n <mat-form-field class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-checkbox (click)=\"model.control.markAsTouched()\" [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\"></mat-checkbox>\n <!-- hidden input is needed so that the checkbox can be used inside a mat-form-field -->\n <input matInput hidden\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString() + 'Helper'\"\n #model=\"ngModel\"\n [pattern]=\"metadata.required ? 'true' : '[\\\\s\\\\S]*'\"\n [required]=\"metadata.required\">\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <mat-form-field class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-slide-toggle (click)=\"model.control.markAsTouched()\" [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\"></mat-slide-toggle>\n <!-- hidden input is needed so that the toggle can be used inside a mat-form-field -->\n <input matInput hidden\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString() + 'Helper'\"\n #model=\"ngModel\"\n [pattern]=\"metadata.required ? 'true' : '[\\\\s\\\\S]*'\"\n [required]=\"metadata.required\">\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_DROPDOWN\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\" [required]=\"metadata.required\">\n <mat-option [value]=\"undefined\">-</mat-option>\n <mat-option [value]=\"true\">{{metadataDropdownBoolean.dropdownTrue}}</mat-option>\n <mat-option [value]=\"false\">{{metadataDropdownBoolean.dropdownFalse}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <!-------------------------------------------->\n <!------------------Numbers------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n type=\"number\"\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadataDefaultNumber.min ? metadataDefaultNumber.min : null\"\n [max]=\"metadataDefaultNumber.max ? metadataDefaultNumber.max : null\"\n />\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_DROPDOWN\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\" [required]=\"metadata.required\">\n <mat-option *ngFor=\"let value of metadataDropdownNumber.dropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Object------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.OBJECT\">\n <b>{{metadataDefaultObject.displayName}}</b>\n <!-- iterates over the object properties -->\n\n <div class=\"row\" *ngFor=\"let row of objectPropertyRows\">\n <!--\n displays another ngx-material-entity with the:\n object as the entity,\n the current key in the loop received by the keyvalue direction as the propertyKey\n and the getValidationErrorMessage of the current component\n -->\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n class=\"col-lg-{{getWidth(objectProperty, key, 'lg')}} col-md-{{getWidth(objectProperty, key, 'md')}} col-sm-{{getWidth(objectProperty, key, 'sm')}}\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div class=\"entityArray\" *ngSwitchCase=\"DecoratorTypes.ARRAY\">\n <div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n\n <div style=\"padding-bottom: 10px\">\n <b>{{metadataEntityArray.displayName}}</b>\n </div>\n <div *ngIf=\"metadataEntityArray.createInline\">\n <div class=\"row\" *ngFor=\"let row of arrayItemInlineRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n class=\"col-lg-{{getWidth(arrayItem, key, 'lg')}} col-md-{{getWidth(arrayItem, key, 'md')}} col-sm-{{getWidth(arrayItem, key, 'sm')}}\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n \n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"metadataEntityArray.createInline && !EntityUtilities.isEntityValid(arrayItem, 'create')\"\n (click)=\"add()\">\n {{metadataEntityArray.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadataEntityArray.removeButtonLabel}}\n </button>\n </div>\n \n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\" class=\"module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadataEntityArray.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n \n <div class=\"array-error\" *ngIf=\"metadataEntityArray.required && !dataSource.data.length\">\n {{metadataEntityArray.missingErrorMessage}}\n </div>\n </div>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_CHIPS\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip *ngFor=\"let value of stringChipsArrayValues\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove>\n <i class=\"{{metadataStringChipsArray.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input matInput\n [matChipInputFor]=\"chipList\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addStringChipArrayValue($event)\"\n [(ngModel)]=\"chipsInput\" [name]=\"propertyKey.toString()\" #chipsModel=\"ngModel\"\n [minlength]='metadataStringChipsArray.minLength ? metadataStringChipsArray.minLength : null'\n [maxlength]='metadataStringChipsArray.maxLength ? metadataStringChipsArray.maxLength : null'\n [pattern]=\"metadataStringChipsArray.regex ? metadataStringChipsArray.regex : '[\\\\s\\\\S]*'\"\n >\n <mat-error *ngIf=\"chipsModel.errors\">{{getValidationErrorMessage(chipsModel)}}</mat-error>\n </mat-chip-list>\n <mat-error *ngIf=\"!chipsModel.errors\">{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-chip *ngFor=\"let value of stringChipsArrayValues\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove>\n <i class=\"{{metadataStringChipsArray.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input matInput\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addStringChipArrayValue($event)\"\n (keyup)=\"filterAutocompleteStrings(chipsInput)\"\n [(ngModel)]=\"chipsInput\" [name]=\"propertyKey.toString()\" #chipsModel=\"ngModel\"\n #chipsElement\n [minlength]='metadataStringChipsArray.minLength ? metadataStringChipsArray.minLength : null'\n [maxlength]='metadataStringChipsArray.maxLength ? metadataStringChipsArray.maxLength : null'\n [pattern]=\"metadataStringChipsArray.regex ? metadataStringChipsArray.regex : '[\\\\s\\\\S]*'\"\n >\n <mat-error *ngIf=\"chipsModel.errors\">{{getValidationErrorMessage(chipsModel)}}</mat-error>\n </mat-chip-list>\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event, chipsElement)\">\n <mat-option *ngFor=\"let value of filteredAutocompleteStrings\" [value]=\"value\">\n {{value}}\n </mat-option>\n </mat-autocomplete>\n <mat-error *ngIf=\"!chipsModel.errors\">{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchDefault>ERROR: The type {{type}} is not known.</div>\n</div>\n\n<!--------------------------------------------------------->\n<!--------------------Add Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #addArrayItemDialog>\n <h2 mat-dialog-title>{{dialogData.createDialogData.title}}</h2>\n\n <mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"dialogData.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"dialogData.getValidationErrorMessage\"\n class=\"col-lg-{{getWidth(dialogData.entity, key, 'lg')}} col-md-{{getWidth(dialogData.entity, key, 'md')}} col-sm-{{getWidth(dialogData.entity, key, 'sm')}}\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n </mat-dialog-content>\n\n <mat-dialog-actions>\n <button mat-raised-button (click)=\"addArrayItem()\" [disabled]=\"!EntityUtilities.isEntityValid(dialogData.entity, 'create')\">\n {{dialogData.createDialogData.createButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancelAddArrayItem()\" class=\"cancel-button\">\n {{dialogData.createDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n\n</ng-template>", styles: ["mat-form-field{width:100%}::ng-deep .hideUnderline .mat-form-field-underline{opacity:0%}.entityArray .buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}.entityArray mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.entityArray .mat-column-select{flex:0 0 75px}.entityArray .array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"] }]
2968
+ args: [{ selector: 'ngx-mat-entity-input', template: "<div [ngSwitch]=\"type\" *ngIf=\"!(hideOmitForCreate && metadata.omitForCreate) && !(hideOmitForEdit && metadata.omitForUpdate)\">\n <!-------------------------------------------->\n <!-----------------Strings-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.STRING\">\n <string-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></string-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_TEXTBOX\">\n <string-textbox-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></string-textbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_AUTOCOMPLETE\">\n <string-autocomplete-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></string-autocomplete-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_DROPDOWN\">\n <string-dropdown-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></string-dropdown-input>\n </div>\n\n <!-------------------------------------------->\n <!-----------------Booleans------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_CHECKBOX\">\n <boolean-checkbox-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></boolean-checkbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <boolean-toggle-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></boolean-toggle-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_DROPDOWN\">\n <boolean-dropdown-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></boolean-dropdown-input>\n </div>\n\n <!-------------------------------------------->\n <!------------------Numbers------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER\">\n <number-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></number-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_DROPDOWN\">\n <number-dropdown-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></number-dropdown-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Object------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.OBJECT\">\n <b>{{metadataDefaultObject.displayName}}</b>\n <!-- iterates over the object properties -->\n <div class=\"row\" *ngFor=\"let row of objectPropertyRows\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n class=\"col-lg-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.getWidth(objectProperty, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div class=\"entityArray\" *ngSwitchCase=\"DecoratorTypes.ARRAY\">\n <div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n <div style=\"padding-bottom: 10px\">\n <b>{{metadataEntityArray.displayName}}</b>\n </div>\n <div *ngIf=\"metadataEntityArray.createInline\">\n <div class=\"row\" *ngFor=\"let row of arrayItemInlineRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n \n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"metadataEntityArray.createInline && !isArrayItemValid\"\n (click)=\"addEntity()\">\n {{metadataEntityArray.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove(selection, entityArrayValues, dataSource)\">\n {{metadataEntityArray.removeButtonLabel}}\n </button>\n </div>\n \n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle(selection, dataSource) : null\" [checked]=\"selection.hasValue() && isAllSelected(selection, dataSource)\" [indeterminate]=\"selection.hasValue() && !isAllSelected(selection, dataSource)\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadataEntityArray.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n \n <div class=\"array-error\" *ngIf=\"metadataEntityArray.required && !dataSource.data.length\">\n {{metadataEntityArray.missingErrorMessage}}\n </div>\n </div>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE\">\n <array-date-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></array-date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_TIME\">\n <array-date-time-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></array-date-time-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_RANGE\">\n <array-date-range-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></array-date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_CHIPS\">\n <array-string-chips-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></array-string-chips-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS\">\n <array-string-autocomplete-chips (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></array-string-autocomplete-chips>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Dates-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.DATE\">\n <date-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_RANGE\">\n <date-range-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_TIME\">\n <date-time-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></date-time-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Files-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.FILE_DEFAULT\">\n <file-default-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></file-default-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.FILE_IMAGE\">\n <file-image-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></file-image-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Custom------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.CUSTOM\">\n <custom-input (inputChangeEvent)=\"emitChange()\" [entity]=\"internalEntity\" [key]=\"internalPropertyKey\" [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"></custom-input>\n </div>\n\n <div *ngSwitchDefault>ERROR: The type {{type}} is not known.</div>\n</div>\n\n<!--------------------------------------------------------->\n<!--------------------Add Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #addArrayItemDialog>\n <h2 mat-dialog-title>{{dialogData.createDialogData.title}}</h2>\n\n <mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"dialogData.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"dialogData.getValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(dialogData.entity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(dialogData.entity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(dialogData.entity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsDialogArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n </mat-dialog-content>\n\n <mat-dialog-actions>\n <button mat-raised-button (click)=\"addArrayItem()\" [disabled]=\"!isDialogArrayItemValid\">\n {{dialogData.createDialogData.createButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancelAddArrayItem()\" class=\"cancel-button\">\n {{dialogData.createDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n\n</ng-template>", styles: ["mat-form-field{width:100%}.entityArray .buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}.entityArray mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.entityArray .mat-column-select{flex:0 0 75px}.entityArray .array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"] }]
1144
2969
  }], ctorParameters: function () { return [{ type: i1.MatDialog }]; }, propDecorators: { entity: [{
1145
2970
  type: Input
1146
2971
  }], propertyKey: [{
@@ -1151,6 +2976,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
1151
2976
  type: Input
1152
2977
  }], hideOmitForEdit: [{
1153
2978
  type: Input
2979
+ }], inputChangeEvent: [{
2980
+ type: Output
1154
2981
  }], addArrayItemDialog: [{
1155
2982
  type: ViewChild,
1156
2983
  args: ['addArrayItemDialog']
@@ -1159,7 +2986,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
1159
2986
  class NgxMatEntityInputModule {
1160
2987
  }
1161
2988
  NgxMatEntityInputModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1162
- NgxMatEntityInputModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, declarations: [NgxMatEntityInputComponent], imports: [CommonModule,
2989
+ NgxMatEntityInputModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, declarations: [StringInputComponent,
2990
+ StringTextboxInputComponent,
2991
+ StringAutocompleteInputComponent,
2992
+ StringDropdownInputComponent,
2993
+ BooleanCheckboxInputComponent,
2994
+ BooleanToggleInputComponent,
2995
+ BooleanDropdownInputComponent,
2996
+ NumberInputComponent,
2997
+ NumberDropdownInputComponent,
2998
+ ArrayStringChipsInputComponent,
2999
+ ArrayStringAutocompleteChipsComponent,
3000
+ DateInputComponent,
3001
+ DateRangeInputComponent,
3002
+ DateTimeInputComponent,
3003
+ ArrayDateInputComponent,
3004
+ ArrayDateTimeInputComponent,
3005
+ ArrayDateRangeInputComponent,
3006
+ FileInputComponent,
3007
+ FileImageInputComponent,
3008
+ FileDefaultInputComponent,
3009
+ DragDropDirective,
3010
+ CustomInputComponent,
3011
+ NgxMatEntityInputComponent], imports: [CommonModule,
1163
3012
  MatInputModule,
1164
3013
  FormsModule,
1165
3014
  MatFormFieldModule,
@@ -1171,7 +3020,8 @@ NgxMatEntityInputModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0",
1171
3020
  MatIconModule,
1172
3021
  MatTableModule,
1173
3022
  MatDialogModule,
1174
- MatButtonModule], exports: [NgxMatEntityInputComponent] });
3023
+ MatButtonModule,
3024
+ MatDatepickerModule], exports: [NgxMatEntityInputComponent] });
1175
3025
  NgxMatEntityInputModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, imports: [[
1176
3026
  CommonModule,
1177
3027
  MatInputModule,
@@ -1185,13 +3035,36 @@ NgxMatEntityInputModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0",
1185
3035
  MatIconModule,
1186
3036
  MatTableModule,
1187
3037
  MatDialogModule,
1188
- MatButtonModule
3038
+ MatButtonModule,
3039
+ MatDatepickerModule
1189
3040
  ]] });
1190
3041
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, decorators: [{
1191
3042
  type: NgModule,
1192
3043
  args: [{
1193
3044
  declarations: [
1194
- NgxMatEntityInputComponent,
3045
+ StringInputComponent,
3046
+ StringTextboxInputComponent,
3047
+ StringAutocompleteInputComponent,
3048
+ StringDropdownInputComponent,
3049
+ BooleanCheckboxInputComponent,
3050
+ BooleanToggleInputComponent,
3051
+ BooleanDropdownInputComponent,
3052
+ NumberInputComponent,
3053
+ NumberDropdownInputComponent,
3054
+ ArrayStringChipsInputComponent,
3055
+ ArrayStringAutocompleteChipsComponent,
3056
+ DateInputComponent,
3057
+ DateRangeInputComponent,
3058
+ DateTimeInputComponent,
3059
+ ArrayDateInputComponent,
3060
+ ArrayDateTimeInputComponent,
3061
+ ArrayDateRangeInputComponent,
3062
+ FileInputComponent,
3063
+ FileImageInputComponent,
3064
+ FileDefaultInputComponent,
3065
+ DragDropDirective,
3066
+ CustomInputComponent,
3067
+ NgxMatEntityInputComponent
1195
3068
  ],
1196
3069
  imports: [
1197
3070
  CommonModule,
@@ -1206,7 +3079,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
1206
3079
  MatIconModule,
1207
3080
  MatTableModule,
1208
3081
  MatDialogModule,
1209
- MatButtonModule
3082
+ MatButtonModule,
3083
+ MatDatepickerModule
1210
3084
  ],
1211
3085
  exports: [NgxMatEntityInputComponent]
1212
3086
  }]
@@ -1249,7 +3123,7 @@ class NgxMatEntityCreateDialogComponent {
1249
3123
  this.injector = injector;
1250
3124
  this.dialog = dialog;
1251
3125
  this.EntityUtilities = EntityUtilities;
1252
- this.getWidth = EntityUtilities.getWidth;
3126
+ this.isEntityValid = false;
1253
3127
  }
1254
3128
  ngOnInit() {
1255
3129
  this.data = new CreateEntityDialogDataBuilder(this.inputData).getResult();
@@ -1257,16 +3131,22 @@ class NgxMatEntityCreateDialogComponent {
1257
3131
  this.entityRows = EntityUtilities.getEntityRows(this.data.entity, true);
1258
3132
  this.entityService = this.injector.get(this.data.EntityServiceClass);
1259
3133
  }
3134
+ /**
3135
+ * Checks if the entity is valid.
3136
+ */
3137
+ checkIsEntityValid() {
3138
+ this.isEntityValid = EntityUtilities.isEntityValid(this.data.entity, 'create');
3139
+ }
1260
3140
  /**
1261
3141
  * Tries add the new entity and close the dialog afterwards.
1262
3142
  * Also handles the confirmation if required.
1263
3143
  */
1264
3144
  create() {
1265
- var _a, _b;
1266
- if (!((_a = this.data.createDialogData) === null || _a === void 0 ? void 0 : _a.createRequiresConfirmDialog)) {
1267
- return this.confirmCreate();
3145
+ if (!this.data.createDialogData.createRequiresConfirmDialog) {
3146
+ this.confirmCreate();
3147
+ return;
1268
3148
  }
1269
- const dialogData = new ConfirmDialogDataBuilder((_b = this.data.createDialogData) === null || _b === void 0 ? void 0 : _b.confirmCreateDialogData)
3149
+ const dialogData = new ConfirmDialogDataBuilder(this.data.createDialogData.confirmCreateDialogData)
1270
3150
  .withDefault('text', ['Do you really want to create this entity?'])
1271
3151
  .withDefault('confirmButtonLabel', 'Create')
1272
3152
  .withDefault('title', 'Create')
@@ -1283,7 +3163,7 @@ class NgxMatEntityCreateDialogComponent {
1283
3163
  });
1284
3164
  }
1285
3165
  confirmCreate() {
1286
- this.entityService.create(this.data.entity).then(() => this.dialogRef.close());
3166
+ void this.entityService.create(this.data.entity).then(() => this.dialogRef.close());
1287
3167
  }
1288
3168
  /**
1289
3169
  * Closes the dialog.
@@ -1293,10 +3173,10 @@ class NgxMatEntityCreateDialogComponent {
1293
3173
  }
1294
3174
  }
1295
3175
  NgxMatEntityCreateDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityCreateDialogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }, { token: i0.Injector }, { token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
1296
- NgxMatEntityCreateDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityCreateDialogComponent, selector: "ngx-mat-entity-create-dialog", ngImport: i0, template: "<h2 mat-dialog-title>{{data.createDialogData.title}}</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\">\n <div class=\"row\" *ngFor=\"let row of entityRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{getWidth(data.entity, key, 'lg')}} col-md-{{getWidth(data.entity, key, 'md')}} col-sm-{{getWidth(data.entity, key, 'sm')}}\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"create()\" [disabled]=\"!EntityUtilities.isEntityValid(data.entity, 'create')\">\n {{data.createDialogData.createButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.createDialogData.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}\n"], components: [{ type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: ["entity", "propertyKey", "getValidationErrorMessage", "hideOmitForCreate", "hideOmitForEdit"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i13.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i13.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i13.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
3176
+ NgxMatEntityCreateDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityCreateDialogComponent, selector: "ngx-mat-entity-create-dialog", ngImport: i0, template: "<h2 mat-dialog-title>{{data.createDialogData.title}}</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\">\n <div class=\"row\" *ngFor=\"let row of entityRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(data.entity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(data.entity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(data.entity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsEntityValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"create()\" [disabled]=\"!isEntityValid\">\n {{data.createDialogData.createButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.createDialogData.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}\n"], components: [{ type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: ["entity", "propertyKey", "getValidationErrorMessage", "hideOmitForCreate", "hideOmitForEdit"], outputs: ["inputChangeEvent"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i3$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i3$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i3$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
1297
3177
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityCreateDialogComponent, decorators: [{
1298
3178
  type: Component,
1299
- args: [{ selector: 'ngx-mat-entity-create-dialog', template: "<h2 mat-dialog-title>{{data.createDialogData.title}}</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\">\n <div class=\"row\" *ngFor=\"let row of entityRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{getWidth(data.entity, key, 'lg')}} col-md-{{getWidth(data.entity, key, 'md')}} col-sm-{{getWidth(data.entity, key, 'sm')}}\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"create()\" [disabled]=\"!EntityUtilities.isEntityValid(data.entity, 'create')\">\n {{data.createDialogData.createButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.createDialogData.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}\n"] }]
3179
+ args: [{ selector: 'ngx-mat-entity-create-dialog', template: "<h2 mat-dialog-title>{{data.createDialogData.title}}</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\">\n <div class=\"row\" *ngFor=\"let row of entityRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(data.entity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(data.entity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(data.entity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsEntityValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"create()\" [disabled]=\"!isEntityValid\">\n {{data.createDialogData.createButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.createDialogData.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}\n"] }]
1300
3180
  }], ctorParameters: function () {
1301
3181
  return [{ type: undefined, decorators: [{
1302
3182
  type: Inject,
@@ -1328,6 +3208,7 @@ class EditDialogDataBuilder extends BaseBuilder {
1328
3208
  }
1329
3209
  // eslint-disable-next-line jsdoc/require-jsdoc
1330
3210
  generateBaseData(data) {
3211
+ var _a, _b, _c, _d, _e, _f;
1331
3212
  const confirmEditDialogData = new ConfirmDialogDataBuilder(data === null || data === void 0 ? void 0 : data.confirmEditDialogData)
1332
3213
  .withDefault('confirmButtonLabel', 'Save')
1333
3214
  .withDefault('text', ['Do you really want to save all changes?'])
@@ -1339,7 +3220,7 @@ class EditDialogDataBuilder extends BaseBuilder {
1339
3220
  .withDefault('text', ['Do you really want to delete this entity?'])
1340
3221
  .withDefault('title', 'Delete')
1341
3222
  .getResult();
1342
- return new EditDialogDataInternal((data === null || data === void 0 ? void 0 : data.title) ? data.title : () => 'Edit', (data === null || data === void 0 ? void 0 : data.confirmButtonLabel) ? data.confirmButtonLabel : 'Save', (data === null || data === void 0 ? void 0 : data.deleteButtonLabel) ? data.deleteButtonLabel : 'Delete', (data === null || data === void 0 ? void 0 : data.cancelButtonLabel) ? data.cancelButtonLabel : 'Cancel', (data === null || data === void 0 ? void 0 : data.deleteRequiresConfirmDialog) ? data.deleteRequiresConfirmDialog : true, (data === null || data === void 0 ? void 0 : data.editRequiresConfirmDialog) ? data.editRequiresConfirmDialog : false, confirmDeleteDialogData, confirmEditDialogData);
3223
+ return new EditDialogDataInternal((_a = data === null || data === void 0 ? void 0 : data.title) !== null && _a !== void 0 ? _a : (() => 'Edit'), (_b = data === null || data === void 0 ? void 0 : data.confirmButtonLabel) !== null && _b !== void 0 ? _b : 'Save', (_c = data === null || data === void 0 ? void 0 : data.deleteButtonLabel) !== null && _c !== void 0 ? _c : 'Delete', (_d = data === null || data === void 0 ? void 0 : data.cancelButtonLabel) !== null && _d !== void 0 ? _d : 'Cancel', (_e = data === null || data === void 0 ? void 0 : data.deleteRequiresConfirmDialog) !== null && _e !== void 0 ? _e : true, (_f = data === null || data === void 0 ? void 0 : data.editRequiresConfirmDialog) !== null && _f !== void 0 ? _f : false, confirmDeleteDialogData, confirmEditDialogData);
1343
3224
  }
1344
3225
  }
1345
3226
 
@@ -1363,8 +3244,9 @@ class EditEntityDialogDataBuilder extends BaseBuilder {
1363
3244
  }
1364
3245
  // eslint-disable-next-line jsdoc/require-jsdoc
1365
3246
  generateBaseData(data) {
3247
+ var _a;
1366
3248
  const editDialogData = new EditDialogDataBuilder(data.editDialogData).getResult();
1367
- return new EditEntityDialogDataInternal(data.entity, data.EntityServiceClass, editDialogData, data.allowDelete ? data.allowDelete : () => true);
3249
+ return new EditEntityDialogDataInternal(data.entity, data.EntityServiceClass, editDialogData, (_a = data.allowDelete) !== null && _a !== void 0 ? _a : (() => true));
1368
3250
  }
1369
3251
  }
1370
3252
 
@@ -1381,14 +3263,20 @@ class NgxMatEntityEditDialogComponent {
1381
3263
  this.injector = injector;
1382
3264
  this.dialog = dialog;
1383
3265
  this.EntityUtilities = EntityUtilities;
1384
- this.getWidth = EntityUtilities.getWidth;
3266
+ this.isEntityValid = true;
3267
+ this.isEntityDirty = (() => __awaiter(this, void 0, void 0, function* () { return false; })).call(this);
1385
3268
  }
1386
3269
  ngOnInit() {
1387
3270
  this.data = new EditEntityDialogDataBuilder(this.inputData).getResult();
1388
3271
  this.dialogRef.disableClose = true;
1389
3272
  this.entityRows = EntityUtilities.getEntityRows(this.data.entity, false, true);
1390
3273
  this.entityService = this.injector.get(this.data.EntityServiceClass);
1391
- this.entityPriorChanges = cloneDeep(this.data.entity);
3274
+ this.entityPriorChanges = LodashUtilities.cloneDeep(this.data.entity);
3275
+ }
3276
+ // eslint-disable-next-line jsdoc/require-jsdoc
3277
+ checkEntity() {
3278
+ this.isEntityValid = EntityUtilities.isEntityValid(this.data.entity, 'update');
3279
+ this.isEntityDirty = EntityUtilities.dirty(this.data.entity, this.entityPriorChanges);
1392
3280
  }
1393
3281
  /**
1394
3282
  * Tries to save the changes and close the dialog afterwards.
@@ -1396,7 +3284,8 @@ class NgxMatEntityEditDialogComponent {
1396
3284
  */
1397
3285
  edit() {
1398
3286
  if (!this.data.editDialogData.editRequiresConfirmDialog) {
1399
- return this.confirmEdit();
3287
+ this.confirmEdit();
3288
+ return;
1400
3289
  }
1401
3290
  const dialogData = new ConfirmDialogDataBuilder(this.data.editDialogData.confirmEditDialogData)
1402
3291
  .withDefault('text', ['Do you really want to save all changes?'])
@@ -1415,7 +3304,7 @@ class NgxMatEntityEditDialogComponent {
1415
3304
  });
1416
3305
  }
1417
3306
  confirmEdit() {
1418
- this.entityService.update(this.data.entity, this.entityPriorChanges).then(() => this.dialogRef.close(1));
3307
+ void this.entityService.update(this.data.entity, this.entityPriorChanges).then(() => this.dialogRef.close(1));
1419
3308
  }
1420
3309
  /**
1421
3310
  * Tries to delete the entity and close the dialog afterwards.
@@ -1423,7 +3312,8 @@ class NgxMatEntityEditDialogComponent {
1423
3312
  */
1424
3313
  delete() {
1425
3314
  if (!this.data.editDialogData.deleteRequiresConfirmDialog) {
1426
- return this.confirmDelete();
3315
+ this.confirmDelete();
3316
+ return;
1427
3317
  }
1428
3318
  const dialogData = new ConfirmDialogDataBuilder(this.data.editDialogData.confirmDeleteDialogData)
1429
3319
  .withDefault('text', ['Do you really want to delete this entity?'])
@@ -1443,7 +3333,7 @@ class NgxMatEntityEditDialogComponent {
1443
3333
  });
1444
3334
  }
1445
3335
  confirmDelete() {
1446
- this.entityService.delete(this.entityPriorChanges.id).then(() => this.dialogRef.close(2));
3336
+ void this.entityService.delete(this.entityPriorChanges).then(() => this.dialogRef.close(2));
1447
3337
  }
1448
3338
  /**
1449
3339
  * Reverts all changes made and closes the dialog.
@@ -1454,10 +3344,10 @@ class NgxMatEntityEditDialogComponent {
1454
3344
  }
1455
3345
  }
1456
3346
  NgxMatEntityEditDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityEditDialogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }, { token: i0.Injector }, { token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
1457
- NgxMatEntityEditDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityEditDialogComponent, selector: "ngx-mat-entity-edit-dialog", ngImport: i0, template: "<h2 mat-dialog-title>\n {{data.editDialogData.title(data.entity)}}\n <button *ngIf=\"data.allowDelete(data.entity)\" mat-raised-button (click)=\"delete()\" color=\"warn\" class=\"delete-button\" tabindex=\"-1\">\n {{data.editDialogData.deleteButtonLabel}}\n </button>\n</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <div class=\"row\" *ngFor=\"let row of entityRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{getWidth(data.entity, key, 'lg')}} col-md-{{getWidth(data.entity, key, 'md')}} col-sm-{{getWidth(data.entity, key, 'sm')}}\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"edit()\" [disabled]=\"!EntityUtilities.isEntityValid(data.entity, 'update') || !EntityUtilities.dirty(data.entity, entityPriorChanges)\">\n {{data.editDialogData.confirmButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.editDialogData.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}.delete-button{float:right}\n"], components: [{ type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: ["entity", "propertyKey", "getValidationErrorMessage", "hideOmitForCreate", "hideOmitForEdit"] }], directives: [{ type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i13.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i13.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i13.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
3347
+ NgxMatEntityEditDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityEditDialogComponent, selector: "ngx-mat-entity-edit-dialog", ngImport: i0, template: "<h2 mat-dialog-title>\n {{data.editDialogData.title(data.entity)}}\n <button *ngIf=\"data.allowDelete(data.entity)\" mat-raised-button (click)=\"delete()\" color=\"warn\" class=\"delete-button\" tabindex=\"-1\">\n {{data.editDialogData.deleteButtonLabel}}\n </button>\n</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <div class=\"row\" *ngFor=\"let row of entityRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(data.entity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(data.entity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(data.entity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkEntity()\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"edit()\" [disabled]=\"!isEntityValid || (isEntityDirty | async) === false\">\n {{data.editDialogData.confirmButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.editDialogData.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}.delete-button{float:right}\n"], components: [{ type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: ["entity", "propertyKey", "getValidationErrorMessage", "hideOmitForCreate", "hideOmitForEdit"], outputs: ["inputChangeEvent"] }], directives: [{ type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i3$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i3$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i3$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }], pipes: { "async": i4.AsyncPipe } });
1458
3348
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityEditDialogComponent, decorators: [{
1459
3349
  type: Component,
1460
- args: [{ selector: 'ngx-mat-entity-edit-dialog', template: "<h2 mat-dialog-title>\n {{data.editDialogData.title(data.entity)}}\n <button *ngIf=\"data.allowDelete(data.entity)\" mat-raised-button (click)=\"delete()\" color=\"warn\" class=\"delete-button\" tabindex=\"-1\">\n {{data.editDialogData.deleteButtonLabel}}\n </button>\n</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <div class=\"row\" *ngFor=\"let row of entityRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{getWidth(data.entity, key, 'lg')}} col-md-{{getWidth(data.entity, key, 'md')}} col-sm-{{getWidth(data.entity, key, 'sm')}}\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"edit()\" [disabled]=\"!EntityUtilities.isEntityValid(data.entity, 'update') || !EntityUtilities.dirty(data.entity, entityPriorChanges)\">\n {{data.editDialogData.confirmButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.editDialogData.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}.delete-button{float:right}\n"] }]
3350
+ args: [{ selector: 'ngx-mat-entity-edit-dialog', template: "<h2 mat-dialog-title>\n {{data.editDialogData.title(data.entity)}}\n <button *ngIf=\"data.allowDelete(data.entity)\" mat-raised-button (click)=\"delete()\" color=\"warn\" class=\"delete-button\" tabindex=\"-1\">\n {{data.editDialogData.deleteButtonLabel}}\n </button>\n</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <div class=\"row\" *ngFor=\"let row of entityRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(data.entity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(data.entity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(data.entity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkEntity()\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"edit()\" [disabled]=\"!isEntityValid || (isEntityDirty | async) === false\">\n {{data.editDialogData.confirmButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.editDialogData.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}.delete-button{float:right}\n"] }]
1461
3351
  }], ctorParameters: function () {
1462
3352
  return [{ type: undefined, decorators: [{
1463
3353
  type: Inject,
@@ -1484,7 +3374,8 @@ class BaseDataBuilder extends BaseBuilder {
1484
3374
  }
1485
3375
  // eslint-disable-next-line jsdoc/require-jsdoc
1486
3376
  generateBaseData(data) {
1487
- return new BaseDataInternal(data.title, data.displayColumns, data.EntityServiceClass, data.searchLabel ? data.searchLabel : 'Search', data.createButtonLabel ? data.createButtonLabel : 'Create', data.searchString ? data.searchString : defaultSearchFunction, data.allowCreate === false ? data.allowCreate : true, data.allowEdit ? data.allowEdit : () => true, data.allowDelete ? data.allowDelete : () => true, data.multiSelectActions ? data.multiSelectActions : [], data.multiSelectLabel ? data.multiSelectLabel : 'Actions', data.EntityClass, data.edit, data.create);
3377
+ var _a, _b, _c, _d, _e, _f, _g, _h;
3378
+ return new BaseDataInternal(data.title, data.displayColumns, data.EntityServiceClass, (_a = data.searchLabel) !== null && _a !== void 0 ? _a : 'Search', (_b = data.createButtonLabel) !== null && _b !== void 0 ? _b : 'Create', (_c = data.searchString) !== null && _c !== void 0 ? _c : defaultSearchFunction, (_d = data.allowCreate) !== null && _d !== void 0 ? _d : true, (_e = data.allowEdit) !== null && _e !== void 0 ? _e : (() => true), (_f = data.allowDelete) !== null && _f !== void 0 ? _f : (() => true), (_g = data.multiSelectActions) !== null && _g !== void 0 ? _g : [], (_h = data.multiSelectLabel) !== null && _h !== void 0 ? _h : 'Actions', data.EntityClass, data.edit, data.create);
1488
3379
  }
1489
3380
  }
1490
3381
  /**
@@ -1531,7 +3422,7 @@ class TableDataBuilder extends BaseBuilder {
1531
3422
  }
1532
3423
  if ((data.baseData.allowEdit && data.baseData.allowEdit !== (() => false)
1533
3424
  || data.baseData.allowDelete && data.baseData.allowDelete !== (() => false)
1534
- || data.baseData.allowCreate)
3425
+ || data.baseData.allowCreate === true)
1535
3426
  && !data.baseData.EntityClass) {
1536
3427
  throw new Error(`
1537
3428
  Missing required Input data "EntityClass".
@@ -1600,21 +3491,19 @@ class NgxMatEntityTableComponent {
1600
3491
  return (_a = this.data.baseData.displayColumns.find((dp) => dp.displayName === header)) === null || _a === void 0 ? void 0 : _a.value(entity);
1601
3492
  };
1602
3493
  this.dataSource.sort = this.sort;
1603
- if (this.data.baseData.searchString) {
1604
- this.dataSource.filterPredicate = (entity, filter) => {
1605
- const searchStr = this.data.baseData.searchString(entity);
1606
- const formattedSearchString = searchStr.toLowerCase();
1607
- const formattedFilterString = filter.toLowerCase();
1608
- return formattedSearchString.includes(formattedFilterString);
1609
- };
1610
- }
3494
+ this.dataSource.filterPredicate = (entity, filter) => {
3495
+ const searchStr = this.data.baseData.searchString(entity);
3496
+ const formattedSearchString = searchStr.toLowerCase();
3497
+ const formattedFilterString = filter.toLowerCase();
3498
+ return formattedSearchString.includes(formattedFilterString);
3499
+ };
1611
3500
  this.dataSource.filter = this.filter;
1612
3501
  this.dataSource.paginator = this.paginator;
1613
3502
  this.entityService.entitiesSubject.pipe(takeUntil(this.onDestroy)).subscribe((entities) => {
1614
3503
  this.dataSource.data = entities;
1615
3504
  this.selection.clear();
1616
3505
  });
1617
- this.entityService.read();
3506
+ void this.entityService.read();
1618
3507
  }
1619
3508
  /**
1620
3509
  * Edits an entity. This either calls the edit-Method provided by the user or uses a default edit-dialog.
@@ -1631,27 +3520,28 @@ class NgxMatEntityTableComponent {
1631
3520
  this.data.baseData.edit(new this.data.baseData.EntityClass(entity));
1632
3521
  }
1633
3522
  else {
1634
- this.editDefault(new this.data.baseData.EntityClass(entity));
3523
+ void this.editDefault(new this.data.baseData.EntityClass(entity));
1635
3524
  }
1636
3525
  }
1637
3526
  }
1638
3527
  editDefault(entity) {
1639
- const inputDialogData = {
1640
- entity: entity,
1641
- EntityServiceClass: this.data.baseData.EntityServiceClass,
1642
- allowDelete: this.data.baseData.allowDelete,
1643
- editDialogData: this.data.editDialogData
1644
- };
1645
- const dialogData = new EditEntityDialogDataBuilder(inputDialogData).getResult();
1646
- firstValueFrom(this.dialog.open(NgxMatEntityEditDialogComponent, {
1647
- data: dialogData,
1648
- minWidth: '60%',
1649
- autoFocus: false,
1650
- restoreFocus: false
1651
- }).afterClosed()).then((res) => {
3528
+ return __awaiter(this, void 0, void 0, function* () {
3529
+ const inputDialogData = {
3530
+ entity: entity,
3531
+ EntityServiceClass: this.data.baseData.EntityServiceClass,
3532
+ allowDelete: this.data.baseData.allowDelete,
3533
+ editDialogData: this.data.editDialogData
3534
+ };
3535
+ const dialogData = new EditEntityDialogDataBuilder(inputDialogData).getResult();
3536
+ const res = yield firstValueFrom(this.dialog.open(NgxMatEntityEditDialogComponent, {
3537
+ data: dialogData,
3538
+ minWidth: '60%',
3539
+ autoFocus: false,
3540
+ restoreFocus: false
3541
+ }).afterClosed());
1652
3542
  if (res === 0) {
1653
3543
  const data = this.dataSource.data;
1654
- data[this.dataSource.data.findIndex((e) => e.id === entity.id)] = entity;
3544
+ data[this.dataSource.data.findIndex((e) => e[this.entityService.idKey] === entity[this.entityService.idKey])] = entity;
1655
3545
  this.dataSource.data = data;
1656
3546
  this.selection.clear();
1657
3547
  }
@@ -1696,7 +3586,8 @@ class NgxMatEntityTableComponent {
1696
3586
  */
1697
3587
  runMultiAction(action) {
1698
3588
  if (!action.requireConfirmDialog || !action.requireConfirmDialog(this.selection.selected)) {
1699
- return this.confirmRunMultiAction(action);
3589
+ this.confirmRunMultiAction(action);
3590
+ return;
1700
3591
  }
1701
3592
  const dialogData = new ConfirmDialogDataBuilder(action.confirmDialogData)
1702
3593
  .withDefault('text', [`Do you really want to run this action on ${this.selection.selected.length} entries?`])
@@ -1740,7 +3631,7 @@ class NgxMatEntityTableComponent {
1740
3631
  this.selection.clear();
1741
3632
  }
1742
3633
  else {
1743
- this.dataSource.data.forEach((row) => this.selection.select(row));
3634
+ this.dataSource.data.forEach(row => this.selection.select(row));
1744
3635
  }
1745
3636
  }
1746
3637
  /**
@@ -1769,7 +3660,7 @@ class NgxMatEntityTableComponent {
1769
3660
  }
1770
3661
  }
1771
3662
  NgxMatEntityTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityTableComponent, deps: [{ token: i1.MatDialog }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
1772
- NgxMatEntityTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityTableComponent, selector: "ngx-mat-entity-table", inputs: { tableData: "tableData" }, viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, static: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "filter", first: true, predicate: ["filter"], descendants: true, static: true }], ngImport: i0, template: "<h1 class=\"title\">{{data.baseData.title}}</h1>\n\n<div class=\"row\">\n <mat-form-field class=\"col-lg-8 col-md-6 col-sm-12\">\n <mat-label>{{data.baseData.searchLabel}}</mat-label>\n <input matInput (keyup)=\"applyFilter($event)\" />\n </mat-form-field>\n <div\n *ngIf=\"data.baseData.multiSelectActions.length\"\n [class.col-lg-2]=\"data.baseData.allowCreate\"\n [class.col-lg-4]=\"!data.baseData.allowCreate\"\n [class.col-md-3]=\"data.baseData.allowCreate\"\n [class.col-md-6]=\"!data.baseData.allowCreate\"\n [class.col-sm-6]=\"data.baseData.allowCreate\"\n [class.col-sm-12]=\"!data.baseData.allowCreate\"\n >\n <button class=\"actions-button\" [matMenuTriggerFor]=\"menu\" mat-raised-button>\n {{data.baseData.multiSelectLabel}}\n </button>\n </div>\n <mat-menu #menu=\"matMenu\">\n <button *ngFor=\"let action of data.baseData.multiSelectActions\" [disabled]=\"multiActionDisabled(action)\" (click)=\"runMultiAction(action)\" mat-menu-item>\n {{action.displayName}}\n </button>\n </mat-menu>\n\n <div\n *ngIf=\"data.baseData.allowCreate\"\n [class.col-lg-2]=\"data.baseData.multiSelectActions.length\"\n [class.col-lg-4]=\"!data.baseData.multiSelectActions.length\"\n [class.col-md-3]=\"data.baseData.multiSelectActions.length\"\n [class.col-md-6]=\"!data.baseData.multiSelectActions.length\"\n [class.col-sm-6]=\"data.baseData.multiSelectActions.length\"\n [class.col-sm-12]=\"!data.baseData.multiSelectActions.length\"\n >\n <button class=\"create-button\" (click)=\"createEntity()\" mat-raised-button>\n {{data.baseData.createButtonLabel}}\n </button>\n </div>\n</div>\n\n<div class=\"mat-elevation-z8\">\n <mat-table *ngIf=\"dataSource\" [dataSource]=\"dataSource\" matSort>\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"> </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\" class=\"module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"> </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n <ng-container *ngFor=\"let dCol of data.baseData.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" [class.enabled]=\"data.baseData.allowEdit(entity)\" (click)=\"editEntity(entity)\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n\n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <mat-paginator *ngIf=\"dataSource\" id=\"paginator\" [length]=\"dataSource.filteredData.length\" [pageIndex]=\"0\" [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\"> </mat-paginator>\n</div>\n", styles: [".title{text-align:center}button{width:100%}.mat-column-select{flex:0 0 75px}.enabled:hover{cursor:pointer}@media (max-width: 767px){.actions-button,.create-button{margin-bottom:15px}}\n"], components: [{ type: i2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i4$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { type: i7$1.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }], directives: [{ type: i2.MatLabel, selector: "mat-label" }, { type: i12.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i9.MatCellDef, selector: "[matCellDef]" }, { type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }] });
3663
+ NgxMatEntityTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityTableComponent, selector: "ngx-mat-entity-table", inputs: { tableData: "tableData" }, viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, static: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "filter", first: true, predicate: ["filter"], descendants: true, static: true }], ngImport: i0, template: "<h1 class=\"title\">{{data.baseData.title}}</h1>\n\n<div class=\"row\">\n <mat-form-field class=\"col-lg-8 col-md-6 col-sm-12\">\n <mat-label>{{data.baseData.searchLabel}}</mat-label>\n <input matInput (keyup)=\"applyFilter($event)\" />\n </mat-form-field>\n <div\n *ngIf=\"data.baseData.multiSelectActions.length\"\n [class.col-lg-2]=\"data.baseData.allowCreate\"\n [class.col-lg-4]=\"!data.baseData.allowCreate\"\n [class.col-md-3]=\"data.baseData.allowCreate\"\n [class.col-md-6]=\"!data.baseData.allowCreate\"\n [class.col-sm-6]=\"data.baseData.allowCreate\"\n [class.col-sm-12]=\"!data.baseData.allowCreate\"\n >\n <button class=\"actions-button\" [matMenuTriggerFor]=\"menu\" mat-raised-button>\n {{data.baseData.multiSelectLabel}}\n </button>\n </div>\n <mat-menu #menu=\"matMenu\">\n <button *ngFor=\"let action of data.baseData.multiSelectActions\" [disabled]=\"multiActionDisabled(action)\" (click)=\"runMultiAction(action)\" mat-menu-item>\n {{action.displayName}}\n </button>\n </mat-menu>\n\n <div\n *ngIf=\"data.baseData.allowCreate\"\n [class.col-lg-2]=\"data.baseData.multiSelectActions.length\"\n [class.col-lg-4]=\"!data.baseData.multiSelectActions.length\"\n [class.col-md-3]=\"data.baseData.multiSelectActions.length\"\n [class.col-md-6]=\"!data.baseData.multiSelectActions.length\"\n [class.col-sm-6]=\"data.baseData.multiSelectActions.length\"\n [class.col-sm-12]=\"!data.baseData.multiSelectActions.length\"\n >\n <button class=\"create-button\" (click)=\"createEntity()\" mat-raised-button>\n {{data.baseData.createButtonLabel}}\n </button>\n </div>\n</div>\n\n<div class=\"mat-elevation-z8\">\n <mat-table *ngIf=\"dataSource\" [dataSource]=\"dataSource\" matSort>\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"> </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\" class=\"module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"> </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n <ng-container *ngFor=\"let dCol of data.baseData.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" [class.enabled]=\"data.baseData.allowEdit(entity)\" (click)=\"editEntity(entity)\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n\n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <mat-paginator *ngIf=\"dataSource\" id=\"paginator\" [length]=\"dataSource.filteredData.length\" [pageIndex]=\"0\" [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\"> </mat-paginator>\n</div>\n", styles: [".title{text-align:center}button{width:100%}.mat-column-select{flex:0 0 75px}.enabled:hover{cursor:pointer}@media (max-width: 767px){.actions-button,.create-button{margin-bottom:15px}}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$3.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i4$3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: i4$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i4$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i4$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { type: i7.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4$3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i4$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i4$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i4$2.MatCellDef, selector: "[matCellDef]" }, { type: i4$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i4$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i4$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }] });
1773
3664
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityTableComponent, decorators: [{
1774
3665
  type: Component,
1775
3666
  args: [{ selector: 'ngx-mat-entity-table', template: "<h1 class=\"title\">{{data.baseData.title}}</h1>\n\n<div class=\"row\">\n <mat-form-field class=\"col-lg-8 col-md-6 col-sm-12\">\n <mat-label>{{data.baseData.searchLabel}}</mat-label>\n <input matInput (keyup)=\"applyFilter($event)\" />\n </mat-form-field>\n <div\n *ngIf=\"data.baseData.multiSelectActions.length\"\n [class.col-lg-2]=\"data.baseData.allowCreate\"\n [class.col-lg-4]=\"!data.baseData.allowCreate\"\n [class.col-md-3]=\"data.baseData.allowCreate\"\n [class.col-md-6]=\"!data.baseData.allowCreate\"\n [class.col-sm-6]=\"data.baseData.allowCreate\"\n [class.col-sm-12]=\"!data.baseData.allowCreate\"\n >\n <button class=\"actions-button\" [matMenuTriggerFor]=\"menu\" mat-raised-button>\n {{data.baseData.multiSelectLabel}}\n </button>\n </div>\n <mat-menu #menu=\"matMenu\">\n <button *ngFor=\"let action of data.baseData.multiSelectActions\" [disabled]=\"multiActionDisabled(action)\" (click)=\"runMultiAction(action)\" mat-menu-item>\n {{action.displayName}}\n </button>\n </mat-menu>\n\n <div\n *ngIf=\"data.baseData.allowCreate\"\n [class.col-lg-2]=\"data.baseData.multiSelectActions.length\"\n [class.col-lg-4]=\"!data.baseData.multiSelectActions.length\"\n [class.col-md-3]=\"data.baseData.multiSelectActions.length\"\n [class.col-md-6]=\"!data.baseData.multiSelectActions.length\"\n [class.col-sm-6]=\"data.baseData.multiSelectActions.length\"\n [class.col-sm-12]=\"!data.baseData.multiSelectActions.length\"\n >\n <button class=\"create-button\" (click)=\"createEntity()\" mat-raised-button>\n {{data.baseData.createButtonLabel}}\n </button>\n </div>\n</div>\n\n<div class=\"mat-elevation-z8\">\n <mat-table *ngIf=\"dataSource\" [dataSource]=\"dataSource\" matSort>\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"> </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\" class=\"module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"> </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n <ng-container *ngFor=\"let dCol of data.baseData.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" [class.enabled]=\"data.baseData.allowEdit(entity)\" (click)=\"editEntity(entity)\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n\n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <mat-paginator *ngIf=\"dataSource\" id=\"paginator\" [length]=\"dataSource.filteredData.length\" [pageIndex]=\"0\" [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\"> </mat-paginator>\n</div>\n", styles: [".title{text-align:center}button{width:100%}.mat-column-select{flex:0 0 75px}.enabled:hover{cursor:pointer}@media (max-width: 767px){.actions-button,.create-button{margin-bottom:15px}}\n"] }]
@@ -1905,17 +3796,88 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
1905
3796
  */
1906
3797
  class EntityArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
1907
3798
  constructor(data) {
3799
+ var _a, _b, _c, _d, _e, _f, _g;
1908
3800
  super(data);
1909
- this.createInline = data.createInline != undefined ? data.createInline : true;
1910
- this.displayStyle = data.displayStyle;
3801
+ this.createInline = (_a = data.createInline) !== null && _a !== void 0 ? _a : true;
1911
3802
  this.itemType = data.itemType;
3803
+ this.allowDuplicates = (_b = data.allowDuplicates) !== null && _b !== void 0 ? _b : false;
3804
+ this.duplicatesErrorDialog = getDefaultDuplicateErrorDialogData(data);
1912
3805
  this.EntityClass = data.EntityClass;
1913
3806
  this.displayColumns = data.displayColumns;
1914
- this.createInline = data.createInline != undefined ? data.createInline : true;
1915
- this.missingErrorMessage = data.missingErrorMessage ? data.missingErrorMessage : 'Needs to contain at least one value';
1916
- this.defaultWidths = data.defaultWidths ? data.defaultWidths : [12, 12, 12];
1917
- this.addButtonLabel = data.addButtonLabel ? data.addButtonLabel : 'Add';
1918
- this.removeButtonLabel = data.removeButtonLabel ? data.removeButtonLabel : 'Remove';
3807
+ this.createInline = (_c = data.createInline) !== null && _c !== void 0 ? _c : true;
3808
+ this.missingErrorMessage = (_d = data.missingErrorMessage) !== null && _d !== void 0 ? _d : 'Needs to contain at least one value';
3809
+ this.defaultWidths = (_e = data.defaultWidths) !== null && _e !== void 0 ? _e : [12, 12, 12];
3810
+ this.addButtonLabel = (_f = data.addButtonLabel) !== null && _f !== void 0 ? _f : 'Add';
3811
+ this.removeButtonLabel = (_g = data.removeButtonLabel) !== null && _g !== void 0 ? _g : 'Remove';
3812
+ }
3813
+ }
3814
+ /**
3815
+ * The internal DateArrayDecoratorConfig. Sets default values.
3816
+ */
3817
+ class DateArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
3818
+ constructor(data) {
3819
+ var _a, _b, _c, _d, _e;
3820
+ super(data);
3821
+ this.itemType = data.itemType;
3822
+ this.allowDuplicates = (_a = data.allowDuplicates) !== null && _a !== void 0 ? _a : false;
3823
+ this.duplicatesErrorDialog = getDefaultDuplicateErrorDialogData(data);
3824
+ this.displayColumns = data.displayColumns;
3825
+ this.defaultWidths = (_b = data.defaultWidths) !== null && _b !== void 0 ? _b : [12, 12, 12];
3826
+ this.addButtonLabel = (_c = data.addButtonLabel) !== null && _c !== void 0 ? _c : 'Add';
3827
+ this.removeButtonLabel = (_d = data.removeButtonLabel) !== null && _d !== void 0 ? _d : 'Remove';
3828
+ this.missingErrorMessage = (_e = data.missingErrorMessage) !== null && _e !== void 0 ? _e : 'Needs to contain at least one value';
3829
+ this.min = data.min;
3830
+ this.max = data.max;
3831
+ this.filter = data.filter;
3832
+ }
3833
+ }
3834
+ /**
3835
+ * The internal DateTimeArrayDecoratorConfig. Sets default values.
3836
+ */
3837
+ class DateTimeArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
3838
+ constructor(data) {
3839
+ var _a, _b, _c, _d, _e, _f, _g;
3840
+ super(data);
3841
+ this.itemType = data.itemType;
3842
+ this.allowDuplicates = (_a = data.allowDuplicates) !== null && _a !== void 0 ? _a : false;
3843
+ this.duplicatesErrorDialog = getDefaultDuplicateErrorDialogData(data);
3844
+ this.displayColumns = data.displayColumns;
3845
+ this.defaultWidths = (_b = data.defaultWidths) !== null && _b !== void 0 ? _b : [12, 12, 12];
3846
+ this.addButtonLabel = (_c = data.addButtonLabel) !== null && _c !== void 0 ? _c : 'Add';
3847
+ this.removeButtonLabel = (_d = data.removeButtonLabel) !== null && _d !== void 0 ? _d : 'Remove';
3848
+ this.missingErrorMessage = (_e = data.missingErrorMessage) !== null && _e !== void 0 ? _e : 'Needs to contain at least one value';
3849
+ this.times = (_f = data.times) !== null && _f !== void 0 ? _f : DateUtilities.getDefaultTimes();
3850
+ this.timeDisplayName = (_g = data.timeDisplayName) !== null && _g !== void 0 ? _g : 'Time';
3851
+ this.minDate = data.minDate;
3852
+ this.maxDate = data.maxDate;
3853
+ this.filterDate = data.filterDate;
3854
+ this.minTime = data.minTime;
3855
+ this.maxTime = data.maxTime;
3856
+ this.filterTime = data.filterTime;
3857
+ }
3858
+ }
3859
+ /**
3860
+ * The internal DateRangeArrayDecoratorConfig. Sets default values.
3861
+ */
3862
+ class DateRangeArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
3863
+ constructor(data) {
3864
+ var _a, _b, _c, _d, _e, _f, _g;
3865
+ super(data);
3866
+ this.itemType = data.itemType;
3867
+ this.allowDuplicates = (_a = data.allowDuplicates) !== null && _a !== void 0 ? _a : false;
3868
+ this.duplicatesErrorDialog = getDefaultDuplicateErrorDialogData(data);
3869
+ this.displayColumns = data.displayColumns;
3870
+ this.defaultWidths = (_b = data.defaultWidths) !== null && _b !== void 0 ? _b : [12, 12, 12];
3871
+ this.addButtonLabel = (_c = data.addButtonLabel) !== null && _c !== void 0 ? _c : 'Add';
3872
+ this.removeButtonLabel = (_d = data.removeButtonLabel) !== null && _d !== void 0 ? _d : 'Remove';
3873
+ this.missingErrorMessage = (_e = data.missingErrorMessage) !== null && _e !== void 0 ? _e : 'Needs to contain at least one value';
3874
+ this.placeholderStart = (_f = data.placeholderStart) !== null && _f !== void 0 ? _f : 'Start';
3875
+ this.placeholderEnd = (_g = data.placeholderEnd) !== null && _g !== void 0 ? _g : 'End';
3876
+ this.minStart = data.minStart;
3877
+ this.maxStart = data.maxStart;
3878
+ this.minEnd = data.minEnd;
3879
+ this.maxEnd = data.maxEnd;
3880
+ this.filter = data.filter;
1919
3881
  }
1920
3882
  }
1921
3883
  /**
@@ -1923,14 +3885,16 @@ class EntityArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal
1923
3885
  */
1924
3886
  class StringChipsArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
1925
3887
  constructor(data) {
3888
+ var _a, _b, _c;
1926
3889
  super(data);
1927
- this.deleteIcon = data.deleteIcon ? data.deleteIcon : 'fas fa-circle-minus';
1928
- this.displayStyle = data.displayStyle;
3890
+ this.deleteIcon = (_a = data.deleteIcon) !== null && _a !== void 0 ? _a : 'fas fa-circle-minus';
1929
3891
  this.itemType = data.itemType;
3892
+ this.allowDuplicates = (_b = data.allowDuplicates) !== null && _b !== void 0 ? _b : false;
3893
+ this.duplicatesErrorDialog = getDefaultDuplicateErrorDialogData(data);
1930
3894
  this.maxLength = data.maxLength;
1931
3895
  this.minLength = data.minLength;
1932
3896
  this.regex = data.regex;
1933
- this.defaultWidths = data.defaultWidths ? data.defaultWidths : [6, 12, 12];
3897
+ this.defaultWidths = (_c = data.defaultWidths) !== null && _c !== void 0 ? _c : [6, 12, 12];
1934
3898
  }
1935
3899
  }
1936
3900
  /**
@@ -1938,17 +3902,38 @@ class StringChipsArrayDecoratorConfigInternal extends PropertyDecoratorConfigInt
1938
3902
  */
1939
3903
  class AutocompleteStringChipsArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
1940
3904
  constructor(data) {
3905
+ var _a, _b, _c;
1941
3906
  super(data);
1942
3907
  this.autocompleteValues = data.autocompleteValues;
1943
- this.deleteIcon = data.deleteIcon ? data.deleteIcon : 'fas fa-circle-minus';
1944
- this.displayStyle = data.displayStyle;
3908
+ this.deleteIcon = (_a = data.deleteIcon) !== null && _a !== void 0 ? _a : 'fas fa-circle-minus';
1945
3909
  this.itemType = data.itemType;
3910
+ this.allowDuplicates = (_b = data.allowDuplicates) !== null && _b !== void 0 ? _b : false;
3911
+ this.duplicatesErrorDialog = getDefaultDuplicateErrorDialogData(data);
1946
3912
  this.maxLength = data.maxLength;
1947
3913
  this.minLength = data.minLength;
1948
3914
  this.regex = data.regex;
1949
- this.defaultWidths = data.defaultWidths ? data.defaultWidths : [6, 12, 12];
3915
+ this.defaultWidths = (_c = data.defaultWidths) !== null && _c !== void 0 ? _c : [6, 12, 12];
1950
3916
  }
1951
3917
  }
3918
+ /**
3919
+ * Gets the default dialog data for the error dialog to display when the user tries to add a duplicate value.
3920
+ *
3921
+ * @param data - The Array Decorator data.
3922
+ * @returns The dialog data with set default values.
3923
+ */
3924
+ function getDefaultDuplicateErrorDialogData(data) {
3925
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
3926
+ return {
3927
+ type: (_b = (_a = data.duplicatesErrorDialog) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : 'info-only',
3928
+ // eslint-disable-next-line max-len
3929
+ text: (_d = (_c = data.duplicatesErrorDialog) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : ['Adding duplicate entries to the array is not allowed.'],
3930
+ title: (_f = (_e = data.duplicatesErrorDialog) === null || _e === void 0 ? void 0 : _e.title) !== null && _f !== void 0 ? _f : 'Error adding duplicate item',
3931
+ confirmButtonLabel: (_g = data.duplicatesErrorDialog) === null || _g === void 0 ? void 0 : _g.confirmButtonLabel,
3932
+ cancelButtonLabel: (_h = data.duplicatesErrorDialog) === null || _h === void 0 ? void 0 : _h.cancelButtonLabel,
3933
+ requireConfirmation: (_j = data.duplicatesErrorDialog) === null || _j === void 0 ? void 0 : _j.requireConfirmation,
3934
+ confirmationText: (_k = data.duplicatesErrorDialog) === null || _k === void 0 ? void 0 : _k.confirmationText
3935
+ };
3936
+ }
1952
3937
 
1953
3938
  /**
1954
3939
  * Decorator for setting and getting array property metadata.
@@ -1961,6 +3946,12 @@ function array(metadata) {
1961
3946
  switch (metadata.itemType) {
1962
3947
  case DecoratorTypes.OBJECT:
1963
3948
  return baseProperty(new EntityArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY);
3949
+ case DecoratorTypes.DATE:
3950
+ return baseProperty(new DateArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY_DATE);
3951
+ case DecoratorTypes.DATE_TIME:
3952
+ return baseProperty(new DateTimeArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY_DATE_TIME);
3953
+ case DecoratorTypes.DATE_RANGE:
3954
+ return baseProperty(new DateRangeArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY_DATE_RANGE);
1964
3955
  case DecoratorTypes.STRING:
1965
3956
  return baseProperty(new StringChipsArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY_STRING_CHIPS);
1966
3957
  case DecoratorTypes.STRING_AUTOCOMPLETE:
@@ -1999,9 +3990,10 @@ class DropdownBooleanDecoratorConfigInternal extends PropertyDecoratorConfigInte
1999
3990
  */
2000
3991
  class CheckboxBooleanDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
2001
3992
  constructor(data) {
3993
+ var _a;
2002
3994
  super(data);
2003
3995
  this.displayStyle = data.displayStyle;
2004
- this.required = data.required === undefined ? false : data.required;
3996
+ this.required = (_a = data.required) !== null && _a !== void 0 ? _a : false;
2005
3997
  }
2006
3998
  }
2007
3999
  /**
@@ -2009,9 +4001,10 @@ class CheckboxBooleanDecoratorConfigInternal extends PropertyDecoratorConfigInte
2009
4001
  */
2010
4002
  class ToggleBooleanDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
2011
4003
  constructor(data) {
4004
+ var _a;
2012
4005
  super(data);
2013
4006
  this.displayStyle = data.displayStyle;
2014
- this.required = data.required === undefined ? false : data.required;
4007
+ this.required = (_a = data.required) !== null && _a !== void 0 ? _a : false;
2015
4008
  }
2016
4009
  }
2017
4010
 
@@ -2039,6 +4032,78 @@ function boolean(metadata) {
2039
4032
  class BooleanDecoratorConfig extends PropertyDecoratorConfig {
2040
4033
  }
2041
4034
 
4035
+ /**
4036
+ * The internal DefaultDateDecoratorConfig. Sets default values.
4037
+ */
4038
+ class DefaultDateDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
4039
+ constructor(data) {
4040
+ super(data);
4041
+ this.displayStyle = data.displayStyle;
4042
+ this.max = data.max;
4043
+ this.min = data.min;
4044
+ this.filter = data.filter;
4045
+ }
4046
+ }
4047
+ /**
4048
+ * The internal DateRangeDateDecoratorConfig. Sets default values.
4049
+ */
4050
+ class DateRangeDateDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
4051
+ constructor(data) {
4052
+ var _a, _b;
4053
+ super(data);
4054
+ this.displayStyle = data.displayStyle;
4055
+ this.minStart = data.minStart;
4056
+ this.maxStart = data.maxStart;
4057
+ this.minEnd = data.minEnd;
4058
+ this.maxEnd = data.maxEnd;
4059
+ this.filter = data.filter;
4060
+ this.placeholderStart = (_a = data.placeholderStart) !== null && _a !== void 0 ? _a : 'Start';
4061
+ this.placeholderEnd = (_b = data.placeholderEnd) !== null && _b !== void 0 ? _b : 'End';
4062
+ }
4063
+ }
4064
+ /**
4065
+ * The internal DateTimeDateDecoratorConfig. Sets default values.
4066
+ */
4067
+ class DateTimeDateDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
4068
+ constructor(data) {
4069
+ var _a, _b;
4070
+ super(data);
4071
+ this.displayStyle = data.displayStyle;
4072
+ this.times = (_a = data.times) !== null && _a !== void 0 ? _a : DateUtilities.getDefaultTimes();
4073
+ this.timeDisplayName = (_b = data.timeDisplayName) !== null && _b !== void 0 ? _b : 'Time';
4074
+ this.minDate = data.minDate;
4075
+ this.maxDate = data.maxDate;
4076
+ this.filterDate = data.filterDate;
4077
+ this.minTime = data.minTime;
4078
+ this.maxTime = data.maxTime;
4079
+ this.filterTime = data.filterTime;
4080
+ }
4081
+ }
4082
+
4083
+ /**
4084
+ * Decorator for setting and getting date property metadata.
4085
+ *
4086
+ * @param metadata - The metadata of the date property.
4087
+ * @returns The method that defines the metadata.
4088
+ */
4089
+ function date(metadata) {
4090
+ if (metadata.displayStyle === 'date') {
4091
+ return baseProperty(new DefaultDateDecoratorConfigInternal(metadata), DecoratorTypes.DATE);
4092
+ }
4093
+ else if (metadata.displayStyle === 'datetime') {
4094
+ return baseProperty(new DateTimeDateDecoratorConfigInternal(metadata), DecoratorTypes.DATE_TIME);
4095
+ }
4096
+ else {
4097
+ return baseProperty(new DateRangeDateDecoratorConfigInternal(metadata), DecoratorTypes.DATE_RANGE);
4098
+ }
4099
+ }
4100
+
4101
+ /**
4102
+ * Definition for the @date metadata.
4103
+ */
4104
+ class DateDecoratorConfig extends PropertyDecoratorConfig {
4105
+ }
4106
+
2042
4107
  /**
2043
4108
  * The internal DefaultNumberDecoratorConfig. Sets default values.
2044
4109
  */
@@ -2062,9 +4127,9 @@ class DropdownNumberDecoratorConfigInternal extends PropertyDecoratorConfigInter
2062
4127
  }
2063
4128
 
2064
4129
  /**
2065
- * Decorator for setting and getting string property metadata.
4130
+ * Decorator for setting and getting number property metadata.
2066
4131
  *
2067
- * @param metadata - The metadata of the string property.
4132
+ * @param metadata - The metadata of the number property.
2068
4133
  * @returns The method that defines the metadata.
2069
4134
  */
2070
4135
  function number(metadata) {
@@ -2089,7 +4154,7 @@ class DefaultObjectDecoratorConfigInternal extends PropertyDecoratorConfigIntern
2089
4154
  constructor(data) {
2090
4155
  super(data);
2091
4156
  this.displayStyle = data.displayStyle;
2092
- this.type = data.type;
4157
+ this.EntityClass = data.EntityClass;
2093
4158
  }
2094
4159
  }
2095
4160
 
@@ -2115,6 +4180,168 @@ class ObjectDecoratorConfig extends PropertyDecoratorConfig {
2115
4180
  class StringDecoratorConfig extends PropertyDecoratorConfig {
2116
4181
  }
2117
4182
 
4183
+ /**
4184
+ * The internal DefaultFileDecoratorConfig. Sets default values.
4185
+ */
4186
+ class DefaultFileDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
4187
+ constructor(data) {
4188
+ var _a, _b, _c, _d, _e, _f, _g, _h;
4189
+ super(data);
4190
+ this.type = data.type;
4191
+ this.preview = false;
4192
+ this.multiple = data.multiple;
4193
+ this.deleteIcon = (_a = data.deleteIcon) !== null && _a !== void 0 ? _a : 'fas fa-circle-minus';
4194
+ this.allowedMimeTypes = (_b = data.allowedMimeTypes) !== null && _b !== void 0 ? _b : ['*'];
4195
+ this.maxSize = (_c = data.maxSize) !== null && _c !== void 0 ? _c : 10;
4196
+ this.maxSizeTotal = (_d = data.maxSizeTotal) !== null && _d !== void 0 ? _d : 100;
4197
+ this.mimeTypeErrorDialog = (_e = data.mimeTypeErrorDialog) !== null && _e !== void 0 ? _e : getDefaultMimeTypeErrorDialogData(data);
4198
+ this.maxSizeErrorDialog = (_f = data.maxSizeErrorDialog) !== null && _f !== void 0 ? _f : getDefaultMaxSizeErrorDialogData(data);
4199
+ this.maxSizeTotalErrorDialog = (_g = data.maxSizeTotalErrorDialog) !== null && _g !== void 0 ? _g : getDefaultMaxSizeTotalErrorDialogData(data);
4200
+ this.dragAndDrop = (_h = data.dragAndDrop) !== null && _h !== void 0 ? _h : data.multiple;
4201
+ }
4202
+ }
4203
+ /**
4204
+ * The internal ImageFileDecoratorConfig. Sets default values.
4205
+ */
4206
+ class ImageFileDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
4207
+ constructor(data) {
4208
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
4209
+ super(data);
4210
+ this.type = data.type;
4211
+ this.allowedMimeTypes = (_a = data.allowedMimeTypes) !== null && _a !== void 0 ? _a : ['image/*'];
4212
+ this.multiple = data.multiple;
4213
+ this.preview = (_b = data.preview) !== null && _b !== void 0 ? _b : true;
4214
+ this.deleteIcon = (_c = data.deleteIcon) !== null && _c !== void 0 ? _c : 'fas fa-circle-minus';
4215
+ this.maxSize = (_d = data.maxSize) !== null && _d !== void 0 ? _d : 10;
4216
+ this.maxSizeTotal = (_e = data.maxSizeTotal) !== null && _e !== void 0 ? _e : 100;
4217
+ this.mimeTypeErrorDialog = (_f = data.mimeTypeErrorDialog) !== null && _f !== void 0 ? _f : getDefaultMimeTypeErrorDialogData(data);
4218
+ this.maxSizeErrorDialog = (_g = data.maxSizeErrorDialog) !== null && _g !== void 0 ? _g : getDefaultMaxSizeErrorDialogData(data);
4219
+ this.maxSizeTotalErrorDialog = (_h = data.maxSizeTotalErrorDialog) !== null && _h !== void 0 ? _h : getDefaultMaxSizeTotalErrorDialogData(data);
4220
+ this.previewPlaceholderUrl = data.previewPlaceholderUrl;
4221
+ this.dragAndDrop = (_j = data.dragAndDrop) !== null && _j !== void 0 ? _j : data.multiple;
4222
+ }
4223
+ }
4224
+ /**
4225
+ * Gets the default dialog data for the error dialog to display
4226
+ * when the user tries to add a file with a wrong type.
4227
+ *
4228
+ * @param data - The File Decorator data.
4229
+ * @returns The dialog data with set default values.
4230
+ */
4231
+ function getDefaultMimeTypeErrorDialogData(data) {
4232
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
4233
+ return {
4234
+ type: (_b = (_a = data.mimeTypeErrorDialog) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : 'info-only',
4235
+ // eslint-disable-next-line max-len
4236
+ text: (_d = (_c = data.mimeTypeErrorDialog) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : (data.multiple ? ['One of the uploaded files has the wrong type.'] : ['The uploaded file has the wrong type.']),
4237
+ title: (_f = (_e = data.mimeTypeErrorDialog) === null || _e === void 0 ? void 0 : _e.title) !== null && _f !== void 0 ? _f : (data.multiple ? 'Error adding files' : 'Error adding file'),
4238
+ confirmButtonLabel: (_g = data.mimeTypeErrorDialog) === null || _g === void 0 ? void 0 : _g.confirmButtonLabel,
4239
+ cancelButtonLabel: (_h = data.mimeTypeErrorDialog) === null || _h === void 0 ? void 0 : _h.cancelButtonLabel,
4240
+ requireConfirmation: (_j = data.mimeTypeErrorDialog) === null || _j === void 0 ? void 0 : _j.requireConfirmation,
4241
+ confirmationText: (_k = data.mimeTypeErrorDialog) === null || _k === void 0 ? void 0 : _k.confirmationText
4242
+ };
4243
+ }
4244
+ /**
4245
+ * Gets the default dialog data for the error dialog to display
4246
+ * when the user tries to add a single file that is bigger than the allowed maxSize.
4247
+ *
4248
+ * @param data - The File Decorator data.
4249
+ * @returns The dialog data with set default values.
4250
+ */
4251
+ function getDefaultMaxSizeErrorDialogData(data) {
4252
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
4253
+ return {
4254
+ type: (_b = (_a = data.mimeTypeErrorDialog) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : 'info-only',
4255
+ // eslint-disable-next-line max-len
4256
+ text: (_d = (_c = data.mimeTypeErrorDialog) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : (data.multiple ? ['One of the uploaded files is too big'] : ['The uploaded files is too big']),
4257
+ title: (_f = (_e = data.mimeTypeErrorDialog) === null || _e === void 0 ? void 0 : _e.title) !== null && _f !== void 0 ? _f : (data.multiple ? 'Error adding files' : 'Error adding file'),
4258
+ confirmButtonLabel: (_g = data.mimeTypeErrorDialog) === null || _g === void 0 ? void 0 : _g.confirmButtonLabel,
4259
+ cancelButtonLabel: (_h = data.mimeTypeErrorDialog) === null || _h === void 0 ? void 0 : _h.cancelButtonLabel,
4260
+ requireConfirmation: (_j = data.mimeTypeErrorDialog) === null || _j === void 0 ? void 0 : _j.requireConfirmation,
4261
+ confirmationText: (_k = data.mimeTypeErrorDialog) === null || _k === void 0 ? void 0 : _k.confirmationText
4262
+ };
4263
+ }
4264
+ /**
4265
+ * Gets the default dialog data for the error dialog to display
4266
+ * when the user tries to add a single file that is bigger than the allowed maxSize.
4267
+ *
4268
+ * @param data - The File Decorator data.
4269
+ * @returns The dialog data with set default values.
4270
+ */
4271
+ function getDefaultMaxSizeTotalErrorDialogData(data) {
4272
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
4273
+ return {
4274
+ type: (_b = (_a = data.mimeTypeErrorDialog) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : 'info-only',
4275
+ // eslint-disable-next-line max-len
4276
+ text: (_d = (_c = data.mimeTypeErrorDialog) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : ['The size of all files combined is too big'],
4277
+ title: (_f = (_e = data.mimeTypeErrorDialog) === null || _e === void 0 ? void 0 : _e.title) !== null && _f !== void 0 ? _f : (data.multiple ? 'Error adding files' : 'Error adding file'),
4278
+ confirmButtonLabel: (_g = data.mimeTypeErrorDialog) === null || _g === void 0 ? void 0 : _g.confirmButtonLabel,
4279
+ cancelButtonLabel: (_h = data.mimeTypeErrorDialog) === null || _h === void 0 ? void 0 : _h.cancelButtonLabel,
4280
+ requireConfirmation: (_j = data.mimeTypeErrorDialog) === null || _j === void 0 ? void 0 : _j.requireConfirmation,
4281
+ confirmationText: (_k = data.mimeTypeErrorDialog) === null || _k === void 0 ? void 0 : _k.confirmationText
4282
+ };
4283
+ }
4284
+
4285
+ /**
4286
+ * Decorator for setting and getting file property metadata.
4287
+ *
4288
+ * @param metadata - The metadata of the file property.
4289
+ * @returns The method that defines the metadata.
4290
+ * @throws When an unknown metadata type was provided.
4291
+ */
4292
+ function file(metadata) {
4293
+ switch (metadata.type) {
4294
+ case 'other':
4295
+ return baseProperty(new DefaultFileDecoratorConfigInternal(metadata), DecoratorTypes.FILE_DEFAULT);
4296
+ case 'image':
4297
+ return baseProperty(new ImageFileDecoratorConfigInternal(metadata), DecoratorTypes.FILE_IMAGE);
4298
+ default:
4299
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
4300
+ throw new Error(`Unknown metadata type ${metadata.type}`);
4301
+ }
4302
+ }
4303
+
4304
+ /**
4305
+ * Definition for the @file metadata.
4306
+ */
4307
+ class FileDecoratorConfig extends PropertyDecoratorConfig {
4308
+ }
4309
+
4310
+ /**
4311
+ * The default function to use for checking if the value is dirty.
4312
+ *
4313
+ * @param value - The current value.
4314
+ * @param valuePriorChanges - The value before any changes.
4315
+ * @returns Whether or not the provided value has been changed.
4316
+ */
4317
+ function defaultIsEqual(value, valuePriorChanges) {
4318
+ return LodashUtilities.isEqual(value, valuePriorChanges);
4319
+ }
4320
+ /**
4321
+ * The internal config for the @custom decorator.
4322
+ * Sets default values.
4323
+ */
4324
+ class CustomDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
4325
+ constructor(data) {
4326
+ var _a, _b;
4327
+ super(data);
4328
+ this.component = data.component;
4329
+ this.isValid = (_a = data.isValid) !== null && _a !== void 0 ? _a : (() => true);
4330
+ this.isEqual = (_b = data.isEqual) !== null && _b !== void 0 ? _b : defaultIsEqual;
4331
+ this.customMetadata = data.customMetadata;
4332
+ }
4333
+ }
4334
+
4335
+ /**
4336
+ * Decorator for setting and getting custom property metadata.
4337
+ *
4338
+ * @param metadata - The metadata of the custom property.
4339
+ * @returns The method that defines the metadata.
4340
+ */
4341
+ function custom(metadata) {
4342
+ return baseProperty(new CustomDecoratorConfigInternal(metadata), DecoratorTypes.CUSTOM);
4343
+ }
4344
+
2118
4345
  /**
2119
4346
  * Public API Surface of ngx-material-entity.
2120
4347
  */
@@ -2123,5 +4350,5 @@ class StringDecoratorConfig extends PropertyDecoratorConfig {
2123
4350
  * Generated bundle index. Do not edit.
2124
4351
  */
2125
4352
 
2126
- export { DecoratorTypes, Entity, EntityService, EntityUtilities, NgxMatEntityConfirmDialogComponent, NgxMatEntityConfirmDialogModule, NgxMatEntityCreateDialogComponent, NgxMatEntityCreateDialogModule, NgxMatEntityEditDialogComponent, NgxMatEntityEditDialogModule, NgxMatEntityInputComponent, NgxMatEntityInputModule, NgxMatEntityTableComponent, NgxMatEntityTableModule, array, boolean, getValidationErrorMessage, number, object, string };
4353
+ export { ArrayDecoratorConfig, DateUtilities, DecoratorTypes, Entity, EntityService, EntityUtilities, FileUtilities, NgxMatEntityBaseInputComponent, NgxMatEntityConfirmDialogComponent, NgxMatEntityConfirmDialogModule, NgxMatEntityCreateDialogComponent, NgxMatEntityCreateDialogModule, NgxMatEntityEditDialogComponent, NgxMatEntityEditDialogModule, NgxMatEntityInputComponent, NgxMatEntityInputModule, NgxMatEntityTableComponent, NgxMatEntityTableModule, array, boolean, custom, date, file, getValidationErrorMessage, number, object, string };
2127
4354
  //# sourceMappingURL=ngx-material-entity.mjs.map