ngx-material-entity 0.1.1 → 0.1.4

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 (133) hide show
  1. package/CONTRIBUTING.md +7 -1
  2. package/README.md +536 -328
  3. package/classes/base.builder.d.ts +35 -0
  4. package/classes/date.utilities.d.ts +58 -0
  5. package/classes/entity.model.d.ts +13 -0
  6. package/classes/{entity-service.class.d.ts → entity.service.d.ts} +35 -20
  7. package/classes/entity.utilities.d.ts +153 -0
  8. package/components/confirm-dialog/confirm-dialog-data.builder.d.ts +23 -0
  9. package/components/confirm-dialog/confirm-dialog-data.d.ts +18 -8
  10. package/components/confirm-dialog/confirm-dialog.component.d.ts +15 -5
  11. package/components/get-validation-error-message.function.d.ts +3 -2
  12. package/components/input/add-array-item-dialog-data.builder.d.ts +20 -0
  13. package/components/input/add-array-item-dialog-data.d.ts +19 -0
  14. package/components/input/input.component.d.ts +151 -30
  15. package/components/input/input.module.d.ts +7 -4
  16. package/components/table/create-dialog/create-dialog-data.builder.d.ts +21 -0
  17. package/components/table/create-dialog/create-entity-dialog-data.builder.d.ts +21 -0
  18. package/components/table/create-dialog/create-entity-dialog-data.d.ts +4 -5
  19. package/components/table/create-dialog/create-entity-dialog.component.d.ts +21 -8
  20. package/components/table/edit-dialog/edit-dialog-data.builder.d.ts +24 -0
  21. package/components/table/edit-dialog/edit-entity-dialog-data.d.ts +7 -8
  22. package/components/table/edit-dialog/edit-entity-dialog.builder.d.ts +22 -0
  23. package/components/table/edit-dialog/edit-entity-dialog.component.d.ts +25 -8
  24. package/components/table/table-data.builder.d.ts +51 -0
  25. package/components/table/table-data.d.ts +46 -30
  26. package/components/table/table.component.d.ts +53 -7
  27. package/components/table/table.module.d.ts +3 -1
  28. package/decorators/array/array-decorator-internal.data.d.ts +45 -0
  29. package/decorators/array/array-decorator.data.d.ts +129 -0
  30. package/decorators/array/array.decorator.d.ts +9 -0
  31. package/decorators/base/base-property.decorator.d.ts +7 -6
  32. package/decorators/base/decorator-types.enum.d.ts +12 -9
  33. package/decorators/base/dropdown-value.interface.d.ts +14 -0
  34. package/decorators/base/property-decorator-internal.data.d.ts +24 -0
  35. package/decorators/base/property-decorator.data.d.ts +70 -0
  36. package/decorators/boolean/boolean-decorator-internal.data.d.ts +25 -0
  37. package/decorators/boolean/boolean-decorator.data.d.ts +37 -0
  38. package/decorators/boolean/boolean.decorator.d.ts +8 -0
  39. package/decorators/date/date-decorator-internal.data.d.ts +44 -0
  40. package/decorators/date/date-decorator.data.d.ts +129 -0
  41. package/decorators/number/number-decorator-internal.data.d.ts +20 -0
  42. package/decorators/number/number-decorator.data.d.ts +36 -0
  43. package/decorators/number/number.decorator.d.ts +8 -0
  44. package/decorators/object/object-decorator-internal.data.d.ts +11 -0
  45. package/decorators/object/object-decorator.data.d.ts +25 -0
  46. package/decorators/object/object.decorator.d.ts +8 -0
  47. package/decorators/string/string-decorator-internal.data.d.ts +41 -0
  48. package/decorators/string/string-decorator.data.d.ts +77 -0
  49. package/decorators/string/string.decorator.d.ts +8 -0
  50. package/esm2020/classes/base.builder.mjs +43 -0
  51. package/esm2020/classes/date.utilities.mjs +138 -0
  52. package/esm2020/classes/entity.model.mjs +19 -0
  53. package/esm2020/classes/entity.service.mjs +83 -0
  54. package/esm2020/classes/entity.utilities.mjs +538 -0
  55. package/esm2020/components/confirm-dialog/confirm-dialog-data.builder.mjs +44 -0
  56. package/esm2020/components/confirm-dialog/confirm-dialog-data.mjs +1 -1
  57. package/esm2020/components/confirm-dialog/confirm-dialog.component.mjs +18 -22
  58. package/esm2020/components/get-validation-error-message.function.mjs +8 -3
  59. package/esm2020/components/input/add-array-item-dialog-data.builder.mjs +30 -0
  60. package/esm2020/components/input/add-array-item-dialog-data.mjs +2 -0
  61. package/esm2020/components/input/input.component.mjs +240 -36
  62. package/esm2020/components/input/input.module.mjs +23 -9
  63. package/esm2020/components/table/create-dialog/create-dialog-data.builder.mjs +32 -0
  64. package/esm2020/components/table/create-dialog/create-entity-dialog-data.builder.mjs +26 -0
  65. package/esm2020/components/table/create-dialog/create-entity-dialog-data.mjs +1 -1
  66. package/esm2020/components/table/create-dialog/create-entity-dialog.component.mjs +31 -31
  67. package/esm2020/components/table/create-dialog/create-entity-dialog.module.mjs +20 -4
  68. package/esm2020/components/table/edit-dialog/edit-dialog-data.builder.mjs +41 -0
  69. package/esm2020/components/table/edit-dialog/edit-entity-dialog-data.mjs +1 -1
  70. package/esm2020/components/table/edit-dialog/edit-entity-dialog.builder.mjs +27 -0
  71. package/esm2020/components/table/edit-dialog/edit-entity-dialog.component.mjs +45 -49
  72. package/esm2020/components/table/table-data.builder.mjs +105 -0
  73. package/esm2020/components/table/table-data.mjs +1 -1
  74. package/esm2020/components/table/table.component.mjs +91 -83
  75. package/esm2020/components/table/table.module.mjs +12 -4
  76. package/esm2020/decorators/array/array-decorator-internal.data.mjs +51 -0
  77. package/esm2020/decorators/array/array-decorator.data.mjs +7 -0
  78. package/esm2020/decorators/array/array.decorator.mjs +24 -0
  79. package/esm2020/decorators/base/base-property.decorator.mjs +6 -5
  80. package/esm2020/decorators/base/decorator-types.enum.mjs +4 -1
  81. package/esm2020/decorators/base/dropdown-value.interface.mjs +2 -0
  82. package/esm2020/decorators/base/property-decorator-internal.data.mjs +38 -0
  83. package/esm2020/decorators/base/property-decorator.data.mjs +6 -0
  84. package/esm2020/decorators/boolean/boolean-decorator-internal.data.mjs +33 -0
  85. package/esm2020/decorators/boolean/boolean-decorator.data.mjs +7 -0
  86. package/esm2020/decorators/boolean/boolean.decorator.mjs +21 -0
  87. package/esm2020/decorators/date/date-decorator-internal.data.mjs +48 -0
  88. package/esm2020/decorators/date/date-decorator.data.mjs +7 -0
  89. package/esm2020/decorators/number/number-decorator-internal.data.mjs +23 -0
  90. package/esm2020/decorators/number/number-decorator.data.mjs +7 -0
  91. package/esm2020/decorators/number/number.decorator.mjs +18 -0
  92. package/esm2020/decorators/object/object-decorator-internal.data.mjs +12 -0
  93. package/esm2020/decorators/object/object-decorator.data.mjs +7 -0
  94. package/esm2020/decorators/object/object.decorator.mjs +13 -0
  95. package/esm2020/decorators/string/string-decorator-internal.data.mjs +48 -0
  96. package/esm2020/decorators/string/string-decorator.data.mjs +7 -0
  97. package/esm2020/decorators/string/string.decorator.mjs +24 -0
  98. package/esm2020/public-api.mjs +20 -13
  99. package/fesm2015/ngx-material-entity.mjs +1664 -944
  100. package/fesm2015/ngx-material-entity.mjs.map +1 -1
  101. package/fesm2020/ngx-material-entity.mjs +1667 -941
  102. package/fesm2020/ngx-material-entity.mjs.map +1 -1
  103. package/package.json +7 -1
  104. package/public-api.d.ts +21 -10
  105. package/classes/entity-model.class.d.ts +0 -9
  106. package/classes/entity-utilities.class.d.ts +0 -95
  107. package/components/input/array-table/add-array-item-dialog/add-array-item-dialog.component.d.ts +0 -35
  108. package/components/input/array-table/add-array-item-dialog/add-array-item-dialog.module.d.ts +0 -12
  109. package/components/input/array-table/array-table.component.d.ts +0 -34
  110. package/components/input/array-table/array-table.module.d.ts +0 -19
  111. package/components/input/internal-input/internal-input.component.d.ts +0 -57
  112. package/components/input/internal-input/internal-input.module.d.ts +0 -16
  113. package/decorators/array.decorator.d.ts +0 -125
  114. package/decorators/base/property-decorator-config.interface.d.ts +0 -50
  115. package/decorators/boolean.decorator.d.ts +0 -42
  116. package/decorators/number.decorator.d.ts +0 -40
  117. package/decorators/object.decorator.d.ts +0 -27
  118. package/decorators/string.decorator.d.ts +0 -76
  119. package/esm2020/classes/entity-model.class.mjs +0 -19
  120. package/esm2020/classes/entity-service.class.mjs +0 -70
  121. package/esm2020/classes/entity-utilities.class.mjs +0 -296
  122. package/esm2020/components/input/array-table/add-array-item-dialog/add-array-item-dialog.component.mjs +0 -43
  123. package/esm2020/components/input/array-table/add-array-item-dialog/add-array-item-dialog.module.mjs +0 -22
  124. package/esm2020/components/input/array-table/array-table.component.mjs +0 -116
  125. package/esm2020/components/input/array-table/array-table.module.mjs +0 -66
  126. package/esm2020/components/input/internal-input/internal-input.component.mjs +0 -73
  127. package/esm2020/components/input/internal-input/internal-input.module.mjs +0 -54
  128. package/esm2020/decorators/array.decorator.mjs +0 -70
  129. package/esm2020/decorators/base/property-decorator-config.interface.mjs +0 -31
  130. package/esm2020/decorators/boolean.decorator.mjs +0 -44
  131. package/esm2020/decorators/number.decorator.mjs +0 -36
  132. package/esm2020/decorators/object.decorator.mjs +0 -23
  133. package/esm2020/decorators/string.decorator.mjs +0 -61
@@ -1,80 +1,51 @@
1
1
  import 'reflect-metadata';
2
2
  import { __decorate, __metadata } from 'tslib';
3
3
  import { BehaviorSubject, firstValueFrom, Subject, takeUntil } from 'rxjs';
4
- import { isEqual, omit, omitBy, isNil, cloneDeep } from 'lodash';
4
+ import { cloneDeep, isEqual, omit, omitBy, isNil } from 'lodash';
5
5
  import * as i0 from '@angular/core';
6
6
  import { Component, Inject, NgModule, Input, 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 i5 from '@angular/material/checkbox';
9
+ import * as i6 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 i7 from '@angular/common';
13
+ import * as i12 from '@angular/common';
14
14
  import { CommonModule } from '@angular/common';
15
- import * as i12 from '@angular/forms';
15
+ import * as i14 from '@angular/forms';
16
16
  import { FormsModule } from '@angular/forms';
17
- import * as i7$1 from '@angular/material/paginator';
18
- import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
19
- import { MatSort } from '@angular/material/sort';
20
- import * as i4$1 from '@angular/material/table';
17
+ import * as i9 from '@angular/material/table';
21
18
  import { MatTableDataSource, MatTableModule } from '@angular/material/table';
22
19
  import { SelectionModel } from '@angular/cdk/collections';
23
- import * as i1$1 from '@angular/material/form-field';
20
+ import * as i2 from '@angular/material/form-field';
24
21
  import { MatFormFieldModule } from '@angular/material/form-field';
25
- import * as i2 from '@angular/material/autocomplete';
22
+ import * as i3$1 from '@angular/material/autocomplete';
26
23
  import { MatAutocompleteModule } from '@angular/material/autocomplete';
27
- import * as i3$1 from '@angular/material/core';
28
- import * as i4 from '@angular/material/select';
24
+ import * as i4 from '@angular/material/core';
25
+ import * as i5 from '@angular/material/select';
29
26
  import { MatSelectModule } from '@angular/material/select';
30
- import * as i6 from '@angular/material/slide-toggle';
27
+ import * as i7 from '@angular/material/slide-toggle';
31
28
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
32
- import * as i8 from '@angular/material/input';
33
- import { MatInputModule } from '@angular/material/input';
34
- import * as i10 from '@angular/cdk/text-field';
35
- import * as i8$1 from '@angular/material/chips';
29
+ import * as i10 from '@angular/material/chips';
36
30
  import { MatChipsModule } from '@angular/material/chips';
37
- import * as i9 from '@angular/material/icon';
31
+ import * as i11 from '@angular/material/datepicker';
32
+ import { MatDatepickerModule } from '@angular/material/datepicker';
33
+ import * as i13 from '@angular/material/input';
34
+ import { MatInputModule } from '@angular/material/input';
35
+ import * as i15 from '@angular/cdk/text-field';
38
36
  import { MatIconModule } from '@angular/material/icon';
39
- import * as i4$2 from '@angular/material/menu';
37
+ import * as i7$1 from '@angular/material/paginator';
38
+ import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
39
+ import { MatSort } from '@angular/material/sort';
40
+ import * as i4$1 from '@angular/material/menu';
40
41
  import { MatMenuModule } from '@angular/material/menu';
41
42
 
42
43
  /**
43
- * The base options for all propertyDecorators
44
- */
45
- class PropertyDecoratorConfig {
46
- /**
47
- * Defines, Whether or not there should be a line break after this input.
48
- * Is used inside the default create and edit dialogs.
49
- */
50
- // lineBreakAfter?: boolean;
51
- constructor(displayName, display = true, required = true, omitForCreate = false, omitForUpdate = false, defaultWidths = [6, 6, 12], order
52
- // lineBreakAfter: boolean = false
53
- ) {
54
- this.displayName = displayName;
55
- this.display = display;
56
- this.required = required;
57
- this.omitForCreate = omitForCreate;
58
- this.omitForUpdate = omitForUpdate;
59
- this.defaultWidths = defaultWidths;
60
- if (order) {
61
- if (order < 0) {
62
- throw new Error('order must be at least 0');
63
- }
64
- this.order = order;
65
- }
66
- else {
67
- this.order = -1;
68
- }
69
- // this.lineBreakAfter = lineBreakAfter;
70
- }
71
- }
72
-
73
- /**
74
- * The base decorator for setting metadata on properties
75
- * @param metadata The metadata to define
76
- * @param type The type of metadata
77
- * @returns The function that sets the metadata
44
+ * The base decorator for setting metadata on properties.
45
+ *
46
+ * @param metadata - The metadata to define.
47
+ * @param type - The type of metadata.
48
+ * @returns The method that sets the metadata.
78
49
  */
79
50
  function baseProperty(metadata, type) {
80
51
  return function (target, propertyKey) {
@@ -101,68 +72,119 @@ var DecoratorTypes;
101
72
  DecoratorTypes["ARRAY"] = "array";
102
73
  DecoratorTypes["ARRAY_STRING_CHIPS"] = "arrayStringChips";
103
74
  DecoratorTypes["ARRAY_STRING_AUTOCOMPLETE_CHIPS"] = "arrayStringAutocompleteChips";
75
+ DecoratorTypes["DATE"] = "date";
76
+ DecoratorTypes["DATE_RANGE"] = "dateRange";
77
+ DecoratorTypes["DATE_TIME"] = "dateTime";
104
78
  })(DecoratorTypes || (DecoratorTypes = {}));
105
79
 
106
80
  /**
107
- * Decorator for setting and getting string propery metadata
108
- * @param metadata The metadata of the string property
81
+ * The internal Position. Sets default values and validates user input.
109
82
  */
110
- function string(metadata) {
111
- if (metadata.displayStyle === 'dropdown') {
112
- return baseProperty(new DropdownStringDecoratorConfig(metadata), DecoratorTypes.STRING_DROPDOWN);
113
- }
114
- else if (metadata.displayStyle === 'autocomplete') {
115
- return baseProperty(new AutocompleteStringDecoratorConfig(metadata), DecoratorTypes.STRING_AUTOCOMPLETE);
116
- }
117
- else if (metadata.displayStyle === 'textbox') {
118
- return baseProperty(new TextboxStringDecoratorConfig(metadata), DecoratorTypes.STRING_TEXTBOX);
83
+ class PositionInternal {
84
+ constructor(data) {
85
+ this.validateInput(data);
86
+ this.row = data?.row ? data.row : -1;
87
+ this.order = data?.order ? data.order : -1;
88
+ }
89
+ validateInput(data) {
90
+ if (data?.order) {
91
+ if (data.order < 1) {
92
+ throw new Error('order must be at least 1');
93
+ }
94
+ if (data.order > 12) {
95
+ throw new Error('order cannot be bigger than 12 (the minimum value for a bootstrap column)');
96
+ }
97
+ }
98
+ if (data?.row && (data.row < 1)) {
99
+ throw new Error('row must be at least 1');
100
+ }
119
101
  }
120
- else {
121
- return baseProperty(new DefaultStringDecoratorConfig(metadata), DecoratorTypes.STRING);
102
+ }
103
+ /**
104
+ * The internal PropertyDecoratorConfig. Sets default values.
105
+ */
106
+ class PropertyDecoratorConfigInternal {
107
+ constructor(data) {
108
+ this.display = data.display != undefined ? data.display : true;
109
+ this.displayName = data.displayName;
110
+ this.required = data.required != undefined ? data.required : true;
111
+ this.omitForCreate = data.omitForCreate != undefined ? data.omitForCreate : false;
112
+ this.omitForUpdate = data.omitForUpdate != undefined ? data.omitForUpdate : false;
113
+ this.defaultWidths = data.defaultWidths ? data.defaultWidths : [6, 6, 12];
114
+ this.position = new PositionInternal(data.position);
122
115
  }
123
116
  }
117
+
124
118
  /**
125
- * Interface definition for the @string metadata
119
+ * The internal DropdownStringDecoratorConfig. Sets default values.
126
120
  */
127
- class StringDecoratorConfig extends PropertyDecoratorConfig {
121
+ class DropdownStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
122
+ constructor(data) {
123
+ super(data);
124
+ this.displayStyle = data.displayStyle;
125
+ this.dropdownValues = data.dropdownValues;
126
+ }
128
127
  }
129
- class DropdownStringDecoratorConfig extends StringDecoratorConfig {
130
- constructor(metadata) {
131
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
132
- this.displayStyle = metadata.displayStyle;
133
- this.dropdownValues = metadata.dropdownValues;
128
+ /**
129
+ * The internal DefaultStringDecoratorConfig. Sets default values.
130
+ */
131
+ class DefaultStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
132
+ constructor(data) {
133
+ super(data);
134
+ this.displayStyle = data.displayStyle;
135
+ this.minLength = data.minLength;
136
+ this.maxLength = data.maxLength;
137
+ this.regex = data.regex;
134
138
  }
135
139
  }
136
- class DefaultStringDecoratorConfig extends StringDecoratorConfig {
137
- constructor(metadata) {
138
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
139
- this.displayStyle = metadata.displayStyle;
140
- this.minLength = metadata.minLength;
141
- this.maxLength = metadata.maxLength;
142
- this.regex = metadata.regex;
140
+ /**
141
+ * The internal TextboxStringDecoratorConfig. Sets default values.
142
+ */
143
+ class TextboxStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
144
+ constructor(data) {
145
+ super(data);
146
+ this.displayStyle = data.displayStyle;
147
+ this.minLength = data.minLength;
148
+ this.maxLength = data.maxLength;
143
149
  }
144
150
  }
145
- class TextboxStringDecoratorConfig extends StringDecoratorConfig {
146
- constructor(metadata) {
147
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
148
- this.displayStyle = metadata.displayStyle;
149
- this.minLength = metadata.minLength;
150
- this.maxLength = metadata.maxLength;
151
+ /**
152
+ * The internal AutocompleteStringDecoratorConfig. Sets default values.
153
+ */
154
+ class AutocompleteStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
155
+ constructor(data) {
156
+ super(data);
157
+ this.displayStyle = data.displayStyle;
158
+ this.autocompleteValues = data.autocompleteValues;
159
+ this.minLength = data.minLength;
160
+ this.maxLength = data.maxLength;
161
+ this.regex = data.regex;
151
162
  }
152
163
  }
153
- class AutocompleteStringDecoratorConfig extends StringDecoratorConfig {
154
- constructor(metadata) {
155
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
156
- this.displayStyle = metadata.displayStyle;
157
- this.autocompleteValues = metadata.autocompleteValues;
158
- this.minLength = metadata.minLength;
159
- this.maxLength = metadata.maxLength;
160
- this.regex = metadata.regex;
164
+
165
+ /**
166
+ * Decorator for setting and getting string Property metadata.
167
+ *
168
+ * @param metadata - The metadata of the string property.
169
+ * @returns The method that defines the metadata.
170
+ */
171
+ function string(metadata) {
172
+ if (metadata.displayStyle === 'dropdown') {
173
+ return baseProperty(new DropdownStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_DROPDOWN);
174
+ }
175
+ else if (metadata.displayStyle === 'autocomplete') {
176
+ return baseProperty(new AutocompleteStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_AUTOCOMPLETE);
177
+ }
178
+ else if (metadata.displayStyle === 'textbox') {
179
+ return baseProperty(new TextboxStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_TEXTBOX);
180
+ }
181
+ else {
182
+ return baseProperty(new DefaultStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING);
161
183
  }
162
184
  }
163
185
 
164
186
  /**
165
- * The base Entity class.
187
+ * A base Entity class with a builtin id.
166
188
  */
167
189
  class Entity {
168
190
  }
@@ -178,19 +200,157 @@ __decorate([
178
200
  __metadata("design:type", String)
179
201
  ], Entity.prototype, "id", void 0);
180
202
 
181
- var _a;
203
+ const DAY_IN_MS = 1000 * 60 * 60 * 24;
204
+ /**
205
+ * Contains Helper Functions for handling date properties.
206
+ */
207
+ class DateUtilities {
208
+ /**
209
+ * Gets the given value as a date value.
210
+ *
211
+ * @param value - The value to get as a date.
212
+ * @returns The given value as a date.
213
+ */
214
+ static asDate(value) {
215
+ return value;
216
+ }
217
+ /**
218
+ * Gets the default times used by the DateTime picker when nothing is specified by the user.
219
+ *
220
+ * @param format - The time format. Defaults to 24.
221
+ * @param minuteSteps - The steps from one time value to the next. Defaults to 30.
222
+ * @returns Times in the 24 hour format from 0:00 until 23:30 in 30 minute steps.
223
+ */
224
+ static getDefaultTimes(format = 24, minuteSteps = 30) {
225
+ const res = [{ displayName: '-', value: undefined }];
226
+ for (let hour = 0; hour < 24; hour++) {
227
+ for (let minute = 0; minute < 60; minute += minuteSteps) {
228
+ res.push(this.getTimeDropdownValue(format, hour, minute));
229
+ }
230
+ }
231
+ return res;
232
+ }
233
+ static getTimeDropdownValue(format, hour, minute) {
234
+ const displayHour = this.getFormattedHour(format, cloneDeep(hour));
235
+ const displayMinute = this.getFormattedMinute(format, hour, minute);
236
+ return {
237
+ displayName: `${displayHour}:${displayMinute}`,
238
+ value: {
239
+ hours: hour,
240
+ minutes: minute
241
+ }
242
+ };
243
+ }
244
+ static getFormattedHour(format, hour) {
245
+ if (format === 12 && hour > 12) {
246
+ hour -= 12;
247
+ }
248
+ return hour;
249
+ }
250
+ static getFormattedMinute(format, hour, minute) {
251
+ let res = `${minute}`;
252
+ if (format === 12) {
253
+ if (hour > 12) {
254
+ res = `${minute} PM`;
255
+ }
256
+ else {
257
+ res = `${minute} AM`;
258
+ }
259
+ }
260
+ if (minute.toString().length === 1) {
261
+ res = '0'.concat(res);
262
+ }
263
+ return res;
264
+ }
265
+ /**
266
+ * Gets the Time object from the given date.
267
+ *
268
+ * @param value - The date to get the time object from.
269
+ * @returns The Time object build from the date value.
270
+ */
271
+ static getTimeFromDate(value) {
272
+ if (!value) {
273
+ return {
274
+ hours: undefined,
275
+ minutes: undefined
276
+ };
277
+ }
278
+ else {
279
+ return {
280
+ hours: new Date(value).getHours(),
281
+ minutes: new Date(value).getMinutes()
282
+ };
283
+ }
284
+ }
285
+ /**
286
+ * Gets the dates between the two given gates. Does additional filtering based on the provided DateRange metadata.
287
+ *
288
+ * @param startDate - The start date.
289
+ * @param endDate - The end date.
290
+ * @param metadataDateRangeDate - The metadata.
291
+ * @returns All dates between the two provided dates. Includes start and end date.
292
+ */
293
+ static getDatesBetween(startDate, endDate, metadataDateRangeDate) {
294
+ const res = [];
295
+ while (startDate.getFullYear() < endDate.getFullYear()
296
+ || startDate.getMonth() < endDate.getMonth()
297
+ || startDate.getDate() <= endDate.getDate()) {
298
+ res.push(new Date(startDate));
299
+ startDate.setTime(startDate.getTime() + DAY_IN_MS);
300
+ }
301
+ if (metadataDateRangeDate.filter) {
302
+ return res.filter(d => metadataDateRangeDate.filter?.(d));
303
+ }
304
+ else {
305
+ return res;
306
+ }
307
+ }
308
+ /**
309
+ * Get all valid times for the dropdown of a datetime property.
310
+ *
311
+ * @param date - The date of the datetime.
312
+ * @param times - All given times to filter.
313
+ * @param min - The function that defines the minimum time.
314
+ * @param max - The function that defines the maximum time.
315
+ * @param filter - A filter function to do more specific time filtering. This could be e.g. The removal of lunch breaks.
316
+ * @returns All valid dropdown values for the datetime property.
317
+ */
318
+ static getValidTimesForDropdown(date, times, min, max, filter) {
319
+ if (min) {
320
+ const minTime = min(date);
321
+ times = times.filter(t => !t.value
322
+ || t.value.hours > minTime.hours
323
+ || (t.value.hours === minTime.hours
324
+ && t.value.minutes >= minTime.minutes));
325
+ }
326
+ if (max) {
327
+ const maxTime = max(date);
328
+ times = times.filter(t => !t.value
329
+ || t.value.hours < maxTime.hours
330
+ || (t.value.hours === maxTime.hours
331
+ && t.value.minutes <= maxTime.minutes));
332
+ }
333
+ if (filter) {
334
+ times = times.filter(t => !t.value || filter(t.value));
335
+ }
336
+ return times;
337
+ }
338
+ }
339
+
182
340
  /**
183
- * Contains HelperMethods around handling Entities and their property-metadata
341
+ * Contains HelperMethods around handling Entities and their property-metadata.
184
342
  */
185
343
  class EntityUtilities {
186
344
  /**
187
- * Gets the properties to omit when updating the entity
188
- * @returns The properties which should be left out for updating a new Entity
345
+ * Gets the properties to omit when updating the entity.
346
+ *
347
+ * @param entity - The entity to get the properties which should be left out for updating from.
348
+ * @returns The properties which should be left out for updating an Entity.
189
349
  */
190
350
  static getOmitForUpdate(entity) {
191
351
  const res = [];
192
- for (const key of Reflect.ownKeys(entity)) {
193
- const metadata = Reflect.getMetadata('metadata', entity, key);
352
+ for (const key of EntityUtilities.keysOf(entity)) {
353
+ const metadata = EntityUtilities.getPropertyMetadata(entity, key);
194
354
  if (metadata.omitForUpdate) {
195
355
  res.push(key);
196
356
  }
@@ -198,13 +358,15 @@ class EntityUtilities {
198
358
  return res;
199
359
  }
200
360
  /**
201
- * Gets the properties to omit when creating new entities
202
- * @returns The properties which should be left out for creating a new Entity
361
+ * Gets the properties to omit when creating new entities.
362
+ *
363
+ * @param entity - The entity to get the properties which should be left out for creating from.
364
+ * @returns The properties which should be left out for creating a new Entity.
203
365
  */
204
366
  static getOmitForCreate(entity) {
205
367
  const res = [];
206
- for (const key of Reflect.ownKeys(entity)) {
207
- const metadata = Reflect.getMetadata('metadata', entity, key);
368
+ for (const key of EntityUtilities.keysOf(entity)) {
369
+ const metadata = EntityUtilities.getPropertyMetadata(entity, key);
208
370
  if (metadata.omitForCreate) {
209
371
  res.push(key);
210
372
  }
@@ -212,11 +374,13 @@ class EntityUtilities {
212
374
  return res;
213
375
  }
214
376
  /**
215
- * Gets the metadata included in an property
216
- * @param entity The entity with the property to get the metadata from
217
- * @param propertyKey The property on the given Entity to get the metadata from
218
- * @param type For secure Typing, defines the returned PropertyConfig
219
- * @returns The metadata of the property
377
+ * Gets the metadata included in an property.
378
+ *
379
+ * @param entity - The entity with the property to get the metadata from.
380
+ * @param propertyKey - The property on the given Entity to get the metadata from.
381
+ * @param type - For secure Typing, defines the returned PropertyConfig.
382
+ * @returns The metadata of the property.
383
+ * @throws When no metadata can be found for the given property.
220
384
  */
221
385
  static getPropertyMetadata(entity, propertyKey,
222
386
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -224,143 +388,144 @@ class EntityUtilities {
224
388
  try {
225
389
  const metadata = Reflect.getMetadata('metadata', entity, propertyKey);
226
390
  if (!metadata) {
227
- throw new Error(`Could not find metadata for property ${String(propertyKey)}
228
- on the entity ${JSON.stringify(entity)}`);
391
+ throw new Error(`Could not find metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
229
392
  }
230
393
  return metadata;
231
394
  }
232
395
  catch (error) {
233
- throw new Error(`Could not find metadata for property ${String(propertyKey)}
234
- on the entity ${JSON.stringify(entity)}`);
396
+ throw new Error(`Could not find metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
235
397
  }
236
398
  }
237
399
  /**
238
400
  * Gets the type of the property-metadata.
239
- * @param entity The entity with the property to get the type from
240
- * @param propertyKey The property on the given Entity to get the type from
241
- * @returns The type of the metadata
401
+ *
402
+ * @param entity - The entity with the property to get the type from.
403
+ * @param propertyKey - The property on the given Entity to get the type from.
404
+ * @returns The type of the metadata.
405
+ * @throws Will throw an error if no metadata can be found for the given property.
242
406
  */
243
407
  static getPropertyType(entity, propertyKey) {
244
408
  try {
245
409
  const propertyType = Reflect.getMetadata('type', entity, propertyKey);
246
410
  if (!propertyType) {
247
- throw new Error(`Could not find type metadata for property ${String(propertyKey)}
248
- on the entity ${JSON.stringify(entity)}`);
411
+ throw new Error(`Could not find type metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
249
412
  }
250
413
  return propertyType;
251
414
  }
252
415
  catch (error) {
253
- throw new Error(`Could not find type metadata for property ${String(propertyKey)}
254
- on the entity ${JSON.stringify(entity)}`);
416
+ throw new Error(`Could not find type metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
255
417
  }
256
418
  }
257
419
  /**
258
420
  * Sets all property values based on a given entity data-object.
259
- * @param entity The data object to get the property values from.
260
- * @param target
261
- * the target object that needs to be constructed
262
- * (if called inside a Entity constructor its usually this)
421
+ *
422
+ * @param target - The target object that needs to be constructed (if called inside an Entity constructor its usually this).
423
+ * @param entity - The data object to get the property values from.
263
424
  * @alias new
264
425
  * @alias build
265
426
  * @alias construct
266
427
  */
267
428
  static new(target, entity) {
268
- if (entity) {
269
- for (const key in entity) {
270
- Reflect.set(target, key, Reflect.get(entity, key));
429
+ for (const key in target) {
430
+ const type = EntityUtilities.getPropertyType(target, key);
431
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
432
+ let value = entity ? Reflect.get(entity, key) : undefined;
433
+ switch (type) {
434
+ case DecoratorTypes.OBJECT:
435
+ const objectMetadata = EntityUtilities.getPropertyMetadata(target, key, DecoratorTypes.OBJECT);
436
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
437
+ value = new objectMetadata.EntityClass(value);
438
+ break;
439
+ case DecoratorTypes.ARRAY:
440
+ const inputArray = value;
441
+ const resArray = [];
442
+ if (inputArray) {
443
+ const arrayMetadata = EntityUtilities.getPropertyMetadata(target, key, DecoratorTypes.ARRAY);
444
+ for (const item of inputArray) {
445
+ const itemWithMetadata = new arrayMetadata.EntityClass(item);
446
+ resArray.push(itemWithMetadata);
447
+ }
448
+ }
449
+ value = resArray;
450
+ break;
451
+ default:
452
+ break;
271
453
  }
454
+ Reflect.set(target, key, value);
272
455
  }
273
456
  }
274
457
  /**
275
458
  * Checks if the values on an entity are valid.
276
- * Also checks all the validators given by the metadata ("required", "maxLength" etc.)
277
- * @param entity The entity to validate.
278
- * @param omit Whether to check for creatiung or editing validity
459
+ * Also checks all the validators given by the metadata ("required", "maxLength" etc.).
460
+ *
461
+ * @param entity - The entity to validate.
462
+ * @param omit - Whether to check for creating or editing validity.
279
463
  * @returns Whether or not the entity is valid.
280
464
  */
281
465
  static isEntityValid(entity, omit) {
282
466
  for (const key in entity) {
283
- if (!this.isPropertyValid(entity, key, omit)) {
467
+ if (!EntityUtilities.isPropertyValid(entity, key, omit)) {
284
468
  return false;
285
469
  }
286
470
  }
287
471
  return true;
288
472
  }
289
473
  /**
290
- * Checks if a single property value is valid
291
- * @param entity The entity where the property is from
292
- * @param key The name of the property
293
- * @returns Whether or not the property value is valid
474
+ * Checks if a single property value is valid.
475
+ *
476
+ * @param entity - The entity where the property is from.
477
+ * @param key - The name of the property.
478
+ * @param omit - Whether to check if the given entity is valid for creation or updating.
479
+ * @returns Whether or not the property value is valid.
480
+ * @throws Throws when it extracts an unknown metadata type.
294
481
  */
295
482
  static isPropertyValid(entity, key, omit) {
296
- const type = this.getPropertyType(entity, key);
297
- const metadata = this.getPropertyMetadata(entity, key, type);
298
- const metadataDefaultString = metadata;
299
- const metadataTextboxString = metadata;
300
- const metadataAutocompleteString = metadata;
301
- const metadataDefaultNumber = metadata;
302
- const objectProperty = entity[key];
303
- const metadataEntityArray = metadata;
304
- const arrayItems = entity[key];
483
+ const type = EntityUtilities.getPropertyType(entity, key);
484
+ const metadata = EntityUtilities.getPropertyMetadata(entity, key, type);
305
485
  if (metadata.omitForCreate && omit === 'create') {
306
486
  return true;
307
487
  }
308
- if (metadata.omitForUpdate && omit === 'edit') {
488
+ if (metadata.omitForUpdate && omit === 'update') {
309
489
  return true;
310
490
  }
311
491
  if (metadata.required && !entity[key]) {
312
492
  return false;
313
493
  }
314
494
  switch (type) {
495
+ case DecoratorTypes.BOOLEAN_DROPDOWN:
496
+ case DecoratorTypes.BOOLEAN_CHECKBOX:
497
+ case DecoratorTypes.BOOLEAN_TOGGLE:
498
+ return true;
499
+ case DecoratorTypes.STRING_DROPDOWN:
500
+ return true;
315
501
  case DecoratorTypes.STRING:
316
- if (metadataDefaultString.maxLength
317
- && entity[key].length > metadataDefaultString.maxLength) {
318
- return false;
319
- }
320
- if (metadataDefaultString.minLength
321
- && entity[key].length < metadataDefaultString.minLength) {
322
- return false;
323
- }
324
- if (metadataDefaultString.regex
325
- && !entity[key].match(metadataDefaultString.regex)) {
326
- return false;
327
- }
328
- break;
329
502
  case DecoratorTypes.STRING_AUTOCOMPLETE:
330
- if (metadataAutocompleteString.maxLength
331
- && entity[key].length > metadataAutocompleteString.maxLength) {
332
- return false;
333
- }
334
- if (metadataAutocompleteString.minLength
335
- && entity[key].length < metadataAutocompleteString.minLength) {
336
- return false;
337
- }
338
- if (metadataAutocompleteString.regex
339
- && entity[key].match(metadataAutocompleteString.regex)) {
503
+ const entityString = entity[key];
504
+ const stringMetadata = metadata;
505
+ if (!this.isStringValid(entityString, stringMetadata)) {
340
506
  return false;
341
507
  }
342
508
  break;
343
509
  case DecoratorTypes.STRING_TEXTBOX:
344
- if (metadataTextboxString.maxLength
345
- && entity[key].length > metadataTextboxString.maxLength) {
346
- return false;
347
- }
348
- if (metadataTextboxString.minLength
349
- && entity[key].length < metadataTextboxString.minLength) {
510
+ const entityTextbox = entity[key];
511
+ const textboxMetadata = metadata;
512
+ if (!this.isTextboxValid(entityTextbox, textboxMetadata)) {
350
513
  return false;
351
514
  }
352
515
  break;
516
+ case DecoratorTypes.NUMBER_DROPDOWN:
517
+ return true;
353
518
  case DecoratorTypes.NUMBER:
354
- if (metadataDefaultNumber.max && entity[key] > metadataDefaultNumber.max) {
355
- return false;
356
- }
357
- if (metadataDefaultNumber.min && entity[key] > metadataDefaultNumber.min) {
519
+ const entityNumber = entity[key];
520
+ const numberMetadata = metadata;
521
+ if (!this.isNumberValid(entityNumber, numberMetadata)) {
358
522
  return false;
359
523
  }
360
524
  break;
361
525
  case DecoratorTypes.OBJECT:
362
- for (const parameterKey in objectProperty) {
363
- if (!this.isPropertyValid(objectProperty, parameterKey, omit)) {
526
+ const entityObject = entity[key];
527
+ for (const parameterKey in entityObject) {
528
+ if (!EntityUtilities.isPropertyValid(entityObject, parameterKey, omit)) {
364
529
  return false;
365
530
  }
366
531
  }
@@ -368,7 +533,30 @@ class EntityUtilities {
368
533
  case DecoratorTypes.ARRAY_STRING_CHIPS:
369
534
  case DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS:
370
535
  case DecoratorTypes.ARRAY:
371
- if (metadataEntityArray.required && !arrayItems.length) {
536
+ const entityArray = entity[key];
537
+ const arrayMetadata = metadata;
538
+ if (arrayMetadata.required && !entityArray.length) {
539
+ return false;
540
+ }
541
+ break;
542
+ case DecoratorTypes.DATE:
543
+ const entityDate = new Date(entity[key]);
544
+ const dateMetadata = metadata;
545
+ if (!this.isDateValid(entityDate, dateMetadata)) {
546
+ return false;
547
+ }
548
+ break;
549
+ case DecoratorTypes.DATE_RANGE:
550
+ const entityDateRange = cloneDeep(entity[key]);
551
+ const dateRangeMetadata = metadata;
552
+ if (!this.isDateRangeValid(entityDateRange, dateRangeMetadata)) {
553
+ return false;
554
+ }
555
+ break;
556
+ case DecoratorTypes.DATE_TIME:
557
+ const entityDateTime = new Date(entity[key]);
558
+ const dateTimeMetadata = metadata;
559
+ if (!this.isDateTimeValid(entityDateTime, dateTimeMetadata)) {
372
560
  return false;
373
561
  }
374
562
  break;
@@ -377,100 +565,312 @@ class EntityUtilities {
377
565
  }
378
566
  return true;
379
567
  }
568
+ static isStringValid(value, metadata) {
569
+ if (metadata.maxLength && value.length > metadata.maxLength) {
570
+ return false;
571
+ }
572
+ if (metadata.minLength && value.length < metadata.minLength) {
573
+ return false;
574
+ }
575
+ if (metadata.regex && !value.match(metadata.regex)) {
576
+ return false;
577
+ }
578
+ return true;
579
+ }
580
+ static isTextboxValid(value, metadata) {
581
+ if (metadata.maxLength && value.length > metadata.maxLength) {
582
+ return false;
583
+ }
584
+ if (metadata.minLength && value.length < metadata.minLength) {
585
+ return false;
586
+ }
587
+ return true;
588
+ }
589
+ static isNumberValid(value, metadata) {
590
+ if (metadata.max && value > metadata.max) {
591
+ return false;
592
+ }
593
+ if (metadata.min && value < metadata.min) {
594
+ return false;
595
+ }
596
+ return true;
597
+ }
598
+ static isDateValid(value, metadata) {
599
+ if (metadata.min && value.getTime() < metadata.min(value).getTime()) {
600
+ return false;
601
+ }
602
+ if (metadata.max && value.getTime() > metadata.max(value).getTime()) {
603
+ return false;
604
+ }
605
+ if (metadata.filter && !metadata.filter(value)) {
606
+ return false;
607
+ }
608
+ return true;
609
+ }
610
+ static isDateRangeValid(value, metadata) {
611
+ if (metadata.required && (!value.start || !value.end)) {
612
+ return false;
613
+ }
614
+ value.start = new Date(value.start);
615
+ value.end = new Date(value.end);
616
+ if (metadata.minStart && value.start.getTime() < metadata.minStart(value.start).getTime()) {
617
+ return false;
618
+ }
619
+ if (metadata.maxStart && value.start.getTime() > metadata.maxStart(value.start).getTime()) {
620
+ return false;
621
+ }
622
+ if (metadata.minEnd && value.end.getTime() < metadata.minEnd(value.end).getTime()) {
623
+ return false;
624
+ }
625
+ if (metadata.maxEnd && value.end.getTime() > metadata.maxEnd(value.end).getTime()) {
626
+ return false;
627
+ }
628
+ if (metadata.filter) {
629
+ if (!metadata.filter(value.start)) {
630
+ return false;
631
+ }
632
+ if (!metadata.filter(value.end)) {
633
+ return false;
634
+ }
635
+ if (value.values) {
636
+ for (const date of value.values) {
637
+ if (!metadata.filter(date)) {
638
+ return false;
639
+ }
640
+ }
641
+ }
642
+ }
643
+ return true;
644
+ }
645
+ static isDateTimeValid(value, metadata) {
646
+ if (metadata.minDate && value.getTime() < metadata.minDate(value).getTime()) {
647
+ return false;
648
+ }
649
+ if (metadata.maxDate && value.getTime() > metadata.maxDate(value).getTime()) {
650
+ return false;
651
+ }
652
+ if (metadata.filterDate && !metadata.filterDate(value)) {
653
+ return false;
654
+ }
655
+ const time = {
656
+ hours: value.getHours(),
657
+ minutes: value.getMinutes()
658
+ };
659
+ if (metadata.minTime) {
660
+ const minTime = metadata.minTime(value);
661
+ if (!(time.hours > minTime.hours
662
+ || (time.hours === minTime.hours
663
+ && time.minutes >= minTime.minutes))) {
664
+ return false;
665
+ }
666
+ }
667
+ if (metadata.maxTime) {
668
+ const maxTime = metadata.maxTime(value);
669
+ if (!(time.hours < maxTime.hours
670
+ || (time.hours === maxTime.hours
671
+ && time.minutes <= maxTime.minutes))) {
672
+ return false;
673
+ }
674
+ }
675
+ if (metadata.filterTime) {
676
+ if (!metadata.filterTime(time)) {
677
+ return false;
678
+ }
679
+ }
680
+ return true;
681
+ }
380
682
  /**
381
- * Checks if an entity is "dirty" (if its values have changed)
382
- * @param entity The entity after all changes
383
- * @param entityPriorChanges The entity before the changes
384
- * @returns Whether or not the entity is dirty
683
+ * Checks if an entity is "dirty" (if its values have changed).
684
+ *
685
+ * @param entity - The entity after all changes.
686
+ * @param entityPriorChanges - The entity before the changes.
687
+ * @returns Whether or not the entity is dirty.
385
688
  */
386
689
  static dirty(entity, entityPriorChanges) {
387
690
  if (!entityPriorChanges) {
388
691
  return false;
389
692
  }
390
693
  else {
391
- const diff = this.difference(entity, entityPriorChanges);
392
- if (JSON.stringify(diff) === '{}') {
393
- return false;
394
- }
395
- else {
396
- return true;
694
+ const differences = this.differencesForDirty(entity, entityPriorChanges);
695
+ return differences.length ? true : false;
696
+ }
697
+ }
698
+ static differencesForDirty(entity, entityPriorChanges) {
699
+ const res = [];
700
+ for (const key in entity) {
701
+ if (!this.isEqual(entity[key], entityPriorChanges[key], EntityUtilities.getPropertyMetadata(entity, key))) {
702
+ res.push({
703
+ key: key,
704
+ before: entityPriorChanges[key],
705
+ after: entity[key]
706
+ });
397
707
  }
398
708
  }
709
+ return res;
399
710
  }
400
711
  /**
401
- * Compares two Entities and returns their difference in an object
402
- * @param entity The first entity to compare
403
- * @param entityPriorChanges The second entity to compare
404
- * @returns The difference between the two Entities in form of a Partial
712
+ * Compares two Entities and returns their difference in an object.
713
+ *
714
+ * @param entity - The first entity to compare.
715
+ * @param entityPriorChanges - The second entity to compare.
716
+ * @returns The difference between the two Entities in form of a Partial.
405
717
  */
406
718
  static difference(entity, entityPriorChanges) {
407
719
  const res = {};
408
720
  for (const key in entity) {
409
- if (!isEqual(entity[key], entityPriorChanges[key])) {
721
+ if (!this.isEqual(entity[key], entityPriorChanges[key], EntityUtilities.getPropertyMetadata(entity, key))) {
410
722
  res[key] = entity[key];
411
723
  }
412
724
  }
413
725
  return res;
414
726
  }
727
+ static isEqual(value, valuePriorChanges, metadata) {
728
+ if (this.isDateRange(value) && this.isDateRange(valuePriorChanges)) {
729
+ const dateRange = cloneDeep(value);
730
+ dateRange.start = new Date(value.start);
731
+ dateRange.end = new Date(value.end);
732
+ dateRange.values = DateUtilities.getDatesBetween(dateRange.start, dateRange.end, metadata);
733
+ const dateRangePriorChanges = cloneDeep(valuePriorChanges);
734
+ dateRangePriorChanges.start = new Date(valuePriorChanges.start);
735
+ dateRangePriorChanges.end = new Date(valuePriorChanges.end);
736
+ dateRangePriorChanges.values = DateUtilities.getDatesBetween(dateRangePriorChanges.start, dateRangePriorChanges.end, metadata);
737
+ return isEqual(dateRange, dateRangePriorChanges);
738
+ }
739
+ if (metadata.displayStyle === 'date') {
740
+ const date = new Date(DateUtilities.asDate(value));
741
+ const datePriorChanges = new Date(DateUtilities.asDate(valuePriorChanges));
742
+ date.setHours(0, 0, 0, 0);
743
+ datePriorChanges.setHours(0, 0, 0, 0);
744
+ return isEqual(date, datePriorChanges);
745
+ }
746
+ return isEqual(value, valuePriorChanges);
747
+ }
748
+ static isDateRange(value) {
749
+ const dateRange = value;
750
+ if (dateRange.start && dateRange.end) {
751
+ try {
752
+ new Date(dateRange.start);
753
+ new Date(dateRange.end);
754
+ return true;
755
+ }
756
+ catch (error) { }
757
+ ;
758
+ }
759
+ return false;
760
+ }
415
761
  /**
416
- * compare function for sorting entity keys by their order value
417
- * @param a first key of entity
418
- * @param b second key of entity
419
- * @param entity current entity (used to get metadata of entity keys)
762
+ * Compare function for sorting entity keys by their order value.
763
+ *
764
+ * @param a - First key of entity.
765
+ * @param b - Second key of entity.
766
+ * @param entity - Current entity (used to get metadata of entity keys).
767
+ * @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'.
420
768
  */
421
769
  static compareOrder(a, b, entity) {
422
- const metadataA = EntityUtilities.getPropertyMetadata(entity, a, EntityUtilities.getPropertyType(entity, a));
423
- const metadataB = EntityUtilities.getPropertyMetadata(entity, b, EntityUtilities.getPropertyType(entity, b));
424
- if (metadataA.order === -1) {
770
+ const metadataA = EntityUtilities.getPropertyMetadata(entity, a);
771
+ const metadataB = EntityUtilities.getPropertyMetadata(entity, b);
772
+ if (metadataA.position.order === -1) {
773
+ if (metadataB.position.order === -1) {
774
+ return 0;
775
+ }
425
776
  return 1;
426
777
  }
427
- else if (metadataB.order === -1) {
428
- return 0;
778
+ else if (metadataB.position.order === -1) {
779
+ return -1;
429
780
  }
430
- return (metadataA.order - metadataB.order);
781
+ return ((metadataA.position.order) - (metadataB.position.order));
431
782
  }
432
783
  /**
433
- * gets the bootstrap column values for "lg", "md", "sm"
434
- * @param entity entity to get the bootstrap column values of the key
435
- * @param key key of the property to get bootstrap column values from
436
- * @param type defines for which screensize the column values should be returned
437
- * @returns bootstrap column value
784
+ * Gets the bootstrap column values for "lg", "md", "sm".
785
+ *
786
+ * @param entity - Entity to get the bootstrap column values of the key.
787
+ * @param key - Key of the property to get bootstrap column values from.
788
+ * @param type - Defines for which screen size the column values should be returned.
789
+ * @returns Bootstrap column value.
438
790
  */
439
791
  static getWidth(entity, key, type) {
440
- const propertyType = EntityUtilities.getPropertyType(entity, key);
441
- const metadata = EntityUtilities.getPropertyMetadata(entity, key, propertyType);
442
- if (metadata.defaultWidths) {
443
- switch (type) {
444
- case 'lg':
445
- return metadata.defaultWidths[0];
446
- case 'md':
447
- return metadata.defaultWidths[1];
448
- case 'sm':
449
- return metadata.defaultWidths[2];
450
- default:
451
- throw new Error('Something went wrong getting the width');
452
- }
453
- }
454
- else {
455
- throw new Error('Something went wrong getting the width');
792
+ const metadata = EntityUtilities.getPropertyMetadata(entity, key);
793
+ switch (type) {
794
+ case 'lg':
795
+ return metadata.defaultWidths[0];
796
+ case 'md':
797
+ return metadata.defaultWidths[1];
798
+ case 'sm':
799
+ return metadata.defaultWidths[2];
456
800
  }
457
801
  }
458
802
  /**
459
- * Resets all changes on an entity
460
- * @param entity The entity to reset
461
- * @param entityPriorChanges The entity before any changes
803
+ * Resets all changes on an entity.
804
+ *
805
+ * @param entity - The entity to reset.
806
+ * @param entityPriorChanges - The entity before any changes.
462
807
  */
463
808
  static resetChangesOnEntity(entity, entityPriorChanges) {
464
809
  for (const key in entityPriorChanges) {
465
810
  Reflect.set(entity, key, Reflect.get(entityPriorChanges, key));
466
811
  }
467
812
  }
813
+ /**
814
+ * Gets the rows that are used to display the given entity.
815
+ *
816
+ * @param entity - The entity to get the rows from.
817
+ * @param hideOmitForCreate - Whether or not keys with the metadata omitForCreate should be filtered out.
818
+ * @param hideOmitForEdit - Whether or not keys with the metadata omitForUpdate should be filtered out.
819
+ * @returns The sorted Rows containing the row number and the keys to display in that row.
820
+ */
821
+ static getEntityRows(entity, hideOmitForCreate = false, hideOmitForEdit = false) {
822
+ const res = [];
823
+ const keys = EntityUtilities.keysOf(entity, hideOmitForCreate, hideOmitForEdit);
824
+ const numberOfRows = this.getNumberOfRows(keys, entity);
825
+ for (let i = 1; i <= numberOfRows; i++) {
826
+ const row = {
827
+ row: i,
828
+ keys: this.getKeysForRow(keys, entity, i)
829
+ };
830
+ res.push(row);
831
+ }
832
+ const lastRow = {
833
+ row: numberOfRows + 1,
834
+ keys: this.getKeysForRow(keys, entity, -1)
835
+ };
836
+ res.push(lastRow);
837
+ return res;
838
+ }
839
+ static getKeysForRow(keys, entity, i) {
840
+ return keys
841
+ .filter(k => EntityUtilities.getPropertyMetadata(entity, k).position.row === i)
842
+ .sort((a, b) => EntityUtilities.compareOrder(a, b, entity));
843
+ }
844
+ static getNumberOfRows(keys, entity) {
845
+ return keys
846
+ .map(k => EntityUtilities.getPropertyMetadata(entity, k).position.row)
847
+ .sort((a, b) => (a > b ? -1 : 1))[0];
848
+ }
849
+ /**
850
+ * Gets the keys of the provided entity correctly typed.
851
+ *
852
+ * @param entity - The entity to get the keys of.
853
+ * @param hideOmitForCreate - Whether or not keys with the metadata omitForCreate should be filtered out.
854
+ * @param hideOmitForEdit - Whether or not keys with the metadata omitForUpdate should be filtered out.
855
+ * @returns An array of keys of the entity.
856
+ */
857
+ static keysOf(entity, hideOmitForCreate = false, hideOmitForEdit = false) {
858
+ let keys = Reflect.ownKeys(entity);
859
+ if (hideOmitForCreate) {
860
+ const omitForCreateKeys = EntityUtilities.getOmitForCreate(entity);
861
+ keys = keys.filter(k => !omitForCreateKeys.includes(k));
862
+ }
863
+ if (hideOmitForEdit) {
864
+ const omitForUpdateKeys = EntityUtilities.getOmitForUpdate(entity);
865
+ keys = keys.filter(k => !omitForUpdateKeys.includes(k));
866
+ }
867
+ return keys;
868
+ }
468
869
  }
469
- _a = EntityUtilities;
470
- // eslint-disable-next-line @typescript-eslint/member-ordering
471
- EntityUtilities.construct = _a.new;
472
- // eslint-disable-next-line @typescript-eslint/member-ordering
473
- EntityUtilities.build = _a.new;
870
+ // eslint-disable-next-line @typescript-eslint/member-ordering, jsdoc/require-jsdoc
871
+ EntityUtilities.construct = EntityUtilities.new;
872
+ // eslint-disable-next-line @typescript-eslint/member-ordering, jsdoc/require-jsdoc
873
+ EntityUtilities.build = EntityUtilities.new;
474
874
 
475
875
  /**
476
876
  * A generic EntityService class.
@@ -482,22 +882,31 @@ class EntityService {
482
882
  constructor(http) {
483
883
  this.http = http;
484
884
  /**
485
- * a subject of all the entity values.
885
+ * The key which holds the id value.
886
+ *
887
+ * @default 'id'
888
+ */
889
+ this.idKey = 'id';
890
+ /**
891
+ * A subject of all the entity values.
486
892
  * Can be subscribed to when you want to do a specific thing whenever the entities change.
487
893
  */
488
894
  this.entitiesSubject = new BehaviorSubject([]);
489
895
  }
490
896
  /**
491
- * gets the entities in an array from the internal entitiesSubject
897
+ * Gets the entities in an array from the internal entitiesSubject.
898
+ *
899
+ * @returns The current entities in form of an array.
492
900
  */
493
901
  get entities() {
494
902
  return this.entitiesSubject.value;
495
903
  }
496
904
  /**
497
- * Creates a new Entity and pushes it to the entities array
498
- * @param entity The data of the entity to create.
905
+ * Creates a new Entity and pushes it to the entities array.
906
+ *
907
+ * @param entity - The data of the entity to create.
499
908
  * All values that should be omitted will be removed from it inside this method.
500
- * @returns A Promise of the created entity
909
+ * @returns A Promise of the created entity.
501
910
  */
502
911
  async create(entity) {
503
912
  const body = omit(entity, EntityUtilities.getOmitForCreate(entity));
@@ -507,8 +916,9 @@ class EntityService {
507
916
  return e;
508
917
  }
509
918
  /**
510
- * Gets all existing entities and pushes them to the entites array
511
- * @returns A Promise of all received Entities
919
+ * Gets all existing entities and pushes them to the entities array.
920
+ *
921
+ * @returns A Promise of all received Entities.
512
922
  */
513
923
  async read() {
514
924
  const e = await firstValueFrom(this.http.get(this.baseUrl));
@@ -516,67 +926,151 @@ class EntityService {
516
926
  return e;
517
927
  }
518
928
  /**
519
- * Updates a specific Entity
520
- * @param entity The updated Entity
929
+ * Updates a specific Entity.
930
+ *
931
+ * @param entity - The updated Entity
521
932
  * All values that should be omitted will be removed from it inside this method.
522
- * @param entityPriorChanges The current Entity.
523
- * It Is used to get changed values and only update them instead of sending the whole entity data
933
+ * @param entityPriorChanges - The current Entity.
934
+ * It Is used to get changed values and only update them instead of sending the whole entity data.
524
935
  */
525
936
  async update(entity, entityPriorChanges) {
526
937
  const reqBody = omit(EntityUtilities.difference(entity, entityPriorChanges), EntityUtilities.getOmitForUpdate(entity));
527
- const updatedEntity = await firstValueFrom(this.http.patch(`${this.baseUrl}/${entityPriorChanges.id}`, omitBy(reqBody, isNil)));
528
- this.entities[this.entities.findIndex((e) => e.id === entityPriorChanges.id)] = updatedEntity;
938
+ const updatedEntity = await firstValueFrom(this.http.patch(`${this.baseUrl}/${entityPriorChanges[this.idKey]}`, omitBy(reqBody, isNil)));
939
+ this.entities[this.entities.findIndex(e => e[this.idKey] === entityPriorChanges[this.idKey])] = updatedEntity;
529
940
  this.entitiesSubject.next(this.entities);
530
941
  }
531
942
  /**
532
- * Method to delete a specific Entity
533
- * @param id The id of the element to delete
943
+ * Deletes a specific Entity.
944
+ *
945
+ * @param entity - The entity to delete.
534
946
  */
535
- async delete(id) {
536
- await firstValueFrom(this.http.delete(`${this.baseUrl}/${id}`));
537
- this.entities.splice(this.entities.findIndex((e) => e.id === id), 1);
947
+ async delete(entity) {
948
+ await firstValueFrom(this.http.delete(`${this.baseUrl}/${entity[this.idKey]}`));
949
+ // the == comparison instead of === is to catch ids that are numbers.
950
+ this.entities.splice(this.entities.findIndex(e => e[this.idKey] === entity[this.idKey]), 1);
538
951
  this.entitiesSubject.next(this.entities);
539
952
  }
540
953
  }
541
954
 
542
- class NgxMatEntityConfirmDialogComponent {
543
- constructor(dialogRef, data) {
544
- this.dialogRef = dialogRef;
545
- this.data = data;
546
- /**
547
- * Used for the checkbox to confirm the action
548
- */
549
- this.confirm = false;
955
+ /**
956
+ * The abstract BaseBuilder class.
957
+ */
958
+ class BaseBuilder {
959
+ constructor(data) {
960
+ this.validateInput(data);
961
+ this.inputData = data;
962
+ this.data = this.generateBaseData(data);
963
+ return this;
550
964
  }
551
- ngOnInit() {
552
- if (this.data.requireConfirmation && !this.data.confirmationText) {
553
- throw new Error(`
554
- Missing required Input "confirmationText".
555
- You can only omit this if you dont have "requireConfirmation" set`);
556
- }
557
- if (!this.data.requireConfirmation && this.data.confirmationText) {
558
- throw new Error('The "confirmationText" will never be shown because "requireConfirmation" is not set to true');
559
- }
560
- if (this.data.requireConfirmation !== true && this.data.requireConfirmation !== false) {
561
- this.data.requireConfirmation = false;
562
- }
563
- if (this.data.type === 'info-only' && this.data.cancelButtonLabel) {
564
- throw new Error('The "cancelButtonLabel" will never be shown because "type" is set to "info-only"');
965
+ /**
966
+ * Used to validate the user input in the constructor.
967
+ *
968
+ * @param data - The user input.
969
+ */
970
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
971
+ validateInput(data) {
972
+ // By default, no validation is done
973
+ }
974
+ ;
975
+ /**
976
+ * Sets the value for the given key if no user value was provided.
977
+ *
978
+ * @param key - The key to set the default value for.
979
+ * @param value - The value to set when nothing was provided.
980
+ * @returns The Builder.
981
+ */
982
+ withDefault(key, value) {
983
+ if (!this.inputData || !this.inputData[key]) {
984
+ this.data[key] = value;
565
985
  }
566
- this.dialogRef.disableClose = true;
986
+ return this;
567
987
  }
568
- confirmAction() {
569
- this.dialogRef.close(1);
988
+ /**
989
+ * Method used to get the final build value after applying all chaining.
990
+ *
991
+ * @returns The build value.
992
+ */
993
+ getResult() {
994
+ return this.data;
995
+ }
996
+ }
997
+
998
+ /**
999
+ * The internal ConfirmDialogData. Requires all default values the user can leave out.
1000
+ */
1001
+ class ConfirmDialogDataInternal {
1002
+ constructor(text, type, confirmButtonLabel, cancelButtonLabel, title, requireConfirmation, confirmationText) {
1003
+ this.text = text;
1004
+ this.type = type;
1005
+ this.confirmButtonLabel = confirmButtonLabel;
1006
+ this.cancelButtonLabel = cancelButtonLabel;
1007
+ this.title = title;
1008
+ this.requireConfirmation = requireConfirmation;
1009
+ this.confirmationText = confirmationText;
1010
+ }
1011
+ }
1012
+ /**
1013
+ * The Builder for the ConfirmDialogData. Sets default values.
1014
+ */
1015
+ class ConfirmDialogDataBuilder extends BaseBuilder {
1016
+ constructor(data) {
1017
+ super(data);
1018
+ }
1019
+ // eslint-disable-next-line jsdoc/require-jsdoc
1020
+ generateBaseData(data) {
1021
+ return new ConfirmDialogDataInternal(data?.text ? data.text : ['Do you really want to do this?'], data?.type ? data.type : 'default', data?.confirmButtonLabel ? data.confirmButtonLabel : 'Confirm', data?.cancelButtonLabel ? data.cancelButtonLabel : 'Cancel', data?.title ? data.title : 'Confirmation', data?.requireConfirmation ? data.requireConfirmation : false, data?.confirmationText);
1022
+ }
1023
+ // eslint-disable-next-line jsdoc/require-jsdoc
1024
+ validateInput(data) {
1025
+ if (!data) {
1026
+ return;
1027
+ }
1028
+ if (data.requireConfirmation && !data.confirmationText) {
1029
+ throw new Error(`Missing required Input data "confirmationText".
1030
+ You can only omit this value when "requireConfirmation" is false.`);
1031
+ }
1032
+ if (!data.requireConfirmation && data.confirmationText) {
1033
+ throw new Error('The "confirmationText" will never be shown because "requireConfirmation" is not set to true');
1034
+ }
1035
+ if (data.type === 'info-only' && data.cancelButtonLabel) {
1036
+ throw new Error('The "cancelButtonLabel" will never be shown because "type" is set to "info-only"');
1037
+ }
1038
+ }
1039
+ }
1040
+
1041
+ /**
1042
+ * The Dialog used whenever confirmation by the user is required (e.g. When the user tries to delete an entity).
1043
+ *
1044
+ * Can be customized with the MAT_DIALOG_DATA "inputData". Customization options are defined in "ConfirmDialogData".
1045
+ */
1046
+ class NgxMatEntityConfirmDialogComponent {
1047
+ constructor(dialogRef, inputData) {
1048
+ this.dialogRef = dialogRef;
1049
+ this.inputData = inputData;
1050
+ this.confirm = false;
1051
+ }
1052
+ ngOnInit() {
1053
+ this.data = new ConfirmDialogDataBuilder(this.inputData).getResult();
1054
+ this.dialogRef.disableClose = true;
1055
+ }
1056
+ /**
1057
+ * Closes the dialog with value 1 to signal that the action should be run.
1058
+ */
1059
+ confirmAction() {
1060
+ this.dialogRef.close(1);
570
1061
  }
1062
+ /**
1063
+ * Closes the dialog.
1064
+ */
571
1065
  cancel() {
572
1066
  this.dialogRef.close();
573
1067
  }
574
1068
  }
575
1069
  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 });
576
- 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 ? data.confirmButtonLabel : 'Delete'}}\n </button>\n <button *ngIf=\"data.type !== 'delete'\" mat-raised-button (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel ? data.confirmButtonLabel : data.type === 'info-only' ? 'Ok' : 'Confirm'}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.cancelButtonLabel ? data.cancelButtonLabel : 'Cancel'}}\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: i5.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: i7.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: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i12.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i12.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]" }] });
1070
+ 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: i12.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: i12.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i14.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i14.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]" }] });
577
1071
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityConfirmDialogComponent, decorators: [{
578
1072
  type: Component,
579
- 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 ? data.confirmButtonLabel : 'Delete'}}\n </button>\n <button *ngIf=\"data.type !== 'delete'\" mat-raised-button (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel ? data.confirmButtonLabel : data.type === 'info-only' ? 'Ok' : 'Confirm'}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.cancelButtonLabel ? data.cancelButtonLabel : 'Cancel'}}\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"] }]
1073
+ 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"] }]
580
1074
  }], ctorParameters: function () { return [{ type: i1.MatDialogRef }, { type: undefined, decorators: [{
581
1075
  type: Inject,
582
1076
  args: [MAT_DIALOG_DATA]
@@ -598,8 +1092,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
598
1092
 
599
1093
  /**
600
1094
  * Generates a default error message for most validation errors.
601
- * @param model The ngModel to get the error from
602
- * @returns The Validation Error Message to display
1095
+ *
1096
+ * @param model - The ngModel to get the error from.
1097
+ * @returns The Validation Error Message to display.
603
1098
  */
604
1099
  function getValidationErrorMessage(model) {
605
1100
  if (model.hasError('matDatepickerParse')) {
@@ -623,85 +1118,95 @@ function getValidationErrorMessage(model) {
623
1118
  else if (model.hasError('required')) {
624
1119
  return 'required';
625
1120
  }
1121
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1122
+ else if (model.hasError('pattern') && model.getError('pattern').requiredPattern === '^true$') {
1123
+ return 'needs to be selected';
1124
+ }
626
1125
  else {
627
1126
  return 'invalid input';
628
1127
  }
629
1128
  }
630
1129
 
631
1130
  /**
632
- * Decorator for setting and getting array propery metadata
633
- * @param metadata The metadata of the array property
1131
+ * The internal CreateDialogData. Requires all default values the user can leave out.
634
1132
  */
635
- function array(metadata) {
636
- switch (metadata.itemType) {
637
- case DecoratorTypes.OBJECT:
638
- return baseProperty(new EntityArrayDecoratorConfig(metadata), DecoratorTypes.ARRAY);
639
- case DecoratorTypes.STRING:
640
- return baseProperty(new StringChipsArrayDecoratorConfig(metadata), DecoratorTypes.ARRAY_STRING_CHIPS);
641
- case DecoratorTypes.STRING_AUTOCOMPLETE:
642
- return baseProperty(new AutocompleteStringChipsArrayDecoratorConfig(metadata), DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS);
643
- default:
644
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
645
- throw new Error(`Unknown itemType ${metadata.itemType}`);
1133
+ class CreateDialogDataInternal {
1134
+ constructor(title, createButtonLabel, cancelButtonLabel, createRequiresConfirmDialog, confirmCreateDialogData) {
1135
+ this.title = title;
1136
+ this.createButtonLabel = createButtonLabel;
1137
+ this.cancelButtonLabel = cancelButtonLabel;
1138
+ this.createRequiresConfirmDialog = createRequiresConfirmDialog;
1139
+ this.confirmCreateDialogData = confirmCreateDialogData;
646
1140
  }
647
1141
  }
648
1142
  /**
649
- * Interface definition for the @array metadata
650
- */
651
- class ArrayDecoratorConfig extends PropertyDecoratorConfig {
652
- }
653
- /**
654
- * Definition for an array of Entities
1143
+ * The Builder for the CreateDialogData. Sets default values.
655
1144
  */
656
- class EntityArrayDecoratorConfig extends ArrayDecoratorConfig {
657
- constructor(metadata) {
658
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
659
- this.itemType = metadata.itemType;
660
- this.displayStyle = metadata.displayStyle;
661
- this.EntityClass = metadata.EntityClass;
662
- this.createDialogData = metadata.createDialogData;
663
- this.missingErrorMessage = metadata.missingErrorMessage;
664
- this.createInline = metadata.createInline;
665
- this.displayColumns = metadata.displayColumns;
1145
+ class CreateDialogDataBuilder extends BaseBuilder {
1146
+ constructor(data) {
1147
+ super(data);
1148
+ }
1149
+ // eslint-disable-next-line jsdoc/require-jsdoc
1150
+ generateBaseData(data) {
1151
+ const confirmCreateDialogData = new ConfirmDialogDataBuilder(data?.confirmCreateDialogData)
1152
+ .withDefault('confirmButtonLabel', 'create')
1153
+ .withDefault('text', ['Do you really want to create this entity?'])
1154
+ .withDefault('title', 'Create')
1155
+ .getResult();
1156
+ return new CreateDialogDataInternal(data?.title ? data.title : 'Create', data?.createButtonLabel ? data.createButtonLabel : 'Create', data?.cancelButtonLabel ? data.cancelButtonLabel : 'Cancel', data?.createRequiresConfirmDialog ? data.createRequiresConfirmDialog : false, confirmCreateDialogData);
666
1157
  }
667
1158
  }
1159
+
668
1160
  /**
669
- * Definition for an array of strings displayed as a chips list
1161
+ * The internal AddArrayItemDialogData. Requires all default values the user can leave out.
670
1162
  */
671
- class StringChipsArrayDecoratorConfig extends ArrayDecoratorConfig {
672
- constructor(metadata) {
673
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
674
- this.itemType = metadata.itemType;
675
- this.displayStyle = metadata.displayStyle;
676
- this.deleteHtml = metadata.deleteHtml;
677
- this.minLength = metadata.minLength;
678
- this.maxLength = metadata.maxLength;
679
- this.regex = metadata.regex;
1163
+ class AddArrayItemDialogDataInternal {
1164
+ constructor(entity, createDialogData, getValidationErrorMessage) {
1165
+ this.entity = entity;
1166
+ this.createDialogData = createDialogData;
1167
+ this.getValidationErrorMessage = getValidationErrorMessage;
680
1168
  }
681
1169
  }
682
1170
  /**
683
- * Definition for an array of autocomplete strings displayed as a chips list
1171
+ * The Builder for the AddArrayItemDialogData. Sets default values.
684
1172
  */
685
- class AutocompleteStringChipsArrayDecoratorConfig extends ArrayDecoratorConfig {
686
- constructor(metadata) {
687
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
688
- this.itemType = metadata.itemType;
689
- this.displayStyle = metadata.displayStyle;
690
- this.deleteHtml = metadata.deleteHtml;
691
- this.autocompleteValues = metadata.autocompleteValues;
692
- this.minLength = metadata.minLength;
693
- this.maxLength = metadata.maxLength;
694
- this.regex = metadata.regex;
1173
+ class AddArrayItemDialogDataBuilder extends BaseBuilder {
1174
+ constructor(data) {
1175
+ super(data);
1176
+ }
1177
+ // eslint-disable-next-line jsdoc/require-jsdoc
1178
+ generateBaseData(data) {
1179
+ const createDialogData = new CreateDialogDataBuilder(data.createDialogData)
1180
+ .withDefault('createButtonLabel', 'Add')
1181
+ .withDefault('title', 'Add to array')
1182
+ .getResult();
1183
+ return new AddArrayItemDialogDataInternal(data.entity, createDialogData, data.getValidationErrorMessage ? data.getValidationErrorMessage : getValidationErrorMessage);
695
1184
  }
696
1185
  }
697
1186
 
698
- class NgxMatEntityInternalInputComponent {
699
- constructor() {
1187
+ /**
1188
+ * The default input component. It gets the metadata of the property from the given @Input "entity" and @Input "propertyKey"
1189
+ * and displays the input field accordingly.
1190
+ *
1191
+ * You can also define a method that generates error-messages and if the input should be hidden when its metadata says
1192
+ * that it should be omitted for creating or updating.
1193
+ * The last part being mostly relevant if you want to use this component inside an ngFor.
1194
+ */
1195
+ class NgxMatEntityInputComponent {
1196
+ constructor(dialog) {
1197
+ this.dialog = dialog;
1198
+ this.chipsInput = '';
1199
+ this.selection = new SelectionModel(true, []);
700
1200
  this.DecoratorTypes = DecoratorTypes;
701
- this.getWidth = EntityUtilities.getWidth;
1201
+ this.EntityUtilities = EntityUtilities;
1202
+ this.DateUtilities = DateUtilities;
1203
+ this.defaultDateFilter = () => true;
702
1204
  }
703
1205
  /**
704
- * Helper method needed to recursively generate property input components (used eg. with the object)
1206
+ * This is needed for the inputs to work inside an ngFor.
1207
+ *
1208
+ * @param index - The index of the element in the ngFor.
1209
+ * @returns The index.
705
1210
  */
706
1211
  trackByFn(index) {
707
1212
  return index;
@@ -718,244 +1223,206 @@ class NgxMatEntityInternalInputComponent {
718
1223
  this.metadataDefaultString = this.metadata;
719
1224
  this.metadataTextboxString = this.metadata;
720
1225
  this.metadataAutocompleteString = this.metadata;
1226
+ this.autocompleteStrings = this.metadataAutocompleteString.autocompleteValues;
1227
+ this.filteredAutocompleteStrings = cloneDeep(this.autocompleteStrings);
721
1228
  this.metadataDropdownString = this.metadata;
722
1229
  this.metadataDropdownBoolean = this.metadata;
1230
+ if ((this.type === DecoratorTypes.BOOLEAN_CHECKBOX || this.type === DecoratorTypes.BOOLEAN_TOGGLE)
1231
+ && this.entity[this.propertyKey] === undefined) {
1232
+ this.entity[this.propertyKey] = false;
1233
+ }
723
1234
  this.metadataDefaultNumber = this.metadata;
724
1235
  this.metadataDropdownNumber = this.metadata;
725
1236
  this.metadataDefaultObject = this.metadata;
726
1237
  this.objectProperty = this.entity[this.propertyKey];
727
- }
728
- getObjectProperties() {
729
- const res = [];
730
- for (const property in this.objectProperty) {
731
- const metadata = EntityUtilities.getPropertyMetadata(this.objectProperty, property, EntityUtilities.getPropertyType(this.objectProperty, property));
732
- if (!(this.hideOmitForCreate && metadata.omitForCreate)
733
- && !(this.hideOmitForEdit && metadata.omitForUpdate)) {
734
- res.push(property);
1238
+ if (this.type === DecoratorTypes.OBJECT) {
1239
+ this.objectPropertyRows = EntityUtilities.getEntityRows(this.objectProperty, this.hideOmitForCreate, this.hideOmitForEdit);
1240
+ }
1241
+ this.metadataEntityArray = this.metadata;
1242
+ if (this.type === DecoratorTypes.ARRAY) {
1243
+ if (!this.entity[this.propertyKey]) {
1244
+ this.entity[this.propertyKey] = [];
1245
+ }
1246
+ this.entityArrayValues = this.entity[this.propertyKey];
1247
+ if (this.metadataEntityArray.createInline === undefined) {
1248
+ this.metadataEntityArray.createInline = true;
1249
+ }
1250
+ if (!this.metadataEntityArray.createInline && !this.metadataEntityArray.createDialogData) {
1251
+ this.metadataEntityArray.createDialogData = {
1252
+ title: 'Add'
1253
+ };
1254
+ }
1255
+ const givenDisplayColumns = this.metadataEntityArray.displayColumns.map((v) => v.displayName);
1256
+ if (givenDisplayColumns.find(s => s === 'select')) {
1257
+ throw new Error(`The name "select" for a display column is reserved.
1258
+ Please choose a different name.`);
1259
+ }
1260
+ this.displayedColumns = ['select'].concat(givenDisplayColumns);
1261
+ this.dataSource = new MatTableDataSource();
1262
+ this.dataSource.data = this.entityArrayValues;
1263
+ this.arrayItem = new this.metadataEntityArray.EntityClass();
1264
+ this.arrayItemInlineRows = EntityUtilities.getEntityRows(this.arrayItem, this.hideOmitForCreate === false ? false : true, this.hideOmitForEdit ? true : false);
1265
+ this.arrayItemPriorChanges = cloneDeep(this.arrayItem);
1266
+ this.dialogInputData = {
1267
+ entity: this.arrayItem,
1268
+ createDialogData: this.metadataEntityArray.createDialogData,
1269
+ getValidationErrorMessage: this.getValidationErrorMessage
1270
+ };
1271
+ this.dialogData = new AddArrayItemDialogDataBuilder(this.dialogInputData).getResult();
1272
+ this.arrayItemDialogRows = EntityUtilities.getEntityRows(this.dialogData.entity, true);
1273
+ }
1274
+ this.metadataStringChipsArray = this.metadata;
1275
+ if ((this.type === DecoratorTypes.ARRAY_STRING_CHIPS || this.type === DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS)
1276
+ && this.entity[this.propertyKey]?.length) {
1277
+ this.stringChipsArrayValues = this.entity[this.propertyKey];
1278
+ }
1279
+ this.metadataAutocompleteStringChipsArray = this.metadata;
1280
+ if (!this.getValidationErrorMessage) {
1281
+ this.getValidationErrorMessage = getValidationErrorMessage;
1282
+ }
1283
+ this.metadataDefaultDate = this.metadata;
1284
+ this.metadataDateRangeDate = this.metadata;
1285
+ this.metadataDateTimeDate = this.metadata;
1286
+ if (this.type === DecoratorTypes.DATE_RANGE) {
1287
+ this.dateRange = cloneDeep(this.entity[this.propertyKey]);
1288
+ if (!this.dateRange) {
1289
+ this.dateRange = {
1290
+ start: undefined,
1291
+ end: undefined,
1292
+ values: undefined
1293
+ };
1294
+ }
1295
+ this.dateRangeStart = new Date(this.dateRange.start);
1296
+ this.dateRangeEnd = new Date(this.dateRange.end);
1297
+ this.setDateRangeValues();
1298
+ }
1299
+ if (this.type === DecoratorTypes.DATE_TIME) {
1300
+ this.time = DateUtilities.getTimeFromDate(DateUtilities.asDate(this.entity[this.propertyKey]));
1301
+ this.timeDropdownValues = this.metadataDateTimeDate.times;
1302
+ if (this.entity[this.propertyKey]) {
1303
+ this.dateTime = new Date(this.entity[this.propertyKey]);
735
1304
  }
736
1305
  }
737
- return res.sort((a, b) => EntityUtilities.compareOrder(a, b, this.objectProperty));
738
- }
739
- }
740
- NgxMatEntityInternalInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInternalInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
741
- NgxMatEntityInternalInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityInternalInputComponent, selector: "ngx-mat-entity-internal-input", inputs: { entity: "entity", propertyKey: "propertyKey", hideOmitForCreate: "hideOmitForCreate", hideOmitForEdit: "hideOmitForEdit", getValidationErrorMessage: "getValidationErrorMessage" }, 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 [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 [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 [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 metadataAutocompleteString.autocompleteValues\" [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\">\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>\n <mat-checkbox [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\">\n {{metadata.displayName}}\n </mat-checkbox>\n <!-- hidden input is needed so that the checkbox can be used inside a mat-form-field -->\n <textarea matInput hidden></textarea>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <mat-form-field>\n <mat-slide-toggle [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\">\n {{metadata.displayName}}\n </mat-slide-toggle>\n <!-- hidden input is needed so that the toggle can be used inside a mat-form-field -->\n <textarea matInput hidden></textarea>\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\">\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 [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\">\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 <div class=\"row\">\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-internal-input\n *ngFor=\"let key of getObjectProperties(); 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-internal-input>\n </div>\n </div>\n\n <div *ngSwitchDefault>ERROR: The type {{type}}is not known.</div>\n</div>", 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.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { type: i3$1.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i4.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i5.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: i6.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: NgxMatEntityInternalInputComponent, selector: "ngx-mat-entity-internal-input", inputs: ["entity", "propertyKey", "hideOmitForCreate", "hideOmitForEdit", "getValidationErrorMessage"] }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i7.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i1$1.MatLabel, selector: "mat-label" }, { type: i8.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: i12.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: i12.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i12.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i12.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i12.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i12.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }, { type: i10.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { type: i2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i12.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i12.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i12.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { type: i7.NgSwitchDefault, selector: "[ngSwitchDefault]" }] });
742
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInternalInputComponent, decorators: [{
743
- type: Component,
744
- args: [{ selector: 'ngx-mat-entity-internal-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 [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 [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 [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 metadataAutocompleteString.autocompleteValues\" [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\">\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>\n <mat-checkbox [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\">\n {{metadata.displayName}}\n </mat-checkbox>\n <!-- hidden input is needed so that the checkbox can be used inside a mat-form-field -->\n <textarea matInput hidden></textarea>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <mat-form-field>\n <mat-slide-toggle [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\">\n {{metadata.displayName}}\n </mat-slide-toggle>\n <!-- hidden input is needed so that the toggle can be used inside a mat-form-field -->\n <textarea matInput hidden></textarea>\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\">\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 [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\">\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 <div class=\"row\">\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-internal-input\n *ngFor=\"let key of getObjectProperties(); 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-internal-input>\n </div>\n </div>\n\n <div *ngSwitchDefault>ERROR: The type {{type}}is not known.</div>\n</div>", styles: ["mat-form-field{width:100%}\n"] }]
745
- }], propDecorators: { entity: [{
746
- type: Input
747
- }], propertyKey: [{
748
- type: Input
749
- }], hideOmitForCreate: [{
750
- type: Input
751
- }], hideOmitForEdit: [{
752
- type: Input
753
- }], getValidationErrorMessage: [{
754
- type: Input
755
- }] } });
756
-
757
- class NgxMatEntityAddArrayItemDialogComponent {
758
- constructor(data, dialogRef) {
759
- this.data = data;
760
- this.dialogRef = dialogRef;
761
- this.EntityUtilities = EntityUtilities;
762
- this.getWidth = EntityUtilities.getWidth;
763
- }
764
- ngOnInit() {
765
- this.dialogRef.disableClose = true;
766
- this.setEntityKeys();
767
- }
768
- setEntityKeys() {
769
- this.entityKeys = Reflect.ownKeys(this.data.entity);
770
- const omitCreateKeys = EntityUtilities.getOmitForCreate(this.data.entity);
771
- this.entityKeys = this.entityKeys.filter((k) => !omitCreateKeys.includes(k))
772
- .sort((a, b) => EntityUtilities.compareOrder(a, b, this.data.entity));
773
- }
774
- create() {
775
- this.dialogRef.close(1);
776
- }
777
- cancel() {
778
- this.dialogRef.close();
779
- }
780
- }
781
- NgxMatEntityAddArrayItemDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityAddArrayItemDialogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component });
782
- NgxMatEntityAddArrayItemDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityAddArrayItemDialogComponent, selector: "ngx-mat-entity-add-array-item-dialog", ngImport: i0, template: "<h2 mat-dialog-title>{{data.createDialogData.title}}</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <ngx-mat-entity-internal-input\n *ngFor=\"let key of entityKeys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"data.getValidationErrorMessage\"\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-internal-input>\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 ? data.createDialogData.createButtonLabel : 'Add'}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.createDialogData.cancelButtonLabel ? data.createDialogData.cancelButtonLabel : 'Cancel'}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}\n"], components: [{ type: NgxMatEntityInternalInputComponent, selector: "ngx-mat-entity-internal-input", inputs: ["entity", "propertyKey", "hideOmitForCreate", "hideOmitForEdit", "getValidationErrorMessage"] }, { 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: i12.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i12.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i12.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
783
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityAddArrayItemDialogComponent, decorators: [{
784
- type: Component,
785
- args: [{ selector: 'ngx-mat-entity-add-array-item-dialog', template: "<h2 mat-dialog-title>{{data.createDialogData.title}}</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <ngx-mat-entity-internal-input\n *ngFor=\"let key of entityKeys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"data.getValidationErrorMessage\"\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-internal-input>\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 ? data.createDialogData.createButtonLabel : 'Add'}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.createDialogData.cancelButtonLabel ? data.createDialogData.cancelButtonLabel : 'Cancel'}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}\n"] }]
786
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
787
- type: Inject,
788
- args: [MAT_DIALOG_DATA]
789
- }] }, { type: i1.MatDialogRef }]; } });
790
-
791
- class NgxMatEntityArrayTableComponent {
792
- constructor(dialog) {
793
- this.dialog = dialog;
794
- this.selection = new SelectionModel(true, []);
795
- this.getWidth = EntityUtilities.getWidth;
796
- this.EntityUtilities = EntityUtilities;
797
1306
  }
798
- trackByFn(index) {
799
- return index;
1307
+ /**
1308
+ * Checks if two times are equal. Is needed for the dropdown.
1309
+ *
1310
+ * @param time1 - The first time to compare.
1311
+ * @param time2 - The second time to compare.
1312
+ * @returns Whether or not the time objects are the same.
1313
+ */
1314
+ compareTimes(time1, time2) {
1315
+ return time1 && time2 && time1.hours === time2.hours && time1.minutes === time2.minutes;
800
1316
  }
801
- ngOnInit() {
802
- this.validateInput();
803
- const givenDisplayColumns = this.metadata.displayColumns.map((v) => v.displayName);
804
- if (givenDisplayColumns.find((s) => s === 'select')) {
805
- throw new Error(`The name "select" for a display column is reserved.
806
- Please choose a different name.`);
1317
+ /**
1318
+ * Updates the date range values based on the start and end date.
1319
+ */
1320
+ setDateRangeValues() {
1321
+ if (this.dateRangeStart && this.dateRangeEnd) {
1322
+ this.dateRange.start = new Date(this.dateRangeStart);
1323
+ this.dateRange.end = new Date(this.dateRangeEnd);
1324
+ const values = DateUtilities.getDatesBetween(new Date(this.dateRange.start), new Date(this.dateRange.end), this.metadataDateRangeDate);
1325
+ this.dateRange.values = values.length ? values : undefined;
807
1326
  }
808
- this.displayedColumns = ['select'].concat(givenDisplayColumns);
809
- this.dataSource = new MatTableDataSource();
810
- this.dataSource.data = this.arrayItems;
811
- this.arrayItem = new this.metadata.EntityClass();
812
- this.arrayItemPriorChanges = cloneDeep(this.arrayItem);
1327
+ else {
1328
+ this.dateRange.values = undefined;
1329
+ }
1330
+ this.entity[this.propertyKey] = this.dateRange;
813
1331
  }
814
- validateInput() {
815
- if (!this.metadata.createInline && !this.metadata.createDialogData) {
816
- throw new Error(`Missing required Input data "createDialogData".
817
- You can only omit this value when the creation is inline.`);
1332
+ /**
1333
+ * Sets the time on a datetime property.
1334
+ */
1335
+ setTime() {
1336
+ if (!this.dateTime) {
1337
+ this.entity[this.propertyKey] = undefined;
1338
+ return;
1339
+ }
1340
+ this.entity[this.propertyKey] = new Date(this.dateTime);
1341
+ if (this.time?.hours != null && this.time?.minutes != null) {
1342
+ DateUtilities.asDate(this.entity[this.propertyKey]).setHours(this.time.hours, this.time.minutes, 0, 0);
1343
+ }
1344
+ else {
1345
+ DateUtilities.asDate(this.entity[this.propertyKey]).setHours(0, 0, 0, 0);
818
1346
  }
819
1347
  }
1348
+ /**
1349
+ * Tries to add an item to the array.
1350
+ * Does this either inline if the "createInline"-metadata is set to true
1351
+ * or in a separate dialog if it is set to false.
1352
+ */
820
1353
  add() {
821
- if (this.metadata.createInline) {
822
- this.arrayItems.push(cloneDeep(this.arrayItem));
823
- this.dataSource.data = this.arrayItems;
1354
+ if (this.metadataEntityArray.createInline) {
1355
+ this.entityArrayValues.push(cloneDeep(this.arrayItem));
1356
+ this.dataSource.data = this.entityArrayValues;
824
1357
  EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
825
1358
  }
826
1359
  else {
827
- const dialogData = {
828
- entity: this.arrayItem,
829
- createDialogData: this.metadata.createDialogData,
830
- getValidationErrorMessage: this.getValidationErrorMessage
831
- };
832
- firstValueFrom(this.dialog.open(NgxMatEntityAddArrayItemDialogComponent, {
833
- data: dialogData,
1360
+ this.addArrayItemDialogRef = this.dialog.open(this.addArrayItemDialog, {
1361
+ data: this.dialogData,
834
1362
  autoFocus: false,
835
1363
  restoreFocus: false
836
- }).afterClosed()).then((res) => {
837
- if (res === 1) {
838
- this.arrayItems.push(cloneDeep(this.arrayItem));
839
- this.dataSource.data = this.arrayItems;
840
- }
841
- EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
842
1364
  });
843
1365
  }
844
1366
  }
1367
+ /**
1368
+ * Adds the array item defined in the dialog.
1369
+ */
1370
+ addArrayItem() {
1371
+ this.addArrayItemDialogRef.close();
1372
+ this.entityArrayValues.push(cloneDeep(this.arrayItem));
1373
+ this.dataSource.data = this.entityArrayValues;
1374
+ EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
1375
+ }
1376
+ /**
1377
+ * Cancels adding the array item defined in the dialog.
1378
+ */
1379
+ cancelAddArrayItem() {
1380
+ this.addArrayItemDialogRef.close();
1381
+ EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
1382
+ }
1383
+ /**
1384
+ * Removes all selected entries from the array.
1385
+ */
845
1386
  remove() {
846
1387
  this.selection.selected.forEach(s => {
847
- this.arrayItems.splice(this.arrayItems.indexOf(s), 1);
1388
+ this.entityArrayValues.splice(this.entityArrayValues.indexOf(s), 1);
848
1389
  });
849
- this.dataSource.data = this.arrayItems;
1390
+ this.dataSource.data = this.entityArrayValues;
850
1391
  this.selection.clear();
851
1392
  }
852
- getObjectProperties() {
853
- const res = [];
854
- for (const property in this.arrayItem) {
855
- const metadata = EntityUtilities.getPropertyMetadata(this.arrayItem, property, EntityUtilities.getPropertyType(this.arrayItem, property));
856
- if (!(metadata.omitForCreate)) {
857
- res.push(property);
858
- }
859
- }
860
- return res.sort((a, b) => EntityUtilities.compareOrder(a, b, this.arrayItem));
861
- }
1393
+ /**
1394
+ * Toggles all array-items in the table.
1395
+ */
862
1396
  masterToggle() {
863
1397
  if (this.isAllSelected()) {
864
1398
  this.selection.clear();
865
1399
  }
866
1400
  else {
867
- this.dataSource.data.forEach((row) => this.selection.select(row));
1401
+ this.dataSource.data.forEach(row => this.selection.select(row));
868
1402
  }
869
1403
  }
1404
+ /**
1405
+ * Checks if all array-items in the table have been selected.
1406
+ * This is needed to display the "masterToggle"-checkbox correctly.
1407
+ *
1408
+ * @returns Whether or not all array-items in the table have been selected.
1409
+ */
870
1410
  isAllSelected() {
871
1411
  const numSelected = this.selection.selected.length;
872
1412
  const numRows = this.dataSource.data.length;
873
1413
  return numSelected === numRows;
874
1414
  }
875
- }
876
- NgxMatEntityArrayTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityArrayTableComponent, deps: [{ token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
877
- NgxMatEntityArrayTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityArrayTableComponent, selector: "ngx-mat-entity-array-table", inputs: { arrayItems: "arrayItems", metadata: "metadata", getValidationErrorMessage: "getValidationErrorMessage", omit: "omit" }, ngImport: i0, template: "<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>{{metadata.displayName}}</b>\n </div>\n <div class=\"row\" *ngIf=\"metadata.createInline\">\n <ngx-mat-entity-internal-input\n *ngFor=\"let key of getObjectProperties(); 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-internal-input>\n </div>\n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"metadata.createInline && !EntityUtilities.isEntityValid(arrayItem, 'create')\"\n (click)=\"add()\">\n Add\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n Remove\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 (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 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 ? metadata.missingErrorMessage : 'Needs to have at least one value'}}\n </div>\n</div>", styles: [".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.5px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"], components: [{ type: NgxMatEntityInternalInputComponent, selector: "ngx-mat-entity-internal-input", inputs: ["entity", "propertyKey", "hideOmitForCreate", "hideOmitForEdit", "getValidationErrorMessage"] }, { 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.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i5.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$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i4$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i4$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i4$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i4$1.MatCellDef, selector: "[matCellDef]" }, { type: i4$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i4$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i4$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }] });
878
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityArrayTableComponent, decorators: [{
879
- type: Component,
880
- args: [{ selector: 'ngx-mat-entity-array-table', template: "<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>{{metadata.displayName}}</b>\n </div>\n <div class=\"row\" *ngIf=\"metadata.createInline\">\n <ngx-mat-entity-internal-input\n *ngFor=\"let key of getObjectProperties(); 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-internal-input>\n </div>\n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"metadata.createInline && !EntityUtilities.isEntityValid(arrayItem, 'create')\"\n (click)=\"add()\">\n Add\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n Remove\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 (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 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 ? metadata.missingErrorMessage : 'Needs to have at least one value'}}\n </div>\n</div>", styles: [".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.5px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"] }]
881
- }], ctorParameters: function () { return [{ type: i1.MatDialog }]; }, propDecorators: { arrayItems: [{
882
- type: Input
883
- }], metadata: [{
884
- type: Input
885
- }], getValidationErrorMessage: [{
886
- type: Input
887
- }], omit: [{
888
- type: Input
889
- }] } });
890
-
891
- class NgxMatEntityInputComponent {
892
- constructor() {
893
- this.chipsInput = '';
894
- this.DecoratorTypes = DecoratorTypes;
895
- this.getWidth = EntityUtilities.getWidth;
896
- }
897
1415
  /**
898
- * Helper method needed to recursively generate property input components (used eg. with the object)
1416
+ * Handles adding strings to the chipsArray.
1417
+ * Checks validation and also creates a new array if it is undefined.
1418
+ * This is needed because two things are validated: The array itself
1419
+ * and the contents of the array. And we need a way to display an
1420
+ * mat-error. As the only validation for the array is whether or not
1421
+ * it contains values, we can set it to undefined when the last element is removed
1422
+ * (removeStringChipArrayValue). That way we can use the "required" validator.
1423
+ *
1424
+ * @param event - The event that fires when a new chip is completed.
899
1425
  */
900
- trackByFn(index) {
901
- return index;
902
- }
903
- ngOnInit() {
904
- if (!this.entity) {
905
- throw new Error('Missing required Input data "entity"');
906
- }
907
- if (!this.propertyKey) {
908
- throw new Error('Missing required Input data "propertyKey"');
909
- }
910
- this.type = EntityUtilities.getPropertyType(this.entity, this.propertyKey);
911
- this.metadata = EntityUtilities.getPropertyMetadata(this.entity, this.propertyKey, this.type);
912
- this.metadataDefaultString = this.metadata;
913
- this.metadataTextboxString = this.metadata;
914
- this.metadataAutocompleteString = this.metadata;
915
- this.autocompleteStrings = this.metadataAutocompleteString.autocompleteValues;
916
- this.filteredAutocompleteStrings = cloneDeep(this.autocompleteStrings);
917
- this.metadataDropdownString = this.metadata;
918
- this.metadataDropdownBoolean = this.metadata;
919
- this.metadataDefaultNumber = this.metadata;
920
- this.metadataDropdownNumber = this.metadata;
921
- this.metadataDefaultObject = this.metadata;
922
- this.objectProperty = this.entity[this.propertyKey];
923
- this.metadataEntityArray = this.metadata;
924
- if (this.metadataEntityArray.EntityClass) {
925
- if (!this.entity[this.propertyKey]) {
926
- this.entity[this.propertyKey] = [];
927
- }
928
- this.entityArrayValues = this.entity[this.propertyKey];
929
- if (this.metadataEntityArray.createInline === undefined) {
930
- this.metadataEntityArray.createInline = true;
931
- }
932
- if (!this.metadataEntityArray.createInline && !this.metadataEntityArray.createDialogData) {
933
- this.metadataEntityArray.createDialogData = {
934
- title: 'Add'
935
- };
936
- }
937
- }
938
- this.metadataStringChipsArray = this.metadata;
939
- if (this.metadataStringChipsArray.itemType
940
- && this.entity[this.propertyKey]?.length) {
941
- this.stringChipsArrayValues = this.entity[this.propertyKey];
942
- }
943
- this.metadataAutocompleteStringChipsArray = this.metadata;
944
- if (!this.getValidationErrorMessage) {
945
- this.getValidationErrorMessage = getValidationErrorMessage;
946
- }
947
- }
948
- getObjectProperties() {
949
- const res = [];
950
- for (const property in this.objectProperty) {
951
- const metadata = EntityUtilities.getPropertyMetadata(this.objectProperty, property, EntityUtilities.getPropertyType(this.objectProperty, property));
952
- if (!(this.hideOmitForCreate && metadata.omitForCreate)
953
- && !(this.hideOmitForEdit && metadata.omitForUpdate)) {
954
- res.push(property);
955
- }
956
- }
957
- return res.sort((a, b) => EntityUtilities.compareOrder(a, b, this.objectProperty));
958
- }
959
1426
  addStringChipArrayValue(event) {
960
1427
  const value = (event.value || '').trim();
961
1428
  if (value) {
@@ -978,6 +1445,16 @@ class NgxMatEntityInputComponent {
978
1445
  }
979
1446
  event.chipInput.clear();
980
1447
  }
1448
+ /**
1449
+ * Removes the given value from the array.
1450
+ * Sets the array to undefined if it is now empty.
1451
+ * This is needed because two things are validated: The array itself
1452
+ * and the contents of the array. And we need a way to display an
1453
+ * mat-error. As the only validation for the array is whether or not
1454
+ * it is empty, setting it to undefined here enables us to use the "required" validator.
1455
+ *
1456
+ * @param value - The string to remove from the array.
1457
+ */
981
1458
  removeStringChipArrayValue(value) {
982
1459
  this.stringChipsArrayValues.splice(this.stringChipsArrayValues.indexOf(value), 1);
983
1460
  if (!this.stringChipsArrayValues.length) {
@@ -985,6 +1462,12 @@ class NgxMatEntityInputComponent {
985
1462
  this.stringChipsArrayValues = this.entity[this.propertyKey];
986
1463
  }
987
1464
  }
1465
+ /**
1466
+ * Handles adding a string to the array when an autocomplete value has been selected.
1467
+ *
1468
+ * @param event - The autocomplete selected event.
1469
+ * @param chipsInput - The element where the user typed the value.
1470
+ */
988
1471
  selected(event, chipsInput) {
989
1472
  const value = (event.option.viewValue || '').trim();
990
1473
  if (this.metadataStringChipsArray.minLength && value.length < this.metadataStringChipsArray.minLength) {
@@ -1005,17 +1488,24 @@ class NgxMatEntityInputComponent {
1005
1488
  this.stringChipsArrayValues.push(value);
1006
1489
  chipsInput.value = '';
1007
1490
  }
1491
+ /**
1492
+ * Dynamically filters the Autocomplete options when the user inputs something.
1493
+ *
1494
+ * @param input - The input of the user.
1495
+ */
1008
1496
  filterAutocompleteStrings(input) {
1009
- const filterValue = input.toLowerCase();
1010
- this.filteredAutocompleteStrings = this.autocompleteStrings.filter(s => s.toLowerCase().includes(filterValue));
1497
+ if (input) {
1498
+ const filterValue = input.toLowerCase();
1499
+ this.filteredAutocompleteStrings = this.autocompleteStrings.filter(s => s.toLowerCase().includes(filterValue));
1500
+ }
1011
1501
  }
1012
1502
  }
1013
- NgxMatEntityInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1014
- 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" }, 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 ? metadata.required : false\"\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 ? metadata.required : false\"\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 ? metadata.required : false\"\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 ? metadata.required : false\">\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>\n <mat-checkbox [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\" [required]=\"metadata.required ? metadata.required : false\">\n {{metadata.displayName}}\n </mat-checkbox>\n <!-- hidden input is needed so that the checkbox can be used inside a mat-form-field -->\n <textarea matInput hidden></textarea>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <mat-form-field>\n <mat-slide-toggle [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\" [required]=\"metadata.required ? metadata.required : false\">\n {{metadata.displayName}}\n </mat-slide-toggle>\n <!-- hidden input is needed so that the toggle can be used inside a mat-form-field -->\n <textarea matInput hidden></textarea>\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 ? metadata.required : false\">\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 ? metadata.required : false\"\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 ? metadata.required : false\">\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 <div class=\"row\">\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 getObjectProperties(); 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 *ngSwitchCase=\"DecoratorTypes.ARRAY\">\n <ngx-mat-entity-array-table\n [arrayItems]=\"entityArrayValues\"\n [metadata]=\"metadataEntityArray\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [omit]=\"hideOmitForCreate ? 'create' : 'edit'\"\n >\n </ngx-mat-entity-array-table>\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 ? metadata.required : false\"\n >\n <mat-chip *ngFor=\"let value of stringChipsArrayValues\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove *ngIf=\"metadataStringChipsArray.deleteHtml\" [innerHtml]=\"metadataStringChipsArray.deleteHtml\">\n </button>\n <button matChipRemove *ngIf=\"!metadataStringChipsArray.deleteHtml\">\n <mat-icon>cancel</mat-icon>\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 ? metadata.required : false\"\n >\n <mat-chip *ngFor=\"let value of stringChipsArrayValues\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove *ngIf=\"metadataStringChipsArray.deleteHtml\" [innerHtml]=\"metadataStringChipsArray.deleteHtml\">\n </button>\n <button matChipRemove *ngIf=\"!metadataStringChipsArray.deleteHtml\">\n <mat-icon>cancel</mat-icon>\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>", 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.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { type: i3$1.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i4.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i5.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: i6.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: NgxMatEntityArrayTableComponent, selector: "ngx-mat-entity-array-table", inputs: ["arrayItems", "metadata", "getValidationErrorMessage", "omit"] }, { type: i8$1.MatChipList, selector: "mat-chip-list", inputs: ["errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i7.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i1$1.MatLabel, selector: "mat-label" }, { type: i8.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: i12.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: i12.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i12.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i12.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i12.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i12.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i12.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }, { type: i10.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { type: i2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.MatCheckboxRequiredValidator, selector: "mat-checkbox[required][formControlName], mat-checkbox[required][formControl], mat-checkbox[required][ngModel]" }, { type: i6.MatSlideToggleRequiredValidator, selector: "mat-slide-toggle[required][formControlName], mat-slide-toggle[required][formControl], mat-slide-toggle[required][ngModel]" }, { type: i12.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i12.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i12.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { type: i8$1.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: i8$1.MatChipRemove, selector: "[matChipRemove]" }, { type: i8$1.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { type: i7.NgSwitchDefault, selector: "[ngSwitchDefault]" }] });
1503
+ NgxMatEntityInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputComponent, deps: [{ token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
1504
+ 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-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.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-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.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 <!-------------------------------------------->\n <!-------------------Dates-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.DATE\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadataDefaultDate.min ? metadataDefaultDate.min(DateUtilities.asDate(entity[propertyKey])) : undefined\"\n [max]=\"metadataDefaultDate.max ? metadataDefaultDate.max(DateUtilities.asDate(entity[propertyKey])) : undefined\"\n [matDatepickerFilter]=\"metadataDefaultDate.filter ? metadataDefaultDate.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>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.DATE_RANGE\">\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]=\"metadataDateRangeDate.filter ? metadataDateRangeDate.filter : defaultDateFilter\">\n <input matStartDate\n [(ngModel)]=\"dateRangeStart\"\n [name]=\"propertyKey.toString() + 'start'\"\n #startModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadataDateRangeDate.minStart ? metadataDateRangeDate.minStart(dateRange.start) : undefined\"\n [max]=\"metadataDateRangeDate.maxStart ? metadataDateRangeDate.maxStart(dateRange.start) : undefined\"\n [placeholder]=\"metadataDateRangeDate.placeholderStart ? metadataDateRangeDate.placeholderStart : 'Start'\"\n (ngModelChange)=\"setDateRangeValues()\"\n >\n <input matEndDate\n [(ngModel)]=\"dateRangeEnd\"\n [name]=\"propertyKey.toString() + 'end'\"\n #endModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadataDateRangeDate.minEnd ? metadataDateRangeDate.minEnd(dateRange.end) : undefined\"\n [max]=\"metadataDateRangeDate.maxEnd ? metadataDateRangeDate.maxEnd(dateRange.end) : undefined\"\n [placeholder]=\"metadataDateRangeDate.placeholderEnd ? metadataDateRangeDate.placeholderEnd : 'End'\"\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>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.DATE_TIME\" class=\"date-time\">\n <mat-form-field appearance=\"standard\" class=\"datepicker\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"dateTime\"\n [name]=\"propertyKey.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadataDateTimeDate.minDate ? metadataDateTimeDate.minDate(dateTime) : undefined\"\n [max]=\"metadataDateTimeDate.maxDate ? metadataDateTimeDate.maxDate(dateTime) : undefined\"\n [matDatepickerFilter]=\"metadataDateTimeDate.filterDate ? metadataDateTimeDate.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>{{metadataDateTimeDate.timeDisplayName}}</mat-label>\n <mat-select\n [(ngModel)]=\"time\"\n [name]=\"propertyKey.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[propertyKey]),\n metadataDateTimeDate.times,\n metadataDateTimeDate.minTime,\n metadataDateTimeDate.maxTime,\n metadataDateTimeDate.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\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 >\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}.date-time{display:flex;align-items:baseline}.date-time .timepicker{margin-left:10px}\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"] }, { type: i11.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i11.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { type: i11.MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { type: i11.MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }], directives: [{ type: i12.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i12.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i12.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i2.MatLabel, selector: "mat-label" }, { type: i13.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: i14.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: i14.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i14.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i14.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i14.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i14.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i14.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i2.MatError, selector: "mat-error", inputs: ["id"] }, { type: i15.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { type: i3$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { type: i12.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i14.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i14.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i14.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.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { type: i2.MatSuffix, selector: "[matSuffix]" }, { type: i11.MatStartDate, selector: "input[matStartDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { type: i11.MatEndDate, selector: "input[matEndDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { type: i12.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: i14.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i14.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i14.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]" }] });
1015
1505
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputComponent, decorators: [{
1016
1506
  type: Component,
1017
- 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 ? metadata.required : false\"\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 ? metadata.required : false\"\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 ? metadata.required : false\"\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 ? metadata.required : false\">\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>\n <mat-checkbox [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\" [required]=\"metadata.required ? metadata.required : false\">\n {{metadata.displayName}}\n </mat-checkbox>\n <!-- hidden input is needed so that the checkbox can be used inside a mat-form-field -->\n <textarea matInput hidden></textarea>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <mat-form-field>\n <mat-slide-toggle [(ngModel)]=\"entity[propertyKey]\" [name]=\"propertyKey.toString()\" #model=\"ngModel\" [required]=\"metadata.required ? metadata.required : false\">\n {{metadata.displayName}}\n </mat-slide-toggle>\n <!-- hidden input is needed so that the toggle can be used inside a mat-form-field -->\n <textarea matInput hidden></textarea>\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 ? metadata.required : false\">\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 ? metadata.required : false\"\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 ? metadata.required : false\">\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 <div class=\"row\">\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 getObjectProperties(); 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 *ngSwitchCase=\"DecoratorTypes.ARRAY\">\n <ngx-mat-entity-array-table\n [arrayItems]=\"entityArrayValues\"\n [metadata]=\"metadataEntityArray\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [omit]=\"hideOmitForCreate ? 'create' : 'edit'\"\n >\n </ngx-mat-entity-array-table>\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 ? metadata.required : false\"\n >\n <mat-chip *ngFor=\"let value of stringChipsArrayValues\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove *ngIf=\"metadataStringChipsArray.deleteHtml\" [innerHtml]=\"metadataStringChipsArray.deleteHtml\">\n </button>\n <button matChipRemove *ngIf=\"!metadataStringChipsArray.deleteHtml\">\n <mat-icon>cancel</mat-icon>\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 ? metadata.required : false\"\n >\n <mat-chip *ngFor=\"let value of stringChipsArrayValues\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove *ngIf=\"metadataStringChipsArray.deleteHtml\" [innerHtml]=\"metadataStringChipsArray.deleteHtml\">\n </button>\n <button matChipRemove *ngIf=\"!metadataStringChipsArray.deleteHtml\">\n <mat-icon>cancel</mat-icon>\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>", styles: ["mat-form-field{width:100%}\n"] }]
1018
- }], ctorParameters: function () { return []; }, propDecorators: { entity: [{
1507
+ 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-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.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-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.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 <!-------------------------------------------->\n <!-------------------Dates-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.DATE\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"entity[propertyKey]\"\n [name]=\"propertyKey.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadataDefaultDate.min ? metadataDefaultDate.min(DateUtilities.asDate(entity[propertyKey])) : undefined\"\n [max]=\"metadataDefaultDate.max ? metadataDefaultDate.max(DateUtilities.asDate(entity[propertyKey])) : undefined\"\n [matDatepickerFilter]=\"metadataDefaultDate.filter ? metadataDefaultDate.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>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.DATE_RANGE\">\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]=\"metadataDateRangeDate.filter ? metadataDateRangeDate.filter : defaultDateFilter\">\n <input matStartDate\n [(ngModel)]=\"dateRangeStart\"\n [name]=\"propertyKey.toString() + 'start'\"\n #startModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadataDateRangeDate.minStart ? metadataDateRangeDate.minStart(dateRange.start) : undefined\"\n [max]=\"metadataDateRangeDate.maxStart ? metadataDateRangeDate.maxStart(dateRange.start) : undefined\"\n [placeholder]=\"metadataDateRangeDate.placeholderStart ? metadataDateRangeDate.placeholderStart : 'Start'\"\n (ngModelChange)=\"setDateRangeValues()\"\n >\n <input matEndDate\n [(ngModel)]=\"dateRangeEnd\"\n [name]=\"propertyKey.toString() + 'end'\"\n #endModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadataDateRangeDate.minEnd ? metadataDateRangeDate.minEnd(dateRange.end) : undefined\"\n [max]=\"metadataDateRangeDate.maxEnd ? metadataDateRangeDate.maxEnd(dateRange.end) : undefined\"\n [placeholder]=\"metadataDateRangeDate.placeholderEnd ? metadataDateRangeDate.placeholderEnd : 'End'\"\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>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.DATE_TIME\" class=\"date-time\">\n <mat-form-field appearance=\"standard\" class=\"datepicker\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"dateTime\"\n [name]=\"propertyKey.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadataDateTimeDate.minDate ? metadataDateTimeDate.minDate(dateTime) : undefined\"\n [max]=\"metadataDateTimeDate.maxDate ? metadataDateTimeDate.maxDate(dateTime) : undefined\"\n [matDatepickerFilter]=\"metadataDateTimeDate.filterDate ? metadataDateTimeDate.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>{{metadataDateTimeDate.timeDisplayName}}</mat-label>\n <mat-select\n [(ngModel)]=\"time\"\n [name]=\"propertyKey.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[propertyKey]),\n metadataDateTimeDate.times,\n metadataDateTimeDate.minTime,\n metadataDateTimeDate.maxTime,\n metadataDateTimeDate.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\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 >\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}.date-time{display:flex;align-items:baseline}.date-time .timepicker{margin-left:10px}\n"] }]
1508
+ }], ctorParameters: function () { return [{ type: i1.MatDialog }]; }, propDecorators: { entity: [{
1019
1509
  type: Input
1020
1510
  }], propertyKey: [{
1021
1511
  type: Input
@@ -1025,53 +1515,134 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
1025
1515
  type: Input
1026
1516
  }], hideOmitForEdit: [{
1027
1517
  type: Input
1518
+ }], addArrayItemDialog: [{
1519
+ type: ViewChild,
1520
+ args: ['addArrayItemDialog']
1028
1521
  }] } });
1029
1522
 
1030
- class NgxMatEntityCreateDialogComponent {
1031
- constructor(data, dialogRef, injector, dialog) {
1032
- this.data = data;
1033
- this.dialogRef = dialogRef;
1034
- this.injector = injector;
1035
- this.dialog = dialog;
1036
- this.EntityUtilities = EntityUtilities;
1037
- this.getWidth = EntityUtilities.getWidth;
1523
+ class NgxMatEntityInputModule {
1524
+ }
1525
+ NgxMatEntityInputModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1526
+ NgxMatEntityInputModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, declarations: [NgxMatEntityInputComponent], imports: [CommonModule,
1527
+ MatInputModule,
1528
+ FormsModule,
1529
+ MatFormFieldModule,
1530
+ MatSelectModule,
1531
+ MatAutocompleteModule,
1532
+ MatCheckboxModule,
1533
+ MatSlideToggleModule,
1534
+ MatChipsModule,
1535
+ MatIconModule,
1536
+ MatTableModule,
1537
+ MatDialogModule,
1538
+ MatButtonModule,
1539
+ MatDatepickerModule], exports: [NgxMatEntityInputComponent] });
1540
+ NgxMatEntityInputModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, imports: [[
1541
+ CommonModule,
1542
+ MatInputModule,
1543
+ FormsModule,
1544
+ MatFormFieldModule,
1545
+ MatSelectModule,
1546
+ MatAutocompleteModule,
1547
+ MatCheckboxModule,
1548
+ MatSlideToggleModule,
1549
+ MatChipsModule,
1550
+ MatIconModule,
1551
+ MatTableModule,
1552
+ MatDialogModule,
1553
+ MatButtonModule,
1554
+ MatDatepickerModule
1555
+ ]] });
1556
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, decorators: [{
1557
+ type: NgModule,
1558
+ args: [{
1559
+ declarations: [
1560
+ NgxMatEntityInputComponent,
1561
+ ],
1562
+ imports: [
1563
+ CommonModule,
1564
+ MatInputModule,
1565
+ FormsModule,
1566
+ MatFormFieldModule,
1567
+ MatSelectModule,
1568
+ MatAutocompleteModule,
1569
+ MatCheckboxModule,
1570
+ MatSlideToggleModule,
1571
+ MatChipsModule,
1572
+ MatIconModule,
1573
+ MatTableModule,
1574
+ MatDialogModule,
1575
+ MatButtonModule,
1576
+ MatDatepickerModule
1577
+ ],
1578
+ exports: [NgxMatEntityInputComponent]
1579
+ }]
1580
+ }] });
1581
+
1582
+ /**
1583
+ * The internal CreateEntityDialogData. Requires all default values the user can leave out.
1584
+ */
1585
+ class CreateEntityDialogDataInternal {
1586
+ constructor(entity, EntityServiceClass, createDialogData) {
1587
+ this.entity = entity;
1588
+ this.EntityServiceClass = EntityServiceClass;
1589
+ this.createDialogData = createDialogData;
1590
+ }
1591
+ }
1592
+ /**
1593
+ * The Builder for the CreateEntityDialogData. Sets default values.
1594
+ */
1595
+ class CreateEntityDialogDataBuilder extends BaseBuilder {
1596
+ constructor(data) {
1597
+ super(data);
1598
+ }
1599
+ // eslint-disable-next-line jsdoc/require-jsdoc
1600
+ generateBaseData(data) {
1601
+ const createDialogData = new CreateDialogDataBuilder(data.createDialogData).getResult();
1602
+ return new CreateEntityDialogDataInternal(data.entity, data.EntityServiceClass, createDialogData);
1603
+ }
1604
+ }
1605
+
1606
+ /**
1607
+ * The default dialog used to create new entities based on the configuration passed in the MAT_DIALOG_DATA "inputData".
1608
+ * Used by the ngx-mat-entity-table.
1609
+ *
1610
+ * It offers a lot of customization options which can be found in "CreateEntityDialogData".
1611
+ */
1612
+ class NgxMatEntityCreateDialogComponent {
1613
+ constructor(inputData, dialogRef, injector, dialog) {
1614
+ this.inputData = inputData;
1615
+ this.dialogRef = dialogRef;
1616
+ this.injector = injector;
1617
+ this.dialog = dialog;
1618
+ this.EntityUtilities = EntityUtilities;
1619
+ this.getWidth = EntityUtilities.getWidth;
1038
1620
  }
1039
1621
  ngOnInit() {
1622
+ this.data = new CreateEntityDialogDataBuilder(this.inputData).getResult();
1040
1623
  this.dialogRef.disableClose = true;
1041
- this.setEntityKeys();
1624
+ this.entityRows = EntityUtilities.getEntityRows(this.data.entity, true);
1042
1625
  this.entityService = this.injector.get(this.data.EntityServiceClass);
1043
1626
  }
1044
- setEntityKeys() {
1045
- this.entityKeys = Reflect.ownKeys(this.data.entity);
1046
- const omitCreateKeys = EntityUtilities.getOmitForCreate(this.data.entity);
1047
- this.entityKeys = this.entityKeys.filter((k) => !omitCreateKeys.includes(k))
1048
- .sort((a, b) => EntityUtilities.compareOrder(a, b, this.data.entity));
1049
- }
1627
+ /**
1628
+ * Tries add the new entity and close the dialog afterwards.
1629
+ * Also handles the confirmation if required.
1630
+ */
1050
1631
  create() {
1051
- if (this.data.createDialogData.createRequiresConfirmDialog === false) {
1632
+ if (!this.data.createDialogData?.createRequiresConfirmDialog) {
1052
1633
  return this.confirmCreate();
1053
1634
  }
1054
- const dialogData = {
1055
- // eslint-disable-next-line max-len
1056
- text: this.data.createDialogData.confirmCreateDialogData?.text ? this.data.createDialogData.confirmCreateDialogData?.text : ['Do you really want to create this entity?'],
1057
- type: 'default',
1058
- // eslint-disable-next-line max-len
1059
- confirmButtonLabel: this.data.createDialogData.confirmCreateDialogData?.confirmButtonLabel ? this.data.createDialogData.confirmCreateDialogData?.confirmButtonLabel : 'Create',
1060
- // eslint-disable-next-line max-len
1061
- cancelButtonLabel: this.data.createDialogData.confirmCreateDialogData?.cancelButtonLabel ? this.data.createDialogData.confirmCreateDialogData?.cancelButtonLabel : 'Cancel',
1062
- // eslint-disable-next-line max-len
1063
- title: this.data.createDialogData.confirmCreateDialogData?.title ? this.data.createDialogData.confirmCreateDialogData?.title : 'Create',
1064
- // eslint-disable-next-line max-len
1065
- requireConfirmation: this.data.createDialogData.confirmCreateDialogData?.requireConfirmation ? this.data.createDialogData.confirmCreateDialogData?.requireConfirmation : false,
1066
- // eslint-disable-next-line max-len
1067
- confirmationText: this.data.createDialogData.confirmCreateDialogData?.confirmationText ? this.data.createDialogData.confirmCreateDialogData?.confirmationText : undefined,
1068
- };
1069
- const dialogref = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
1635
+ const dialogData = new ConfirmDialogDataBuilder(this.data.createDialogData?.confirmCreateDialogData)
1636
+ .withDefault('text', ['Do you really want to create this entity?'])
1637
+ .withDefault('confirmButtonLabel', 'Create')
1638
+ .withDefault('title', 'Create')
1639
+ .getResult();
1640
+ const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
1070
1641
  data: dialogData,
1071
1642
  autoFocus: false,
1072
1643
  restoreFocus: false
1073
1644
  });
1074
- dialogref.afterClosed().subscribe((res) => {
1645
+ dialogRef.afterClosed().subscribe((res) => {
1075
1646
  if (res === 1) {
1076
1647
  this.confirmCreate();
1077
1648
  }
@@ -1080,23 +1651,96 @@ class NgxMatEntityCreateDialogComponent {
1080
1651
  confirmCreate() {
1081
1652
  this.entityService.create(this.data.entity).then(() => this.dialogRef.close());
1082
1653
  }
1654
+ /**
1655
+ * Closes the dialog.
1656
+ */
1083
1657
  cancel() {
1084
1658
  this.dialogRef.close();
1085
1659
  }
1086
1660
  }
1087
1661
  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 });
1088
- 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\" class=\"row\">\n <ngx-mat-entity-input\n *ngFor=\"let key of entityKeys\"\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 </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 ? data.createDialogData.createButtonLabel : 'Create'}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.createDialogData.cancelButtonLabel ? data.createDialogData.cancelButtonLabel : 'Cancel'}}\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: i12.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i12.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i12.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
1662
+ 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: i14.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i14.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i14.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i12.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
1089
1663
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityCreateDialogComponent, decorators: [{
1090
1664
  type: Component,
1091
- 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\" class=\"row\">\n <ngx-mat-entity-input\n *ngFor=\"let key of entityKeys\"\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 </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 ? data.createDialogData.createButtonLabel : 'Create'}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.createDialogData.cancelButtonLabel ? data.createDialogData.cancelButtonLabel : 'Cancel'}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}\n"] }]
1665
+ 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"] }]
1092
1666
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1093
1667
  type: Inject,
1094
1668
  args: [MAT_DIALOG_DATA]
1095
1669
  }] }, { type: i1.MatDialogRef }, { type: i0.Injector }, { type: i1.MatDialog }]; } });
1096
1670
 
1671
+ /**
1672
+ * The internal EditDialogData. Requires all default values the user can leave out.
1673
+ */
1674
+ class EditDialogDataInternal {
1675
+ constructor(title, confirmButtonLabel, deleteButtonLabel, cancelButtonLabel, deleteRequiresConfirmDialog, editRequiresConfirmDialog, confirmDeleteDialogData, confirmEditDialogData) {
1676
+ this.title = title;
1677
+ this.confirmButtonLabel = confirmButtonLabel;
1678
+ this.deleteButtonLabel = deleteButtonLabel;
1679
+ this.cancelButtonLabel = cancelButtonLabel;
1680
+ this.deleteRequiresConfirmDialog = deleteRequiresConfirmDialog;
1681
+ this.editRequiresConfirmDialog = editRequiresConfirmDialog;
1682
+ this.confirmDeleteDialogData = confirmDeleteDialogData;
1683
+ this.confirmEditDialogData = confirmEditDialogData;
1684
+ }
1685
+ }
1686
+ /**
1687
+ * The Builder for the EditDialogData. Sets default values.
1688
+ */
1689
+ class EditDialogDataBuilder extends BaseBuilder {
1690
+ constructor(data) {
1691
+ super(data);
1692
+ }
1693
+ // eslint-disable-next-line jsdoc/require-jsdoc
1694
+ generateBaseData(data) {
1695
+ const confirmEditDialogData = new ConfirmDialogDataBuilder(data?.confirmEditDialogData)
1696
+ .withDefault('confirmButtonLabel', 'Save')
1697
+ .withDefault('text', ['Do you really want to save all changes?'])
1698
+ .withDefault('title', 'Edit')
1699
+ .getResult();
1700
+ const confirmDeleteDialogData = new ConfirmDialogDataBuilder(data?.confirmDeleteDialogData)
1701
+ .withDefault('confirmButtonLabel', 'Delete')
1702
+ .withDefault('type', 'delete')
1703
+ .withDefault('text', ['Do you really want to delete this entity?'])
1704
+ .withDefault('title', 'Delete')
1705
+ .getResult();
1706
+ return new EditDialogDataInternal(data?.title ? data.title : () => 'Edit', data?.confirmButtonLabel ? data.confirmButtonLabel : 'Save', data?.deleteButtonLabel ? data.deleteButtonLabel : 'Delete', data?.cancelButtonLabel ? data.cancelButtonLabel : 'Cancel', data?.deleteRequiresConfirmDialog ? data.deleteRequiresConfirmDialog : true, data?.editRequiresConfirmDialog ? data.editRequiresConfirmDialog : false, confirmDeleteDialogData, confirmEditDialogData);
1707
+ }
1708
+ }
1709
+
1710
+ /**
1711
+ * The internal EditEntityDialogData. Requires all default values the user can leave out.
1712
+ */
1713
+ class EditEntityDialogDataInternal {
1714
+ constructor(entity, EntityServiceClass, editDialogData, allowDelete) {
1715
+ this.entity = entity;
1716
+ this.EntityServiceClass = EntityServiceClass;
1717
+ this.editDialogData = editDialogData;
1718
+ this.allowDelete = allowDelete;
1719
+ }
1720
+ }
1721
+ /**
1722
+ * The Builder for the EditEntityDialogData. Sets default values.
1723
+ */
1724
+ class EditEntityDialogDataBuilder extends BaseBuilder {
1725
+ constructor(data) {
1726
+ super(data);
1727
+ }
1728
+ // eslint-disable-next-line jsdoc/require-jsdoc
1729
+ generateBaseData(data) {
1730
+ const editDialogData = new EditDialogDataBuilder(data.editDialogData).getResult();
1731
+ return new EditEntityDialogDataInternal(data.entity, data.EntityServiceClass, editDialogData, data.allowDelete ? data.allowDelete : () => true);
1732
+ }
1733
+ }
1734
+
1735
+ /**
1736
+ * The default dialog used to edit an existing entity based on the configuration passed in the MAT_DIALOG_DATA "inputData".
1737
+ * Used by the ngx-mat-entity-table.
1738
+ *
1739
+ * It offers a lot of customization options which can be found in "EditEntityDialogData".
1740
+ */
1097
1741
  class NgxMatEntityEditDialogComponent {
1098
- constructor(data, dialogRef, injector, dialog) {
1099
- this.data = data;
1742
+ constructor(inputData, dialogRef, injector, dialog) {
1743
+ this.inputData = inputData;
1100
1744
  this.dialogRef = dialogRef;
1101
1745
  this.injector = injector;
1102
1746
  this.dialog = dialog;
@@ -1104,41 +1748,31 @@ class NgxMatEntityEditDialogComponent {
1104
1748
  this.getWidth = EntityUtilities.getWidth;
1105
1749
  }
1106
1750
  ngOnInit() {
1751
+ this.data = new EditEntityDialogDataBuilder(this.inputData).getResult();
1107
1752
  this.dialogRef.disableClose = true;
1108
- this.setEntityKeys();
1753
+ this.entityRows = EntityUtilities.getEntityRows(this.data.entity, false, true);
1109
1754
  this.entityService = this.injector.get(this.data.EntityServiceClass);
1110
1755
  this.entityPriorChanges = cloneDeep(this.data.entity);
1111
1756
  }
1112
- setEntityKeys() {
1113
- this.entityKeys = Reflect.ownKeys(this.data.entity);
1114
- const omitUpdateKeys = EntityUtilities.getOmitForUpdate(this.data.entity);
1115
- this.entityKeys = this.entityKeys.filter((k) => !omitUpdateKeys.includes(k))
1116
- .sort((a, b) => EntityUtilities.compareOrder(a, b, this.data.entity));
1117
- }
1757
+ /**
1758
+ * Tries to save the changes and close the dialog afterwards.
1759
+ * Also handles the confirmation if required.
1760
+ */
1118
1761
  edit() {
1119
- if (this.data.editDialogData.editRequiresConfirmDialog === false) {
1762
+ if (!this.data.editDialogData.editRequiresConfirmDialog) {
1120
1763
  return this.confirmEdit();
1121
1764
  }
1122
- const dialogData = {
1123
- // eslint-disable-next-line max-len
1124
- text: this.data.editDialogData.confirmEditDialogData?.text ? this.data.editDialogData.confirmEditDialogData?.text : ['Do you really want to save all changes?'],
1125
- type: 'default',
1126
- // eslint-disable-next-line max-len
1127
- confirmButtonLabel: this.data.editDialogData.confirmEditDialogData?.confirmButtonLabel ? this.data.editDialogData.confirmEditDialogData?.confirmButtonLabel : 'Confirm',
1128
- // eslint-disable-next-line max-len
1129
- cancelButtonLabel: this.data.editDialogData.confirmEditDialogData?.cancelButtonLabel ? this.data.editDialogData.confirmEditDialogData?.cancelButtonLabel : 'Cancel',
1130
- title: this.data.editDialogData.confirmEditDialogData?.title ? this.data.editDialogData.confirmEditDialogData?.title : 'Edit',
1131
- // eslint-disable-next-line max-len
1132
- requireConfirmation: this.data.editDialogData.confirmEditDialogData?.requireConfirmation ? this.data.editDialogData.confirmEditDialogData?.requireConfirmation : false,
1133
- // eslint-disable-next-line max-len
1134
- confirmationText: this.data.editDialogData.confirmEditDialogData?.confirmationText ? this.data.editDialogData.confirmEditDialogData?.confirmationText : undefined,
1135
- };
1136
- const dialogref = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
1765
+ const dialogData = new ConfirmDialogDataBuilder(this.data.editDialogData.confirmEditDialogData)
1766
+ .withDefault('text', ['Do you really want to save all changes?'])
1767
+ .withDefault('confirmButtonLabel', 'Save')
1768
+ .withDefault('title', 'Edit')
1769
+ .getResult();
1770
+ const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
1137
1771
  data: dialogData,
1138
1772
  autoFocus: false,
1139
1773
  restoreFocus: false
1140
1774
  });
1141
- dialogref.afterClosed().subscribe((res) => {
1775
+ dialogRef.afterClosed().subscribe((res) => {
1142
1776
  if (res === 1) {
1143
1777
  this.confirmEdit();
1144
1778
  }
@@ -1147,54 +1781,160 @@ class NgxMatEntityEditDialogComponent {
1147
1781
  confirmEdit() {
1148
1782
  this.entityService.update(this.data.entity, this.entityPriorChanges).then(() => this.dialogRef.close(1));
1149
1783
  }
1784
+ /**
1785
+ * Tries to delete the entity and close the dialog afterwards.
1786
+ * Also handles the confirmation if required.
1787
+ */
1150
1788
  delete() {
1151
- if (this.data.editDialogData.deleteRequiresConfirmDialog === false) {
1789
+ if (!this.data.editDialogData.deleteRequiresConfirmDialog) {
1152
1790
  return this.confirmDelete();
1153
1791
  }
1154
- const dialogData = {
1155
- // eslint-disable-next-line max-len
1156
- text: this.data.editDialogData.confirmDeleteDialogData?.text ? this.data.editDialogData.confirmDeleteDialogData?.text : ['Do you really want to delete this entity?'],
1157
- type: 'delete',
1158
- // eslint-disable-next-line max-len
1159
- confirmButtonLabel: this.data.editDialogData.confirmDeleteDialogData?.confirmButtonLabel ? this.data.editDialogData.confirmDeleteDialogData?.confirmButtonLabel : 'Delete',
1160
- // eslint-disable-next-line max-len
1161
- cancelButtonLabel: this.data.editDialogData.confirmDeleteDialogData?.cancelButtonLabel ? this.data.editDialogData.confirmDeleteDialogData?.cancelButtonLabel : 'Cancel',
1162
- // eslint-disable-next-line max-len
1163
- title: this.data.editDialogData.confirmDeleteDialogData?.title ? this.data.editDialogData.confirmDeleteDialogData?.title : 'Delete',
1164
- // eslint-disable-next-line max-len
1165
- requireConfirmation: this.data.editDialogData.confirmDeleteDialogData?.requireConfirmation ? this.data.editDialogData.confirmDeleteDialogData?.requireConfirmation : false,
1166
- // eslint-disable-next-line max-len
1167
- confirmationText: this.data.editDialogData.confirmDeleteDialogData?.confirmationText ? this.data.editDialogData.confirmDeleteDialogData?.confirmationText : undefined,
1168
- };
1169
- const dialogref = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
1792
+ const dialogData = new ConfirmDialogDataBuilder(this.data.editDialogData.confirmDeleteDialogData)
1793
+ .withDefault('text', ['Do you really want to delete this entity?'])
1794
+ .withDefault('type', 'delete')
1795
+ .withDefault('confirmButtonLabel', 'Delete')
1796
+ .withDefault('title', 'Delete')
1797
+ .getResult();
1798
+ const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
1170
1799
  data: dialogData,
1171
1800
  autoFocus: false,
1172
1801
  restoreFocus: false
1173
1802
  });
1174
- dialogref.afterClosed().subscribe((res) => {
1803
+ dialogRef.afterClosed().subscribe((res) => {
1175
1804
  if (res === 1) {
1176
1805
  this.confirmDelete();
1177
1806
  }
1178
1807
  });
1179
1808
  }
1180
1809
  confirmDelete() {
1181
- this.entityService.delete(this.entityPriorChanges.id).then(() => this.dialogRef.close(2));
1810
+ this.entityService.delete(this.entityPriorChanges).then(() => this.dialogRef.close(2));
1182
1811
  }
1812
+ /**
1813
+ * Reverts all changes made and closes the dialog.
1814
+ */
1183
1815
  cancel() {
1184
1816
  EntityUtilities.resetChangesOnEntity(this.data.entity, this.entityPriorChanges);
1185
1817
  this.dialogRef.close(0);
1186
1818
  }
1187
1819
  }
1188
1820
  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 });
1189
- 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 ? data.editDialogData.deleteButtonLabel : 'Delete'}}\n </button>\n</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <ngx-mat-entity-input\n *ngFor=\"let key of entityKeys\"\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 </form>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"edit()\" [disabled]=\"!EntityUtilities.isEntityValid(data.entity, 'edit') || !EntityUtilities.dirty(data.entity, entityPriorChanges)\">\n {{data.editDialogData.confirmButtonLabel ? data.editDialogData.confirmButtonLabel : 'Save'}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.editDialogData.cancelButtonLabel ? data.editDialogData.cancelButtonLabel : 'Cancel'}}\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: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i12.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i12.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i12.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
1821
+ 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: i12.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i14.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i14.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i14.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i12.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
1190
1822
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityEditDialogComponent, decorators: [{
1191
1823
  type: Component,
1192
- 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 ? data.editDialogData.deleteButtonLabel : 'Delete'}}\n </button>\n</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <ngx-mat-entity-input\n *ngFor=\"let key of entityKeys\"\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 </form>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"edit()\" [disabled]=\"!EntityUtilities.isEntityValid(data.entity, 'edit') || !EntityUtilities.dirty(data.entity, entityPriorChanges)\">\n {{data.editDialogData.confirmButtonLabel ? data.editDialogData.confirmButtonLabel : 'Save'}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.editDialogData.cancelButtonLabel ? data.editDialogData.cancelButtonLabel : 'Cancel'}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}.delete-button{float:right}\n"] }]
1824
+ 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"] }]
1193
1825
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1194
1826
  type: Inject,
1195
1827
  args: [MAT_DIALOG_DATA]
1196
1828
  }] }, { type: i1.MatDialogRef }, { type: i0.Injector }, { type: i1.MatDialog }]; } });
1197
1829
 
1830
+ /**
1831
+ * The internal TableData. Requires all default values the user can leave out.
1832
+ */
1833
+ class TableDataInternal {
1834
+ constructor(baseData, createDialogData, editDialogData) {
1835
+ this.baseData = baseData;
1836
+ this.createDialogData = createDialogData;
1837
+ this.editDialogData = editDialogData;
1838
+ }
1839
+ }
1840
+ /**
1841
+ * The Builder for the table BaseData. Sets default values.
1842
+ */
1843
+ class BaseDataBuilder extends BaseBuilder {
1844
+ constructor(data) {
1845
+ super(data);
1846
+ }
1847
+ // eslint-disable-next-line jsdoc/require-jsdoc
1848
+ generateBaseData(data) {
1849
+ 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);
1850
+ }
1851
+ }
1852
+ /**
1853
+ * The internal TableData. Requires all default values the user can leave out.
1854
+ */
1855
+ class BaseDataInternal {
1856
+ constructor(title, displayColumns, EntityServiceClass, searchLabel, createButtonLabel, searchString, allowCreate, allowEdit, allowDelete, multiSelectActions, multiSelectLabel, EntityClass, edit, create) {
1857
+ this.title = title;
1858
+ this.displayColumns = displayColumns;
1859
+ this.EntityServiceClass = EntityServiceClass;
1860
+ this.EntityClass = EntityClass;
1861
+ this.searchLabel = searchLabel;
1862
+ this.createButtonLabel = createButtonLabel;
1863
+ this.searchString = searchString;
1864
+ this.allowCreate = allowCreate;
1865
+ this.allowEdit = allowEdit;
1866
+ this.allowDelete = allowDelete;
1867
+ this.multiSelectActions = multiSelectActions;
1868
+ this.multiSelectLabel = multiSelectLabel;
1869
+ this.edit = edit;
1870
+ this.create = create;
1871
+ }
1872
+ }
1873
+ /**
1874
+ * The Builder for the complete TableData. Sets default values and validates user input.
1875
+ */
1876
+ class TableDataBuilder extends BaseBuilder {
1877
+ constructor(data) {
1878
+ super(data);
1879
+ }
1880
+ // eslint-disable-next-line jsdoc/require-jsdoc
1881
+ generateBaseData(data) {
1882
+ const createDialogData = new CreateDialogDataBuilder(data.createDialogData).getResult();
1883
+ const editDialogData = new EditDialogDataBuilder(data.editDialogData).getResult();
1884
+ const baseData = new BaseDataBuilder(data.baseData).getResult();
1885
+ return new TableDataInternal(baseData, createDialogData, editDialogData);
1886
+ }
1887
+ // eslint-disable-next-line jsdoc/require-jsdoc
1888
+ validateInput(data) {
1889
+ if (data.baseData.multiSelectActions?.length && data.baseData.displayColumns.find(dp => dp.displayName === 'select')) {
1890
+ throw new Error(`The name "select" for a display column is reserved for the multi-select action functionality.
1891
+ Please choose a different name.`);
1892
+ }
1893
+ if ((data.baseData.allowEdit && data.baseData.allowEdit !== (() => false)
1894
+ || data.baseData.allowDelete && data.baseData.allowDelete !== (() => false)
1895
+ || data.baseData.allowCreate)
1896
+ && !data.baseData.EntityClass) {
1897
+ throw new Error(`
1898
+ Missing required Input data "EntityClass".
1899
+ You can only omit this value if you can neither create or update entities.`);
1900
+ }
1901
+ if (data.baseData.allowCreate !== false && !data.baseData.create && !data.createDialogData) {
1902
+ throw new Error(`Missing required Input data "createDialogData".
1903
+ You can only omit this value when creation is disallowed or done with a custom create method.`);
1904
+ }
1905
+ if ((data.baseData.allowEdit !== (() => false)
1906
+ || data.baseData.allowDelete !== (() => false))
1907
+ && !data.baseData.edit
1908
+ && !data.editDialogData) {
1909
+ throw new Error(`Missing required Input data "editDialogData".
1910
+ You can only omit this value when editing and deleting is disallowed or done with a custom edit method.`);
1911
+ }
1912
+ }
1913
+ }
1914
+ /**
1915
+ * The default search function taken from googles mat table.
1916
+ * This will be used if no custom search function is provided by the configuration.
1917
+ *
1918
+ * It generates a string from an entity which is then used to compare it to the search input.
1919
+ *
1920
+ * @param entity - An entity that is in the search.
1921
+ * @returns The generated string of the given entity used for comparison with the search input.
1922
+ */
1923
+ function defaultSearchFunction(entity) {
1924
+ const searchString = Object.keys(entity)
1925
+ .reduce((currentTerm, key) => {
1926
+ return `${currentTerm}${entity[key]}◬`;
1927
+ }, '')
1928
+ .toLowerCase();
1929
+ return searchString;
1930
+ }
1931
+
1932
+ /**
1933
+ * Generates a fully functional table for displaying, creating, updating and deleting entities
1934
+ * based on the configuration passed in the @Input "tableData".
1935
+ *
1936
+ * It offers a lot of customization options which can be found in "TableData".
1937
+ */
1198
1938
  class NgxMatEntityTableComponent {
1199
1939
  constructor(dialog, injector) {
1200
1940
  this.dialog = dialog;
@@ -1203,27 +1943,26 @@ class NgxMatEntityTableComponent {
1203
1943
  this.dataSource = new MatTableDataSource();
1204
1944
  this.selection = new SelectionModel(true, []);
1205
1945
  }
1946
+ /**
1947
+ * Sets up all the configuration for the table and the EntityService.
1948
+ */
1206
1949
  ngOnInit() {
1207
- this.validateInput();
1208
- this.entityService = this.injector.get(this.entitiesData.baseData.EntityServiceClass);
1209
- const givenDisplayColumns = this.entitiesData.baseData.displayColumns.map((v) => v.displayName);
1210
- if (this.entitiesData.baseData.multiSelectActions?.length) {
1211
- if (givenDisplayColumns.find((s) => s === 'select')) {
1212
- throw new Error(`The name "select" for a display column is reserved for the multi-select action functionality.
1213
- Please choose a different name.`);
1214
- }
1950
+ this.data = new TableDataBuilder(this.tableData).getResult();
1951
+ this.entityService = this.injector.get(this.data.baseData.EntityServiceClass);
1952
+ const givenDisplayColumns = this.data.baseData.displayColumns.map((v) => v.displayName);
1953
+ if (this.data.baseData.multiSelectActions.length) {
1215
1954
  this.displayedColumns = ['select'].concat(givenDisplayColumns);
1216
1955
  }
1217
1956
  else {
1218
1957
  this.displayedColumns = givenDisplayColumns;
1219
1958
  }
1220
1959
  this.dataSource.sortingDataAccessor = (entity, header) => {
1221
- return this.entitiesData.baseData.displayColumns.find((dp) => dp.displayName === header)?.value(entity);
1960
+ return this.data.baseData.displayColumns.find((dp) => dp.displayName === header)?.value(entity);
1222
1961
  };
1223
1962
  this.dataSource.sort = this.sort;
1224
- if (this.entitiesData.baseData.searchString) {
1963
+ if (this.data.baseData.searchString) {
1225
1964
  this.dataSource.filterPredicate = (entity, filter) => {
1226
- const searchStr = this.entitiesData.baseData.searchString?.(entity);
1965
+ const searchStr = this.data.baseData.searchString(entity);
1227
1966
  const formattedSearchString = searchStr.toLowerCase();
1228
1967
  const formattedFilterString = filter.toLowerCase();
1229
1968
  return formattedSearchString.includes(formattedFilterString);
@@ -1237,62 +1976,33 @@ class NgxMatEntityTableComponent {
1237
1976
  });
1238
1977
  this.entityService.read();
1239
1978
  }
1240
- validateInput() {
1241
- if (!this.entitiesData.baseData.displayColumns) {
1242
- throw new Error('Missing required Input data "displayColumns"');
1243
- }
1244
- if (!this.entitiesData.baseData.title) {
1245
- throw new Error('Missing required Input data "title"');
1246
- }
1247
- if (!this.entitiesData.baseData.EntityServiceClass) {
1248
- throw new Error('Missing required Input data "EntityServiceClass"');
1249
- }
1250
- if (this.entitiesData.baseData.allowCreate === undefined) {
1251
- this.entitiesData.baseData.allowCreate = true;
1252
- }
1253
- if (this.entitiesData.baseData.allowEdit === undefined) {
1254
- this.entitiesData.baseData.allowEdit = () => true;
1255
- }
1256
- if (this.entitiesData.baseData.allowDelete === undefined) {
1257
- this.entitiesData.baseData.allowDelete = () => true;
1258
- }
1259
- if ((this.entitiesData.baseData.allowEdit !== (() => false)
1260
- || this.entitiesData.baseData.allowDelete !== (() => false)
1261
- || this.entitiesData.baseData.allowCreate)
1262
- && !this.entitiesData.baseData.EntityClass) {
1263
- throw new Error(`
1264
- Missing required Input data "EntityClass".
1265
- You can only omit this value if you can neither create or update entities.`);
1266
- }
1267
- if (this.entitiesData.baseData.allowCreate && !this.entitiesData.baseData.create && !this.entitiesData.createDialogData) {
1268
- throw new Error(`Missing required Input data "createDialogData".
1269
- You can only omit this value when creation is disallowed or done with a custom create method.`);
1270
- }
1271
- if ((this.entitiesData.baseData.allowEdit !== (() => false)
1272
- || this.entitiesData.baseData.allowDelete !== (() => false))
1273
- && !this.entitiesData.baseData.edit
1274
- && !this.entitiesData.editDialogData) {
1275
- throw new Error(`Missing required Input data "editDialogData".
1276
- You can only omit this value when editing and deleting is disallowed or done with a custom edit method.`);
1277
- }
1278
- }
1979
+ /**
1980
+ * Edits an entity. This either calls the edit-Method provided by the user or uses a default edit-dialog.
1981
+ *
1982
+ * @param entity - The entity that should be updated.
1983
+ * @throws When no EntityClass was provided, as a new call is needed to initialize metadata.
1984
+ */
1279
1985
  editEntity(entity) {
1280
- if (this.entitiesData.baseData.allowEdit?.(entity)) {
1281
- if (this.entitiesData.baseData.edit) {
1282
- this.entitiesData.baseData.edit(new this.entitiesData.baseData.EntityClass(entity));
1986
+ if (this.data.baseData.allowEdit(entity)) {
1987
+ if (!this.data.baseData.EntityClass) {
1988
+ throw new Error('No "EntityClass" specified for this table');
1989
+ }
1990
+ if (this.data.baseData.edit) {
1991
+ this.data.baseData.edit(new this.data.baseData.EntityClass(entity));
1283
1992
  }
1284
1993
  else {
1285
- this.editDefault(new this.entitiesData.baseData.EntityClass(entity));
1994
+ this.editDefault(new this.data.baseData.EntityClass(entity));
1286
1995
  }
1287
1996
  }
1288
1997
  }
1289
1998
  editDefault(entity) {
1290
- const dialogData = {
1999
+ const inputDialogData = {
1291
2000
  entity: entity,
1292
- EntityServiceClass: this.entitiesData.baseData.EntityServiceClass,
1293
- allowDelete: this.entitiesData.baseData.allowDelete,
1294
- editDialogData: this.entitiesData.editDialogData
2001
+ EntityServiceClass: this.data.baseData.EntityServiceClass,
2002
+ allowDelete: this.data.baseData.allowDelete,
2003
+ editDialogData: this.data.editDialogData
1295
2004
  };
2005
+ const dialogData = new EditEntityDialogDataBuilder(inputDialogData).getResult();
1296
2006
  firstValueFrom(this.dialog.open(NgxMatEntityEditDialogComponent, {
1297
2007
  data: dialogData,
1298
2008
  minWidth: '60%',
@@ -1301,28 +2011,36 @@ class NgxMatEntityTableComponent {
1301
2011
  }).afterClosed()).then((res) => {
1302
2012
  if (res === 0) {
1303
2013
  const data = this.dataSource.data;
1304
- data[this.dataSource.data.findIndex((e) => e.id === entity.id)] = entity;
2014
+ data[this.dataSource.data.findIndex((e) => e[this.entityService.idKey] === entity[this.entityService.idKey])] = entity;
1305
2015
  this.dataSource.data = data;
1306
2016
  this.selection.clear();
1307
2017
  }
1308
2018
  });
1309
2019
  }
2020
+ /**
2021
+ * Creates a new Entity. This either calls the create-Method provided by the user or uses a default create-dialog.
2022
+ *
2023
+ * @throws When no EntityClass was provided, as a new call is needed to initialize metadata.
2024
+ */
1310
2025
  createEntity() {
1311
- if (this.entitiesData.baseData.allowCreate) {
1312
- if (this.entitiesData.baseData.create) {
1313
- this.entitiesData.baseData.create(new this.entitiesData.baseData.EntityClass());
2026
+ if (this.data.baseData.allowCreate) {
2027
+ if (!this.data.baseData.EntityClass) {
2028
+ throw new Error('No "EntityClass" specified for this table');
2029
+ }
2030
+ if (this.data.baseData.create) {
2031
+ this.data.baseData.create(new this.data.baseData.EntityClass());
1314
2032
  }
1315
2033
  else {
1316
- this.createDefault(new this.entitiesData.baseData.EntityClass());
2034
+ this.createDefault(new this.data.baseData.EntityClass());
1317
2035
  }
1318
2036
  }
1319
2037
  }
1320
2038
  createDefault(entity) {
1321
- const dialogData = {
2039
+ const dialogData = new CreateEntityDialogDataBuilder({
1322
2040
  entity: entity,
1323
- EntityServiceClass: this.entitiesData.baseData.EntityServiceClass,
1324
- createDialogData: this.entitiesData.createDialogData
1325
- };
2041
+ EntityServiceClass: this.data.baseData.EntityServiceClass,
2042
+ createDialogData: this.data.createDialogData
2043
+ }).getResult();
1326
2044
  this.dialog.open(NgxMatEntityCreateDialogComponent, {
1327
2045
  data: dialogData,
1328
2046
  minWidth: '60%',
@@ -1330,26 +2048,26 @@ class NgxMatEntityTableComponent {
1330
2048
  restoreFocus: false
1331
2049
  });
1332
2050
  }
2051
+ /**
2052
+ * Runs the MultiAction for all selected entries.
2053
+ * Also handles confirmation with an additional dialog if configured.
2054
+ *
2055
+ * @param action - The MultiAction to run.
2056
+ */
1333
2057
  runMultiAction(action) {
1334
2058
  if (!action.requireConfirmDialog || !action.requireConfirmDialog(this.selection.selected)) {
1335
2059
  return this.confirmRunMultiAction(action);
1336
2060
  }
1337
- const dialogData = {
1338
- // eslint-disable-next-line max-len
1339
- text: action.confirmDialogData?.text ? action.confirmDialogData?.text : [`Do you really want to run this action on ${this.selection.selected.length} entries?`],
1340
- type: 'default',
1341
- confirmButtonLabel: action.confirmDialogData?.confirmButtonLabel ? action.confirmDialogData?.confirmButtonLabel : 'Confirm',
1342
- cancelButtonLabel: action.confirmDialogData?.cancelButtonLabel ? action.confirmDialogData?.cancelButtonLabel : 'Cancel',
1343
- title: action.confirmDialogData?.title ? action.confirmDialogData?.title : action.displayName,
1344
- requireConfirmation: action.confirmDialogData?.requireConfirmation ? action.confirmDialogData?.requireConfirmation : false,
1345
- confirmationText: action.confirmDialogData?.confirmationText ? action.confirmDialogData?.confirmationText : undefined
1346
- };
1347
- const dialogref = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
2061
+ const dialogData = new ConfirmDialogDataBuilder(action.confirmDialogData)
2062
+ .withDefault('text', [`Do you really want to run this action on ${this.selection.selected.length} entries?`])
2063
+ .withDefault('title', action.displayName)
2064
+ .getResult();
2065
+ const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
1348
2066
  data: dialogData,
1349
2067
  autoFocus: false,
1350
2068
  restoreFocus: false
1351
2069
  });
1352
- dialogref.afterClosed().subscribe((res) => {
2070
+ dialogRef.afterClosed().subscribe((res) => {
1353
2071
  if (res === 1) {
1354
2072
  this.confirmRunMultiAction(action);
1355
2073
  }
@@ -1358,6 +2076,12 @@ class NgxMatEntityTableComponent {
1358
2076
  confirmRunMultiAction(action) {
1359
2077
  action.action(this.selection.selected);
1360
2078
  }
2079
+ /**
2080
+ * Checks if an MultiAction is disabled (e.g. Because no entries have been selected).
2081
+ *
2082
+ * @param action - The MultiAction to check.
2083
+ * @returns Whether or not the Action can be used.
2084
+ */
1361
2085
  multiActionDisabled(action) {
1362
2086
  if (!this.selection.selected.length) {
1363
2087
  return true;
@@ -1367,6 +2091,9 @@ class NgxMatEntityTableComponent {
1367
2091
  }
1368
2092
  return false;
1369
2093
  }
2094
+ /**
2095
+ * Toggles all entries in the table.
2096
+ */
1370
2097
  masterToggle() {
1371
2098
  if (this.isAllSelected()) {
1372
2099
  this.selection.clear();
@@ -1375,6 +2102,12 @@ class NgxMatEntityTableComponent {
1375
2102
  this.dataSource.data.forEach((row) => this.selection.select(row));
1376
2103
  }
1377
2104
  }
2105
+ /**
2106
+ * Checks if all entries in the table have been selected.
2107
+ * This is needed to display the "masterToggle"-checkbox correctly.
2108
+ *
2109
+ * @returns Whether or not all entries in the table have been selected.
2110
+ */
1378
2111
  isAllSelected() {
1379
2112
  const numSelected = this.selection.selected.length;
1380
2113
  const numRows = this.dataSource.data.length;
@@ -1384,17 +2117,22 @@ class NgxMatEntityTableComponent {
1384
2117
  this.onDestroy.next(undefined);
1385
2118
  this.onDestroy.complete();
1386
2119
  }
2120
+ /**
2121
+ * Applies the search input to filter the table entries.
2122
+ *
2123
+ * @param event - The keyup-event which contains the search-string of the user.
2124
+ */
1387
2125
  applyFilter(event) {
1388
2126
  const filterValue = event.target.value;
1389
2127
  this.dataSource.filter = filterValue.trim().toLowerCase();
1390
2128
  }
1391
2129
  }
1392
2130
  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 });
1393
- NgxMatEntityTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityTableComponent, selector: "ngx-mat-entity-table", inputs: { entitiesData: "entitiesData" }, 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\">{{entitiesData.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>{{entitiesData.baseData.searchLabel ? entitiesData.baseData.searchLabel : 'Search'}}</mat-label>\n <input matInput (keyup)=\"applyFilter($event)\" />\n </mat-form-field>\n <div\n *ngIf=\"entitiesData.baseData.multiSelectActions?.length\"\n [class.col-lg-2]=\"entitiesData.baseData.allowCreate\"\n [class.col-lg-4]=\"!entitiesData.baseData.allowCreate\"\n [class.col-md-3]=\"entitiesData.baseData.allowCreate\"\n [class.col-md-6]=\"!entitiesData.baseData.allowCreate\"\n [class.col-sm-6]=\"entitiesData.baseData.allowCreate\"\n [class.col-sm-12]=\"!entitiesData.baseData.allowCreate\"\n >\n <button class=\"actions-button\" [matMenuTriggerFor]=\"menu\" mat-raised-button>\n {{entitiesData.baseData.multiSelectLabel ? entitiesData.baseData.multiSelectLabel : 'Actions'}}\n </button>\n </div>\n <mat-menu #menu=\"matMenu\">\n <button *ngFor=\"let action of entitiesData.baseData.multiSelectActions\" [disabled]=\"multiActionDisabled(action)\" (click)=\"runMultiAction(action)\" mat-menu-item>\n {{action.displayName}}\n </button>\n </mat-menu>\n\n <div\n *ngIf=\"entitiesData.baseData.allowCreate\"\n [class.col-lg-2]=\"entitiesData.baseData.multiSelectActions?.length\"\n [class.col-lg-4]=\"!entitiesData.baseData.multiSelectActions?.length\"\n [class.col-md-3]=\"entitiesData.baseData.multiSelectActions?.length\"\n [class.col-md-6]=\"!entitiesData.baseData.multiSelectActions?.length\"\n [class.col-sm-6]=\"entitiesData.baseData.multiSelectActions?.length\"\n [class.col-sm-12]=\"!entitiesData.baseData.multiSelectActions?.length\"\n >\n <button class=\"create-button\" (click)=\"createEntity()\" mat-raised-button>\n {{entitiesData.baseData.createButtonLabel ? entitiesData.baseData.createButtonLabel : 'Create'}}\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 entitiesData.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]=\"entitiesData.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{margin-bottom:15px}}@media (max-width: 575px){.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$2.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: i4$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i5.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$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i4$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { type: i7$1.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i8.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: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i4$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i4$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i4$1.MatCellDef, selector: "[matCellDef]" }, { type: i4$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i4$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i4$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }] });
2131
+ 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: i13.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: i12.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i12.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"] }] });
1394
2132
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityTableComponent, decorators: [{
1395
2133
  type: Component,
1396
- args: [{ selector: 'ngx-mat-entity-table', template: "<h1 class=\"title\">{{entitiesData.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>{{entitiesData.baseData.searchLabel ? entitiesData.baseData.searchLabel : 'Search'}}</mat-label>\n <input matInput (keyup)=\"applyFilter($event)\" />\n </mat-form-field>\n <div\n *ngIf=\"entitiesData.baseData.multiSelectActions?.length\"\n [class.col-lg-2]=\"entitiesData.baseData.allowCreate\"\n [class.col-lg-4]=\"!entitiesData.baseData.allowCreate\"\n [class.col-md-3]=\"entitiesData.baseData.allowCreate\"\n [class.col-md-6]=\"!entitiesData.baseData.allowCreate\"\n [class.col-sm-6]=\"entitiesData.baseData.allowCreate\"\n [class.col-sm-12]=\"!entitiesData.baseData.allowCreate\"\n >\n <button class=\"actions-button\" [matMenuTriggerFor]=\"menu\" mat-raised-button>\n {{entitiesData.baseData.multiSelectLabel ? entitiesData.baseData.multiSelectLabel : 'Actions'}}\n </button>\n </div>\n <mat-menu #menu=\"matMenu\">\n <button *ngFor=\"let action of entitiesData.baseData.multiSelectActions\" [disabled]=\"multiActionDisabled(action)\" (click)=\"runMultiAction(action)\" mat-menu-item>\n {{action.displayName}}\n </button>\n </mat-menu>\n\n <div\n *ngIf=\"entitiesData.baseData.allowCreate\"\n [class.col-lg-2]=\"entitiesData.baseData.multiSelectActions?.length\"\n [class.col-lg-4]=\"!entitiesData.baseData.multiSelectActions?.length\"\n [class.col-md-3]=\"entitiesData.baseData.multiSelectActions?.length\"\n [class.col-md-6]=\"!entitiesData.baseData.multiSelectActions?.length\"\n [class.col-sm-6]=\"entitiesData.baseData.multiSelectActions?.length\"\n [class.col-sm-12]=\"!entitiesData.baseData.multiSelectActions?.length\"\n >\n <button class=\"create-button\" (click)=\"createEntity()\" mat-raised-button>\n {{entitiesData.baseData.createButtonLabel ? entitiesData.baseData.createButtonLabel : 'Create'}}\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 entitiesData.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]=\"entitiesData.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{margin-bottom:15px}}@media (max-width: 575px){.create-button{margin-bottom:15px}}\n"] }]
1397
- }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i0.Injector }]; }, propDecorators: { entitiesData: [{
2134
+ 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"] }]
2135
+ }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i0.Injector }]; }, propDecorators: { tableData: [{
1398
2136
  type: Input
1399
2137
  }], paginator: [{
1400
2138
  type: ViewChild,
@@ -1407,354 +2145,342 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
1407
2145
  args: ['filter', { static: true }]
1408
2146
  }] } });
1409
2147
 
1410
- class NgxMatEntityTableModule {
2148
+ class NgxMatEntityCreateDialogModule {
1411
2149
  }
1412
- NgxMatEntityTableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1413
- NgxMatEntityTableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityTableModule, declarations: [NgxMatEntityTableComponent], imports: [CommonModule,
1414
- MatInputModule,
2150
+ NgxMatEntityCreateDialogModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityCreateDialogModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2151
+ NgxMatEntityCreateDialogModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityCreateDialogModule, declarations: [NgxMatEntityCreateDialogComponent], imports: [CommonModule,
2152
+ NgxMatEntityInputModule,
2153
+ MatDialogModule,
1415
2154
  FormsModule,
1416
- MatFormFieldModule,
1417
- MatCheckboxModule,
1418
- MatTableModule,
1419
- MatPaginatorModule,
1420
- MatButtonModule,
1421
- MatMenuModule,
1422
- MatDialogModule], exports: [NgxMatEntityTableComponent] });
1423
- NgxMatEntityTableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityTableModule, imports: [[
2155
+ MatButtonModule], exports: [NgxMatEntityCreateDialogComponent] });
2156
+ NgxMatEntityCreateDialogModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityCreateDialogModule, imports: [[
1424
2157
  CommonModule,
1425
- MatInputModule,
2158
+ NgxMatEntityInputModule,
2159
+ MatDialogModule,
1426
2160
  FormsModule,
1427
- MatFormFieldModule,
1428
- MatCheckboxModule,
1429
- MatTableModule,
1430
- MatPaginatorModule,
1431
- MatButtonModule,
1432
- MatMenuModule,
1433
- MatDialogModule
2161
+ MatButtonModule
1434
2162
  ]] });
1435
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityTableModule, decorators: [{
2163
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityCreateDialogModule, decorators: [{
1436
2164
  type: NgModule,
1437
2165
  args: [{
1438
- declarations: [NgxMatEntityTableComponent],
2166
+ declarations: [NgxMatEntityCreateDialogComponent],
1439
2167
  imports: [
1440
2168
  CommonModule,
1441
- MatInputModule,
2169
+ NgxMatEntityInputModule,
2170
+ MatDialogModule,
1442
2171
  FormsModule,
1443
- MatFormFieldModule,
1444
- MatCheckboxModule,
1445
- MatTableModule,
1446
- MatPaginatorModule,
1447
- MatButtonModule,
1448
- MatMenuModule,
1449
- MatDialogModule
2172
+ MatButtonModule
1450
2173
  ],
1451
- exports: [NgxMatEntityTableComponent]
2174
+ exports: [NgxMatEntityCreateDialogComponent]
1452
2175
  }]
1453
2176
  }] });
1454
2177
 
1455
- class NgxMatEntityInternalInputModule {
2178
+ class NgxMatEntityEditDialogModule {
1456
2179
  }
1457
- NgxMatEntityInternalInputModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInternalInputModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1458
- NgxMatEntityInternalInputModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInternalInputModule, declarations: [NgxMatEntityInternalInputComponent], imports: [CommonModule,
1459
- MatInputModule,
2180
+ NgxMatEntityEditDialogModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityEditDialogModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2181
+ NgxMatEntityEditDialogModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityEditDialogModule, declarations: [NgxMatEntityEditDialogComponent], imports: [CommonModule,
2182
+ NgxMatEntityInputModule,
2183
+ MatDialogModule,
1460
2184
  FormsModule,
1461
- MatFormFieldModule,
1462
- MatSelectModule,
1463
- MatAutocompleteModule,
1464
- MatCheckboxModule,
1465
- MatSlideToggleModule,
1466
- MatTableModule], exports: [NgxMatEntityInternalInputComponent] });
1467
- NgxMatEntityInternalInputModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInternalInputModule, imports: [[
2185
+ MatButtonModule,
2186
+ NgxMatEntityConfirmDialogModule], exports: [NgxMatEntityEditDialogComponent] });
2187
+ NgxMatEntityEditDialogModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityEditDialogModule, imports: [[
1468
2188
  CommonModule,
1469
- MatInputModule,
2189
+ NgxMatEntityInputModule,
2190
+ MatDialogModule,
1470
2191
  FormsModule,
1471
- MatFormFieldModule,
1472
- MatSelectModule,
1473
- MatAutocompleteModule,
1474
- MatCheckboxModule,
1475
- MatSlideToggleModule,
1476
- MatTableModule
2192
+ MatButtonModule,
2193
+ NgxMatEntityConfirmDialogModule
1477
2194
  ]] });
1478
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInternalInputModule, decorators: [{
2195
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityEditDialogModule, decorators: [{
1479
2196
  type: NgModule,
1480
2197
  args: [{
1481
- declarations: [NgxMatEntityInternalInputComponent],
2198
+ declarations: [NgxMatEntityEditDialogComponent],
1482
2199
  imports: [
1483
2200
  CommonModule,
1484
- MatInputModule,
2201
+ NgxMatEntityInputModule,
2202
+ MatDialogModule,
1485
2203
  FormsModule,
1486
- MatFormFieldModule,
1487
- MatSelectModule,
1488
- MatAutocompleteModule,
1489
- MatCheckboxModule,
1490
- MatSlideToggleModule,
1491
- MatTableModule
2204
+ MatButtonModule,
2205
+ NgxMatEntityConfirmDialogModule
1492
2206
  ],
1493
- exports: [NgxMatEntityInternalInputComponent]
1494
- }]
1495
- }] });
1496
-
1497
- class NgxMatEntityAddArrayItemDialogModule {
1498
- }
1499
- NgxMatEntityAddArrayItemDialogModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityAddArrayItemDialogModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1500
- NgxMatEntityAddArrayItemDialogModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityAddArrayItemDialogModule, declarations: [NgxMatEntityAddArrayItemDialogComponent], imports: [CommonModule, NgxMatEntityInternalInputModule, MatDialogModule, FormsModule, MatButtonModule], exports: [NgxMatEntityAddArrayItemDialogComponent] });
1501
- NgxMatEntityAddArrayItemDialogModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityAddArrayItemDialogModule, imports: [[CommonModule, NgxMatEntityInternalInputModule, MatDialogModule, FormsModule, MatButtonModule]] });
1502
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityAddArrayItemDialogModule, decorators: [{
1503
- type: NgModule,
1504
- args: [{
1505
- declarations: [NgxMatEntityAddArrayItemDialogComponent],
1506
- imports: [CommonModule, NgxMatEntityInternalInputModule, MatDialogModule, FormsModule, MatButtonModule],
1507
- exports: [NgxMatEntityAddArrayItemDialogComponent]
2207
+ exports: [NgxMatEntityEditDialogComponent]
1508
2208
  }]
1509
2209
  }] });
1510
2210
 
1511
- class NgxMatEntityArrayTableModule {
2211
+ class NgxMatEntityTableModule {
1512
2212
  }
1513
- NgxMatEntityArrayTableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityArrayTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1514
- NgxMatEntityArrayTableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityArrayTableModule, declarations: [NgxMatEntityArrayTableComponent], imports: [CommonModule,
2213
+ NgxMatEntityTableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2214
+ NgxMatEntityTableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityTableModule, declarations: [NgxMatEntityTableComponent], imports: [CommonModule,
1515
2215
  MatInputModule,
1516
2216
  FormsModule,
1517
2217
  MatFormFieldModule,
1518
- MatSelectModule,
1519
- MatAutocompleteModule,
1520
2218
  MatCheckboxModule,
1521
- MatSlideToggleModule,
1522
2219
  MatTableModule,
1523
- NgxMatEntityInternalInputModule,
2220
+ MatPaginatorModule,
1524
2221
  MatButtonModule,
1525
- NgxMatEntityAddArrayItemDialogModule], exports: [NgxMatEntityArrayTableComponent] });
1526
- NgxMatEntityArrayTableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityArrayTableModule, imports: [[
2222
+ MatMenuModule,
2223
+ MatDialogModule,
2224
+ NgxMatEntityCreateDialogModule,
2225
+ NgxMatEntityEditDialogModule], exports: [NgxMatEntityTableComponent] });
2226
+ NgxMatEntityTableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityTableModule, imports: [[
1527
2227
  CommonModule,
1528
2228
  MatInputModule,
1529
2229
  FormsModule,
1530
2230
  MatFormFieldModule,
1531
- MatSelectModule,
1532
- MatAutocompleteModule,
1533
2231
  MatCheckboxModule,
1534
- MatSlideToggleModule,
1535
2232
  MatTableModule,
1536
- NgxMatEntityInternalInputModule,
2233
+ MatPaginatorModule,
1537
2234
  MatButtonModule,
1538
- NgxMatEntityAddArrayItemDialogModule
2235
+ MatMenuModule,
2236
+ MatDialogModule,
2237
+ NgxMatEntityCreateDialogModule,
2238
+ NgxMatEntityEditDialogModule,
1539
2239
  ]] });
1540
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityArrayTableModule, decorators: [{
2240
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityTableModule, decorators: [{
1541
2241
  type: NgModule,
1542
2242
  args: [{
1543
- declarations: [NgxMatEntityArrayTableComponent],
2243
+ declarations: [NgxMatEntityTableComponent],
1544
2244
  imports: [
1545
2245
  CommonModule,
1546
2246
  MatInputModule,
1547
2247
  FormsModule,
1548
2248
  MatFormFieldModule,
1549
- MatSelectModule,
1550
- MatAutocompleteModule,
1551
2249
  MatCheckboxModule,
1552
- MatSlideToggleModule,
1553
2250
  MatTableModule,
1554
- NgxMatEntityInternalInputModule,
2251
+ MatPaginatorModule,
1555
2252
  MatButtonModule,
1556
- NgxMatEntityAddArrayItemDialogModule
2253
+ MatMenuModule,
2254
+ MatDialogModule,
2255
+ NgxMatEntityCreateDialogModule,
2256
+ NgxMatEntityEditDialogModule,
1557
2257
  ],
1558
- exports: [NgxMatEntityArrayTableComponent]
2258
+ exports: [NgxMatEntityTableComponent]
1559
2259
  }]
1560
2260
  }] });
1561
2261
 
1562
- class NgxMatEntityInputModule {
2262
+ /**
2263
+ * The internal EntityArrayDecoratorConfig. Sets default values.
2264
+ */
2265
+ class EntityArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
2266
+ constructor(data) {
2267
+ super(data);
2268
+ this.createInline = data.createInline != undefined ? data.createInline : true;
2269
+ this.displayStyle = data.displayStyle;
2270
+ this.itemType = data.itemType;
2271
+ this.EntityClass = data.EntityClass;
2272
+ this.displayColumns = data.displayColumns;
2273
+ this.createInline = data.createInline != undefined ? data.createInline : true;
2274
+ this.missingErrorMessage = data.missingErrorMessage ? data.missingErrorMessage : 'Needs to contain at least one value';
2275
+ this.defaultWidths = data.defaultWidths ? data.defaultWidths : [12, 12, 12];
2276
+ this.addButtonLabel = data.addButtonLabel ? data.addButtonLabel : 'Add';
2277
+ this.removeButtonLabel = data.removeButtonLabel ? data.removeButtonLabel : 'Remove';
2278
+ }
2279
+ }
2280
+ /**
2281
+ * The internal StringChipsArrayDecoratorConfig. Sets default values.
2282
+ */
2283
+ class StringChipsArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
2284
+ constructor(data) {
2285
+ super(data);
2286
+ this.deleteIcon = data.deleteIcon ? data.deleteIcon : 'fas fa-circle-minus';
2287
+ this.displayStyle = data.displayStyle;
2288
+ this.itemType = data.itemType;
2289
+ this.maxLength = data.maxLength;
2290
+ this.minLength = data.minLength;
2291
+ this.regex = data.regex;
2292
+ this.defaultWidths = data.defaultWidths ? data.defaultWidths : [6, 12, 12];
2293
+ }
2294
+ }
2295
+ /**
2296
+ * The internal AutocompleteStringChipsArrayDecoratorConfig. Sets default values.
2297
+ */
2298
+ class AutocompleteStringChipsArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
2299
+ constructor(data) {
2300
+ super(data);
2301
+ this.autocompleteValues = data.autocompleteValues;
2302
+ this.deleteIcon = data.deleteIcon ? data.deleteIcon : 'fas fa-circle-minus';
2303
+ this.displayStyle = data.displayStyle;
2304
+ this.itemType = data.itemType;
2305
+ this.maxLength = data.maxLength;
2306
+ this.minLength = data.minLength;
2307
+ this.regex = data.regex;
2308
+ this.defaultWidths = data.defaultWidths ? data.defaultWidths : [6, 12, 12];
2309
+ }
1563
2310
  }
1564
- NgxMatEntityInputModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1565
- NgxMatEntityInputModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, declarations: [NgxMatEntityInputComponent], imports: [CommonModule,
1566
- MatInputModule,
1567
- FormsModule,
1568
- MatFormFieldModule,
1569
- MatSelectModule,
1570
- MatAutocompleteModule,
1571
- MatCheckboxModule,
1572
- MatSlideToggleModule,
1573
- NgxMatEntityArrayTableModule,
1574
- MatChipsModule,
1575
- MatIconModule], exports: [NgxMatEntityInputComponent] });
1576
- NgxMatEntityInputModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, imports: [[
1577
- CommonModule,
1578
- MatInputModule,
1579
- FormsModule,
1580
- MatFormFieldModule,
1581
- MatSelectModule,
1582
- MatAutocompleteModule,
1583
- MatCheckboxModule,
1584
- MatSlideToggleModule,
1585
- NgxMatEntityArrayTableModule,
1586
- MatChipsModule,
1587
- MatIconModule
1588
- ]] });
1589
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, decorators: [{
1590
- type: NgModule,
1591
- args: [{
1592
- declarations: [NgxMatEntityInputComponent],
1593
- imports: [
1594
- CommonModule,
1595
- MatInputModule,
1596
- FormsModule,
1597
- MatFormFieldModule,
1598
- MatSelectModule,
1599
- MatAutocompleteModule,
1600
- MatCheckboxModule,
1601
- MatSlideToggleModule,
1602
- NgxMatEntityArrayTableModule,
1603
- MatChipsModule,
1604
- MatIconModule
1605
- ],
1606
- exports: [NgxMatEntityInputComponent]
1607
- }]
1608
- }] });
1609
2311
 
1610
- class NgxMatEntityCreateDialogModule {
2312
+ /**
2313
+ * Decorator for setting and getting array property metadata.
2314
+ *
2315
+ * @param metadata - The metadata of the array property.
2316
+ * @returns The method that defines the metadata.
2317
+ * @throws When the given type of the array-items is unknown.
2318
+ */
2319
+ function array(metadata) {
2320
+ switch (metadata.itemType) {
2321
+ case DecoratorTypes.OBJECT:
2322
+ return baseProperty(new EntityArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY);
2323
+ case DecoratorTypes.STRING:
2324
+ return baseProperty(new StringChipsArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY_STRING_CHIPS);
2325
+ case DecoratorTypes.STRING_AUTOCOMPLETE:
2326
+ return baseProperty(new AutocompleteStringChipsArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS);
2327
+ default:
2328
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
2329
+ throw new Error(`Unknown itemType ${metadata.itemType}`);
2330
+ }
1611
2331
  }
1612
- NgxMatEntityCreateDialogModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityCreateDialogModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1613
- NgxMatEntityCreateDialogModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityCreateDialogModule, declarations: [NgxMatEntityCreateDialogComponent], imports: [CommonModule, NgxMatEntityInputModule, MatDialogModule, FormsModule, MatButtonModule], exports: [NgxMatEntityCreateDialogComponent] });
1614
- NgxMatEntityCreateDialogModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityCreateDialogModule, imports: [[CommonModule, NgxMatEntityInputModule, MatDialogModule, FormsModule, MatButtonModule]] });
1615
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityCreateDialogModule, decorators: [{
1616
- type: NgModule,
1617
- args: [{
1618
- declarations: [NgxMatEntityCreateDialogComponent],
1619
- imports: [CommonModule, NgxMatEntityInputModule, MatDialogModule, FormsModule, MatButtonModule],
1620
- exports: [NgxMatEntityCreateDialogComponent]
1621
- }]
1622
- }] });
1623
2332
 
1624
- class NgxMatEntityEditDialogModule {
2333
+ /**
2334
+ * The base options for all propertyDecorators.
2335
+ */
2336
+ class PropertyDecoratorConfig {
1625
2337
  }
1626
- NgxMatEntityEditDialogModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityEditDialogModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1627
- NgxMatEntityEditDialogModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityEditDialogModule, declarations: [NgxMatEntityEditDialogComponent], imports: [CommonModule,
1628
- NgxMatEntityInputModule,
1629
- MatDialogModule,
1630
- FormsModule,
1631
- MatButtonModule,
1632
- NgxMatEntityConfirmDialogModule], exports: [NgxMatEntityEditDialogComponent] });
1633
- NgxMatEntityEditDialogModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityEditDialogModule, imports: [[
1634
- CommonModule,
1635
- NgxMatEntityInputModule,
1636
- MatDialogModule,
1637
- FormsModule,
1638
- MatButtonModule,
1639
- NgxMatEntityConfirmDialogModule
1640
- ]] });
1641
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityEditDialogModule, decorators: [{
1642
- type: NgModule,
1643
- args: [{
1644
- declarations: [NgxMatEntityEditDialogComponent],
1645
- imports: [
1646
- CommonModule,
1647
- NgxMatEntityInputModule,
1648
- MatDialogModule,
1649
- FormsModule,
1650
- MatButtonModule,
1651
- NgxMatEntityConfirmDialogModule
1652
- ],
1653
- exports: [NgxMatEntityEditDialogComponent]
1654
- }]
1655
- }] });
1656
2338
 
1657
2339
  /**
1658
- * Decorator for setting and getting string propery metadata
1659
- * @param metadata The metadata of the string property
2340
+ * Interface definition for the @array metadata.
2341
+ */
2342
+ class ArrayDecoratorConfig extends PropertyDecoratorConfig {
2343
+ }
2344
+
2345
+ /**
2346
+ * The internal DropdownBooleanDecoratorConfig. Sets default values.
2347
+ */
2348
+ class DropdownBooleanDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
2349
+ constructor(data) {
2350
+ super(data);
2351
+ this.displayStyle = data.displayStyle;
2352
+ this.dropdownTrue = data.dropdownTrue;
2353
+ this.dropdownFalse = data.dropdownFalse;
2354
+ }
2355
+ }
2356
+ /**
2357
+ * The internal CheckboxBooleanDecoratorConfig. Sets default values.
2358
+ */
2359
+ class CheckboxBooleanDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
2360
+ constructor(data) {
2361
+ super(data);
2362
+ this.displayStyle = data.displayStyle;
2363
+ this.required = data.required === undefined ? false : data.required;
2364
+ }
2365
+ }
2366
+ /**
2367
+ * The internal ToggleBooleanDecoratorConfig. Sets default values.
2368
+ */
2369
+ class ToggleBooleanDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
2370
+ constructor(data) {
2371
+ super(data);
2372
+ this.displayStyle = data.displayStyle;
2373
+ this.required = data.required === undefined ? false : data.required;
2374
+ }
2375
+ }
2376
+
2377
+ /**
2378
+ * Decorator for setting and getting boolean property metadata.
2379
+ *
2380
+ * @param metadata - The metadata of the boolean property.
2381
+ * @returns The method that defines the metadata.
1660
2382
  */
1661
2383
  function boolean(metadata) {
1662
2384
  if (metadata.displayStyle === 'dropdown') {
1663
- return baseProperty(new DropdownBooleanDecoratorConfig(metadata), DecoratorTypes.BOOLEAN_DROPDOWN);
2385
+ return baseProperty(new DropdownBooleanDecoratorConfigInternal(metadata), DecoratorTypes.BOOLEAN_DROPDOWN);
1664
2386
  }
1665
2387
  else if (metadata.displayStyle === 'checkbox') {
1666
- return baseProperty(new CheckboxBooleanDecoratorConfig(metadata), DecoratorTypes.BOOLEAN_CHECKBOX);
2388
+ return baseProperty(new CheckboxBooleanDecoratorConfigInternal(metadata), DecoratorTypes.BOOLEAN_CHECKBOX);
1667
2389
  }
1668
2390
  else {
1669
- return baseProperty(new ToggleBooleanDecoratorConfig(metadata), DecoratorTypes.BOOLEAN_TOGGLE);
2391
+ return baseProperty(new ToggleBooleanDecoratorConfigInternal(metadata), DecoratorTypes.BOOLEAN_TOGGLE);
1670
2392
  }
1671
2393
  }
2394
+
1672
2395
  /**
1673
- * The Definition for the @boolean metadata
2396
+ * The Definition for the @boolean metadata.
1674
2397
  */
1675
2398
  class BooleanDecoratorConfig extends PropertyDecoratorConfig {
1676
2399
  }
1677
- class DropdownBooleanDecoratorConfig extends BooleanDecoratorConfig {
1678
- constructor(metadata) {
1679
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
1680
- this.displayStyle = metadata.displayStyle;
1681
- this.dropdownTrue = metadata.dropdownTrue;
1682
- this.dropdownFalse = metadata.dropdownFalse;
1683
- }
1684
- }
1685
- class CheckboxBooleanDecoratorConfig extends BooleanDecoratorConfig {
1686
- constructor(metadata) {
1687
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
1688
- this.displayStyle = metadata.displayStyle;
2400
+
2401
+ /**
2402
+ * The internal DefaultNumberDecoratorConfig. Sets default values.
2403
+ */
2404
+ class DefaultNumberDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
2405
+ constructor(data) {
2406
+ super(data);
2407
+ this.displayStyle = data.displayStyle;
2408
+ this.max = data.max;
2409
+ this.min = data.min;
1689
2410
  }
1690
2411
  }
1691
- class ToggleBooleanDecoratorConfig extends BooleanDecoratorConfig {
1692
- constructor(metadata) {
1693
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
1694
- this.displayStyle = metadata.displayStyle;
2412
+ /**
2413
+ * The internal DropdownNumberDecoratorConfig. Sets default values.
2414
+ */
2415
+ class DropdownNumberDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
2416
+ constructor(data) {
2417
+ super(data);
2418
+ this.displayStyle = data.displayStyle;
2419
+ this.dropdownValues = data.dropdownValues;
1695
2420
  }
1696
2421
  }
1697
2422
 
1698
2423
  /**
1699
- * Decorator for setting and getting string propery metadata
1700
- * @param metadata The metadata of the string property
2424
+ * Decorator for setting and getting number property metadata.
2425
+ *
2426
+ * @param metadata - The metadata of the number property.
2427
+ * @returns The method that defines the metadata.
1701
2428
  */
1702
2429
  function number(metadata) {
1703
2430
  if (metadata.displayStyle === 'dropdown') {
1704
- return baseProperty(new DropdownNumberDecoratorConfig(metadata), DecoratorTypes.NUMBER_DROPDOWN);
2431
+ return baseProperty(new DropdownNumberDecoratorConfigInternal(metadata), DecoratorTypes.NUMBER_DROPDOWN);
1705
2432
  }
1706
2433
  else {
1707
- return baseProperty(new DefaultNumberDecoratorConfig(metadata), DecoratorTypes.NUMBER);
2434
+ return baseProperty(new DefaultNumberDecoratorConfigInternal(metadata), DecoratorTypes.NUMBER);
1708
2435
  }
1709
2436
  }
2437
+
1710
2438
  /**
1711
- * Interface definition for the @number metadata
2439
+ * Definition for the @number metadata.
1712
2440
  */
1713
2441
  class NumberDecoratorConfig extends PropertyDecoratorConfig {
1714
2442
  }
1715
- class DefaultNumberDecoratorConfig extends NumberDecoratorConfig {
1716
- constructor(metadata) {
1717
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
1718
- this.displayStyle = metadata.displayStyle;
1719
- this.min = metadata.min;
1720
- this.max = metadata.max;
1721
- }
1722
- }
1723
- class DropdownNumberDecoratorConfig extends NumberDecoratorConfig {
1724
- constructor(metadata) {
1725
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
1726
- this.displayStyle = metadata.displayStyle;
1727
- this.dropdownValues = metadata.dropdownValues;
2443
+
2444
+ /**
2445
+ * The internal DefaultObjectDecoratorConfig. Sets default values.
2446
+ */
2447
+ class DefaultObjectDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
2448
+ constructor(data) {
2449
+ super(data);
2450
+ this.displayStyle = data.displayStyle;
2451
+ this.EntityClass = data.EntityClass;
1728
2452
  }
1729
2453
  }
1730
2454
 
1731
2455
  /**
1732
- * Decorator for setting and getting object propery metadata.
1733
- * @param metadata The metadata of the object property
2456
+ * Decorator for setting and getting object property metadata.
2457
+ *
2458
+ * @param metadata - The metadata of the object property.
2459
+ * @returns The method that defines the metadata.
1734
2460
  */
1735
2461
  function object(metadata) {
1736
- return baseProperty(new DefaultObjectDecoratorConfig(metadata), DecoratorTypes.OBJECT);
2462
+ return baseProperty(new DefaultObjectDecoratorConfigInternal(metadata), DecoratorTypes.OBJECT);
1737
2463
  }
2464
+
1738
2465
  /**
1739
- * Interface definition for the @object metadata
2466
+ * Definition for the @object metadata.
1740
2467
  */
1741
2468
  class ObjectDecoratorConfig extends PropertyDecoratorConfig {
1742
2469
  }
1743
- class DefaultObjectDecoratorConfig extends ObjectDecoratorConfig {
1744
- constructor(metadata) {
1745
- super(metadata.displayName, metadata.display, metadata.required, metadata.omitForCreate, metadata.omitForUpdate, metadata.defaultWidths, metadata.order);
1746
- this.displayStyle = metadata.displayStyle;
1747
- this.type = metadata.type;
1748
- }
2470
+
2471
+ /**
2472
+ * Definition for the @string metadata.
2473
+ */
2474
+ class StringDecoratorConfig extends PropertyDecoratorConfig {
1749
2475
  }
1750
2476
 
1751
- /*
1752
- * Public API Surface of ngx-material-entity
2477
+ /**
2478
+ * Public API Surface of ngx-material-entity.
1753
2479
  */
1754
2480
 
1755
2481
  /**
1756
2482
  * Generated bundle index. Do not edit.
1757
2483
  */
1758
2484
 
1759
- export { AutocompleteStringChipsArrayDecoratorConfig, AutocompleteStringDecoratorConfig, CheckboxBooleanDecoratorConfig, DecoratorTypes, DefaultNumberDecoratorConfig, DefaultObjectDecoratorConfig, DefaultStringDecoratorConfig, DropdownBooleanDecoratorConfig, DropdownNumberDecoratorConfig, DropdownStringDecoratorConfig, Entity, EntityArrayDecoratorConfig, EntityService, EntityUtilities, NgxMatEntityConfirmDialogComponent, NgxMatEntityConfirmDialogModule, NgxMatEntityCreateDialogComponent, NgxMatEntityCreateDialogModule, NgxMatEntityEditDialogComponent, NgxMatEntityEditDialogModule, NgxMatEntityInputComponent, NgxMatEntityInputModule, NgxMatEntityTableComponent, NgxMatEntityTableModule, StringChipsArrayDecoratorConfig, TextboxStringDecoratorConfig, ToggleBooleanDecoratorConfig, array, boolean, getValidationErrorMessage, number, object, string };
2485
+ export { DateUtilities, DecoratorTypes, Entity, EntityService, EntityUtilities, NgxMatEntityConfirmDialogComponent, NgxMatEntityConfirmDialogModule, NgxMatEntityCreateDialogComponent, NgxMatEntityCreateDialogModule, NgxMatEntityEditDialogComponent, NgxMatEntityEditDialogModule, NgxMatEntityInputComponent, NgxMatEntityInputModule, NgxMatEntityTableComponent, NgxMatEntityTableModule, array, boolean, getValidationErrorMessage, number, object, string };
1760
2486
  //# sourceMappingURL=ngx-material-entity.mjs.map