ngx-material-entity 0.1.4 → 1.0.5
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.
- package/README.md +416 -39
- package/capsulation/lodash.utilities.d.ts +62 -0
- package/capsulation/reflect.utilities.d.ts +56 -0
- package/classes/base.builder.d.ts +2 -1
- package/classes/date.utilities.d.ts +18 -6
- package/classes/entity.model.d.ts +9 -2
- package/classes/entity.service.d.ts +38 -1
- package/classes/entity.utilities.d.ts +45 -16
- package/classes/file.utilities.d.ts +52 -0
- package/components/input/add-array-item-dialog-data.builder.d.ts +3 -2
- package/components/input/add-array-item-dialog-data.d.ts +2 -1
- package/components/input/array/array-date-input/array-date-input.component.d.ts +11 -0
- package/components/input/array/array-date-range-input/array-date-range-input.component.d.ts +20 -0
- package/components/input/array/array-date-time-input/array-date-time-input.component.d.ts +22 -0
- package/components/input/array/array-string-autocomplete-chips/array-string-autocomplete-chips.component.d.ts +50 -0
- package/components/input/array/array-string-chips-input/array-string-chips-input.component.d.ts +42 -0
- package/components/input/array/array-table.class.d.ts +48 -0
- package/components/input/base-input.component.d.ts +57 -0
- package/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.d.ts +10 -0
- package/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.d.ts +9 -0
- package/components/input/boolean/boolean-toggle-input/boolean-toggle-input.component.d.ts +10 -0
- package/components/input/custom/custom.component.d.ts +13 -0
- package/components/input/date/date-input/date-input.component.d.ts +11 -0
- package/components/input/date/date-range-input/date-range-input.component.d.ts +19 -0
- package/components/input/date/date-time-input/date-time-input.component.d.ts +30 -0
- package/components/input/file/file-default-input/file-default-input.component.d.ts +13 -0
- package/components/input/file/file-image-input/file-image-input.component.d.ts +22 -0
- package/components/input/file/file-input/dragDrop.directive.d.ts +32 -0
- package/components/input/file/file-input/file-input.component.d.ts +33 -0
- package/components/input/input.component.d.ts +49 -92
- package/components/input/input.module.d.ts +41 -16
- package/components/input/number/number-dropdown-input/number-dropdown-input.component.d.ts +9 -0
- package/components/input/number/number-input/number-input.component.d.ts +9 -0
- package/components/input/number/number-slider-input/number-slider-input.component.d.ts +9 -0
- package/components/input/string/string-autocomplete-input/string-autocomplete-input.component.d.ts +18 -0
- package/components/input/string/string-dropdown-input/string-dropdown-input.component.d.ts +9 -0
- package/components/input/string/string-input/string-input.component.d.ts +9 -0
- package/components/input/string/string-password-input/string-password-input.component.d.ts +15 -0
- package/components/input/string/string-textbox-input/string-textbox-input.component.d.ts +9 -0
- package/components/table/create-dialog/create-entity-dialog-data.builder.d.ts +3 -2
- package/components/table/create-dialog/create-entity-dialog-data.d.ts +2 -1
- package/components/table/create-dialog/create-entity-dialog.component.d.ts +7 -2
- package/components/table/edit-dialog/edit-dialog-data.builder.d.ts +3 -2
- package/components/table/edit-dialog/edit-entity-dialog-data.d.ts +6 -1
- package/components/table/edit-dialog/edit-entity-dialog.builder.d.ts +5 -3
- package/components/table/edit-dialog/edit-entity-dialog.component.d.ts +6 -2
- package/components/table/table-data.builder.d.ts +9 -8
- package/components/table/table-data.d.ts +18 -10
- package/components/table/table.component.d.ts +2 -1
- package/decorators/array/array-decorator-internal.data.d.ts +71 -6
- package/decorators/array/array-decorator.data.d.ts +178 -12
- package/decorators/array/array.decorator.d.ts +3 -2
- package/decorators/base/base-property.decorator.d.ts +2 -3
- package/decorators/base/decorator-types.enum.d.ts +15 -5
- package/decorators/custom/custom-decorator-internal.data.d.ts +17 -0
- package/decorators/custom/custom-decorator.data.d.ts +37 -0
- package/decorators/custom/custom.decorator.d.ts +11 -0
- package/decorators/date/date-decorator-internal.data.d.ts +2 -2
- package/decorators/date/date.decorator.d.ts +8 -0
- package/decorators/file/file-decorator-internal.data.d.ts +92 -0
- package/decorators/file/file-decorator.data.d.ts +92 -0
- package/decorators/file/file.decorator.d.ts +9 -0
- package/decorators/number/number-decorator-internal.data.d.ts +20 -1
- package/decorators/number/number-decorator.data.d.ts +27 -1
- package/decorators/number/number.decorator.d.ts +2 -2
- package/decorators/object/object-decorator-internal.data.d.ts +2 -2
- package/decorators/object/object-decorator.data.d.ts +3 -3
- package/decorators/object/object.decorator.d.ts +2 -1
- package/decorators/string/string-decorator-internal.data.d.ts +14 -1
- package/decorators/string/string-decorator.data.d.ts +37 -1
- package/decorators/string/string.decorator.d.ts +2 -2
- package/esm2020/capsulation/lodash.utilities.mjs +75 -0
- package/esm2020/capsulation/reflect.utilities.mjs +69 -0
- package/esm2020/classes/base.builder.mjs +2 -3
- package/esm2020/classes/date.utilities.mjs +35 -15
- package/esm2020/classes/entity.model.mjs +5 -1
- package/esm2020/classes/entity.service.mjs +103 -6
- package/esm2020/classes/entity.utilities.mjs +241 -71
- package/esm2020/classes/file.utilities.mjs +124 -0
- package/esm2020/components/confirm-dialog/confirm-dialog-data.builder.mjs +4 -4
- package/esm2020/components/confirm-dialog/confirm-dialog.component.mjs +3 -3
- package/esm2020/components/input/add-array-item-dialog-data.builder.mjs +2 -2
- package/esm2020/components/input/add-array-item-dialog-data.mjs +1 -1
- package/esm2020/components/input/array/array-date-input/array-date-input.component.mjs +26 -0
- package/esm2020/components/input/array/array-date-range-input/array-date-range-input.component.mjs +50 -0
- package/esm2020/components/input/array/array-date-time-input/array-date-time-input.component.mjs +50 -0
- package/esm2020/components/input/array/array-string-autocomplete-chips/array-string-autocomplete-chips.component.mjs +103 -0
- package/esm2020/components/input/array/array-string-chips-input/array-string-chips-input.component.mjs +85 -0
- package/esm2020/components/input/array/array-table.class.mjs +104 -0
- package/esm2020/components/input/base-input.component.mjs +65 -0
- package/esm2020/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.mjs +21 -0
- package/esm2020/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.mjs +17 -0
- package/esm2020/components/input/boolean/boolean-toggle-input/boolean-toggle-input.component.mjs +21 -0
- package/esm2020/components/input/custom/custom.component.mjs +26 -0
- package/esm2020/components/input/date/date-input/date-input.component.mjs +22 -0
- package/esm2020/components/input/date/date-range-input/date-range-input.component.mjs +51 -0
- package/esm2020/components/input/date/date-time-input/date-time-input.component.mjs +63 -0
- package/esm2020/components/input/file/file-default-input/file-default-input.component.mjs +23 -0
- package/esm2020/components/input/file/file-image-input/file-image-input.component.mjs +84 -0
- package/esm2020/components/input/file/file-input/dragDrop.directive.mjs +64 -0
- package/esm2020/components/input/file/file-input/file-input.component.mjs +154 -0
- package/esm2020/components/input/input.component.mjs +137 -236
- package/esm2020/components/input/input.module.mjs +82 -6
- package/esm2020/components/input/number/number-dropdown-input/number-dropdown-input.component.mjs +18 -0
- package/esm2020/components/input/number/number-input/number-input.component.mjs +16 -0
- package/esm2020/components/input/number/number-slider-input/number-slider-input.component.mjs +17 -0
- package/esm2020/components/input/string/string-autocomplete-input/string-autocomplete-input.component.mjs +35 -0
- package/esm2020/components/input/string/string-dropdown-input/string-dropdown-input.component.mjs +18 -0
- package/esm2020/components/input/string/string-input/string-input.component.mjs +16 -0
- package/esm2020/components/input/string/string-password-input/string-password-input.component.mjs +36 -0
- package/esm2020/components/input/string/string-textbox-input/string-textbox-input.component.mjs +17 -0
- package/esm2020/components/table/create-dialog/create-dialog-data.builder.mjs +2 -2
- package/esm2020/components/table/create-dialog/create-entity-dialog-data.builder.mjs +1 -1
- package/esm2020/components/table/create-dialog/create-entity-dialog-data.mjs +1 -1
- package/esm2020/components/table/create-dialog/create-entity-dialog.component.mjs +15 -8
- package/esm2020/components/table/edit-dialog/edit-dialog-data.builder.mjs +2 -2
- package/esm2020/components/table/edit-dialog/edit-entity-dialog-data.mjs +1 -1
- package/esm2020/components/table/edit-dialog/edit-entity-dialog.builder.mjs +4 -3
- package/esm2020/components/table/edit-dialog/edit-entity-dialog.component.mjs +19 -10
- package/esm2020/components/table/table-data.builder.mjs +13 -10
- package/esm2020/components/table/table-data.mjs +1 -1
- package/esm2020/components/table/table.component.mjs +35 -35
- package/esm2020/decorators/array/array-decorator-internal.data.mjs +102 -14
- package/esm2020/decorators/array/array-decorator.data.mjs +2 -2
- package/esm2020/decorators/array/array.decorator.mjs +8 -2
- package/esm2020/decorators/base/base-property.decorator.mjs +4 -3
- package/esm2020/decorators/base/decorator-types.enum.mjs +9 -1
- package/esm2020/decorators/base/property-decorator-internal.data.mjs +10 -10
- package/esm2020/decorators/base/property-decorator.data.mjs +1 -1
- package/esm2020/decorators/boolean/boolean-decorator-internal.data.mjs +3 -3
- package/esm2020/decorators/custom/custom-decorator-internal.data.mjs +26 -0
- package/esm2020/decorators/custom/custom-decorator.data.mjs +2 -0
- package/esm2020/decorators/custom/custom.decorator.mjs +13 -0
- package/esm2020/decorators/date/date-decorator-internal.data.mjs +5 -5
- package/esm2020/decorators/date/date.decorator.mjs +21 -0
- package/esm2020/decorators/file/file-decorator-internal.data.mjs +98 -0
- package/esm2020/decorators/file/file-decorator.data.mjs +7 -0
- package/esm2020/decorators/file/file.decorator.mjs +22 -0
- package/esm2020/decorators/number/number-decorator-internal.data.mjs +24 -1
- package/esm2020/decorators/number/number-decorator.data.mjs +1 -1
- package/esm2020/decorators/number/number.decorator.mjs +9 -7
- package/esm2020/decorators/object/object-decorator-internal.data.mjs +1 -1
- package/esm2020/decorators/object/object-decorator.data.mjs +1 -1
- package/esm2020/decorators/object/object.decorator.mjs +1 -1
- package/esm2020/decorators/string/string-decorator-internal.data.mjs +16 -1
- package/esm2020/decorators/string/string-decorator.data.mjs +1 -1
- package/esm2020/decorators/string/string.decorator.mjs +13 -13
- package/esm2020/mocks/placeholder-data.png.mjs +3 -0
- package/esm2020/public-api.mjs +9 -1
- package/fesm2015/ngx-material-entity.mjs +2488 -524
- package/fesm2015/ngx-material-entity.mjs.map +1 -1
- package/fesm2020/ngx-material-entity.mjs +2363 -493
- package/fesm2020/ngx-material-entity.mjs.map +1 -1
- package/mocks/placeholder-data.png.d.ts +1 -0
- package/package.json +1 -1
- package/public-api.d.ts +8 -0
|
@@ -1,45 +1,116 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import { __decorate, __metadata } from 'tslib';
|
|
3
|
+
import { isEqual, cloneDeep, omit, isNil, omitBy, isArray } from 'lodash';
|
|
3
4
|
import { BehaviorSubject, firstValueFrom, Subject, takeUntil } from 'rxjs';
|
|
4
|
-
import { cloneDeep, isEqual, omit, omitBy, isNil } from 'lodash';
|
|
5
5
|
import * as i0 from '@angular/core';
|
|
6
|
-
import { Component, Inject, NgModule, Input, ViewChild } from '@angular/core';
|
|
6
|
+
import { Component, Inject, NgModule, EventEmitter, Input, Output, Directive, HostListener, ViewChild } from '@angular/core';
|
|
7
7
|
import * as i1 from '@angular/material/dialog';
|
|
8
8
|
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
9
|
-
import * as
|
|
9
|
+
import * as i2 from '@angular/material/checkbox';
|
|
10
10
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
11
11
|
import * as i3 from '@angular/material/button';
|
|
12
12
|
import { MatButtonModule } from '@angular/material/button';
|
|
13
|
-
import * as
|
|
13
|
+
import * as i6 from '@angular/common';
|
|
14
14
|
import { CommonModule } from '@angular/common';
|
|
15
|
-
import * as
|
|
15
|
+
import * as i4 from '@angular/forms';
|
|
16
16
|
import { FormsModule } from '@angular/forms';
|
|
17
|
-
import * as
|
|
17
|
+
import * as i4$2 from '@angular/material/table';
|
|
18
18
|
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
|
19
19
|
import { SelectionModel } from '@angular/cdk/collections';
|
|
20
|
-
import * as
|
|
20
|
+
import * as i1$1 from '@angular/material/form-field';
|
|
21
21
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
22
|
-
import * as
|
|
22
|
+
import * as i4$1 from '@angular/material/input';
|
|
23
|
+
import { MatInputModule } from '@angular/material/input';
|
|
24
|
+
import * as i3$1 from '@angular/cdk/text-field';
|
|
25
|
+
import * as i2$1 from '@angular/material/autocomplete';
|
|
23
26
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
|
24
|
-
import * as
|
|
25
|
-
import * as
|
|
27
|
+
import * as i3$2 from '@angular/material/core';
|
|
28
|
+
import * as i2$2 from '@angular/material/select';
|
|
26
29
|
import { MatSelectModule } from '@angular/material/select';
|
|
27
|
-
import * as
|
|
30
|
+
import * as i2$3 from '@angular/material/slide-toggle';
|
|
28
31
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
29
|
-
import * as
|
|
30
|
-
import {
|
|
31
|
-
import * as
|
|
32
|
+
import * as i2$4 from '@angular/material/slider';
|
|
33
|
+
import { MatSliderModule } from '@angular/material/slider';
|
|
34
|
+
import * as i2$5 from '@angular/material/datepicker';
|
|
32
35
|
import { MatDatepickerModule } from '@angular/material/datepicker';
|
|
33
|
-
import * as
|
|
34
|
-
import {
|
|
35
|
-
import * as i15 from '@angular/cdk/text-field';
|
|
36
|
+
import * as i2$6 from '@angular/material/chips';
|
|
37
|
+
import { MatChipsModule } from '@angular/material/chips';
|
|
36
38
|
import { MatIconModule } from '@angular/material/icon';
|
|
37
|
-
import * as i7
|
|
39
|
+
import * as i7 from '@angular/material/paginator';
|
|
38
40
|
import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
|
|
39
41
|
import { MatSort } from '@angular/material/sort';
|
|
40
|
-
import * as i4$
|
|
42
|
+
import * as i4$3 from '@angular/material/menu';
|
|
41
43
|
import { MatMenuModule } from '@angular/material/menu';
|
|
42
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Encapsulates all functionality of Reflect.
|
|
47
|
+
*/
|
|
48
|
+
class ReflectUtilities {
|
|
49
|
+
/**
|
|
50
|
+
* Gets the metadata value for the provided metadata key on the target object or its prototype chain.
|
|
51
|
+
*
|
|
52
|
+
* @param metadataKey - A key used to store and retrieve metadata.
|
|
53
|
+
* @param target - The target object on which the metadata is defined.
|
|
54
|
+
* @param propertyKey - The property key for the target.
|
|
55
|
+
* @returns The metadata value for the metadata key if found; otherwise, undefined.
|
|
56
|
+
*/
|
|
57
|
+
static getMetadata(metadataKey, target, propertyKey) {
|
|
58
|
+
return Reflect.getMetadata(metadataKey, target, propertyKey);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Returns the string and symbol keys of the own properties of an object. The own properties of an object
|
|
62
|
+
* are those that are defined directly on that object, and are not inherited from the object's prototype.
|
|
63
|
+
*
|
|
64
|
+
* @param target - Object that contains the own properties.
|
|
65
|
+
* @returns The keys of the given object.
|
|
66
|
+
*/
|
|
67
|
+
static ownKeys(target) {
|
|
68
|
+
return Reflect.ownKeys(target);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Gets the property of target, equivalent to `target[propertyKey]`.
|
|
72
|
+
*
|
|
73
|
+
* @param target - Object that contains the property on itself or in its prototype chain.
|
|
74
|
+
* @param propertyKey - The property name.
|
|
75
|
+
* @returns The property of the target of the given key.
|
|
76
|
+
*/
|
|
77
|
+
static get(target, propertyKey) {
|
|
78
|
+
return Reflect.get(target, propertyKey);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Sets the property of target, equivalent to `target[propertyKey] = value`.
|
|
82
|
+
*
|
|
83
|
+
* @param target - Object that contains the property on itself or in its prototype chain.
|
|
84
|
+
* @param propertyKey - The property name.
|
|
85
|
+
* @param value - The value to set the property to.
|
|
86
|
+
* @returns If setting the value was successful.
|
|
87
|
+
*/
|
|
88
|
+
static set(target, propertyKey, value) {
|
|
89
|
+
return Reflect.set(target, propertyKey, value);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Equivalent to `propertyKey in target`.
|
|
93
|
+
*
|
|
94
|
+
* @param target - Object that contains the property on itself or in its prototype chain.
|
|
95
|
+
* @param propertyKey - Name of the property.
|
|
96
|
+
* @returns Whether or not the given target has the key.
|
|
97
|
+
*/
|
|
98
|
+
static has(target, propertyKey) {
|
|
99
|
+
return Reflect.has(target, propertyKey);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Define a unique metadata entry on the target.
|
|
103
|
+
*
|
|
104
|
+
* @param metadataKey - A key used to store and retrieve metadata.
|
|
105
|
+
* @param metadataValue - A value that contains attached metadata.
|
|
106
|
+
* @param target - The target object on which to define metadata.
|
|
107
|
+
* @param propertyKey - The property key for the target.
|
|
108
|
+
*/
|
|
109
|
+
static defineMetadata(metadataKey, metadataValue, target, propertyKey) {
|
|
110
|
+
Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
43
114
|
/**
|
|
44
115
|
* The base decorator for setting metadata on properties.
|
|
45
116
|
*
|
|
@@ -49,8 +120,8 @@ import { MatMenuModule } from '@angular/material/menu';
|
|
|
49
120
|
*/
|
|
50
121
|
function baseProperty(metadata, type) {
|
|
51
122
|
return function (target, propertyKey) {
|
|
52
|
-
|
|
53
|
-
|
|
123
|
+
ReflectUtilities.defineMetadata('metadata', metadata, target, propertyKey);
|
|
124
|
+
ReflectUtilities.defineMetadata('type', type, target, propertyKey);
|
|
54
125
|
};
|
|
55
126
|
}
|
|
56
127
|
|
|
@@ -63,18 +134,26 @@ var DecoratorTypes;
|
|
|
63
134
|
DecoratorTypes["STRING_DROPDOWN"] = "stringDropdown";
|
|
64
135
|
DecoratorTypes["STRING_AUTOCOMPLETE"] = "stringAutocomplete";
|
|
65
136
|
DecoratorTypes["STRING_TEXTBOX"] = "stringTextbox";
|
|
137
|
+
DecoratorTypes["STRING_PASSWORD"] = "stringPassword";
|
|
66
138
|
DecoratorTypes["NUMBER"] = "number";
|
|
67
139
|
DecoratorTypes["NUMBER_DROPDOWN"] = "numberDropdown";
|
|
140
|
+
DecoratorTypes["NUMBER_SLIDER"] = "numberSlider";
|
|
68
141
|
DecoratorTypes["BOOLEAN_CHECKBOX"] = "boolean";
|
|
69
142
|
DecoratorTypes["BOOLEAN_TOGGLE"] = "booleanToggle";
|
|
70
143
|
DecoratorTypes["BOOLEAN_DROPDOWN"] = "booleanDropdown";
|
|
71
144
|
DecoratorTypes["OBJECT"] = "object";
|
|
72
145
|
DecoratorTypes["ARRAY"] = "array";
|
|
146
|
+
DecoratorTypes["ARRAY_DATE"] = "arrayDate";
|
|
147
|
+
DecoratorTypes["ARRAY_DATE_TIME"] = "arrayDateTime";
|
|
148
|
+
DecoratorTypes["ARRAY_DATE_RANGE"] = "arrayDateRange";
|
|
73
149
|
DecoratorTypes["ARRAY_STRING_CHIPS"] = "arrayStringChips";
|
|
74
150
|
DecoratorTypes["ARRAY_STRING_AUTOCOMPLETE_CHIPS"] = "arrayStringAutocompleteChips";
|
|
75
151
|
DecoratorTypes["DATE"] = "date";
|
|
76
152
|
DecoratorTypes["DATE_RANGE"] = "dateRange";
|
|
77
153
|
DecoratorTypes["DATE_TIME"] = "dateTime";
|
|
154
|
+
DecoratorTypes["FILE_DEFAULT"] = "fileDefault";
|
|
155
|
+
DecoratorTypes["FILE_IMAGE"] = "fileImage";
|
|
156
|
+
DecoratorTypes["CUSTOM"] = "custom";
|
|
78
157
|
})(DecoratorTypes || (DecoratorTypes = {}));
|
|
79
158
|
|
|
80
159
|
/**
|
|
@@ -83,11 +162,11 @@ var DecoratorTypes;
|
|
|
83
162
|
class PositionInternal {
|
|
84
163
|
constructor(data) {
|
|
85
164
|
this.validateInput(data);
|
|
86
|
-
this.row = data?.row
|
|
87
|
-
this.order = data?.order
|
|
165
|
+
this.row = data?.row ?? -1;
|
|
166
|
+
this.order = data?.order ?? -1;
|
|
88
167
|
}
|
|
89
168
|
validateInput(data) {
|
|
90
|
-
if (data?.order) {
|
|
169
|
+
if (data?.order != null) {
|
|
91
170
|
if (data.order < 1) {
|
|
92
171
|
throw new Error('order must be at least 1');
|
|
93
172
|
}
|
|
@@ -95,7 +174,7 @@ class PositionInternal {
|
|
|
95
174
|
throw new Error('order cannot be bigger than 12 (the minimum value for a bootstrap column)');
|
|
96
175
|
}
|
|
97
176
|
}
|
|
98
|
-
if (data?.row &&
|
|
177
|
+
if (data?.row != null && data.row < 1) {
|
|
99
178
|
throw new Error('row must be at least 1');
|
|
100
179
|
}
|
|
101
180
|
}
|
|
@@ -105,12 +184,12 @@ class PositionInternal {
|
|
|
105
184
|
*/
|
|
106
185
|
class PropertyDecoratorConfigInternal {
|
|
107
186
|
constructor(data) {
|
|
108
|
-
this.display = data.display
|
|
187
|
+
this.display = data.display ?? true;
|
|
109
188
|
this.displayName = data.displayName;
|
|
110
|
-
this.required = data.required
|
|
111
|
-
this.omitForCreate = data.omitForCreate
|
|
112
|
-
this.omitForUpdate = data.omitForUpdate
|
|
113
|
-
this.defaultWidths = data.defaultWidths
|
|
189
|
+
this.required = data.required ?? true;
|
|
190
|
+
this.omitForCreate = data.omitForCreate ?? false;
|
|
191
|
+
this.omitForUpdate = data.omitForUpdate ?? false;
|
|
192
|
+
this.defaultWidths = data.defaultWidths ?? [6, 6, 12];
|
|
114
193
|
this.position = new PositionInternal(data.position);
|
|
115
194
|
}
|
|
116
195
|
}
|
|
@@ -161,6 +240,21 @@ class AutocompleteStringDecoratorConfigInternal extends PropertyDecoratorConfigI
|
|
|
161
240
|
this.regex = data.regex;
|
|
162
241
|
}
|
|
163
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* The internal PasswordStringDecoratorConfig. Sets default values.
|
|
245
|
+
*/
|
|
246
|
+
class PasswordStringDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
247
|
+
constructor(data) {
|
|
248
|
+
super(data);
|
|
249
|
+
this.displayStyle = data.displayStyle;
|
|
250
|
+
this.minLength = data.minLength;
|
|
251
|
+
this.maxLength = data.maxLength;
|
|
252
|
+
this.regex = data.regex;
|
|
253
|
+
this.needsConfirmation = data.needsConfirmation ?? true;
|
|
254
|
+
this.confirmationDisplayName = data.confirmationDisplayName ?? 'Confirm Password';
|
|
255
|
+
this.passwordsDontMatchErrorMessage = data.passwordsDontMatchErrorMessage ?? 'Passwords need to match!';
|
|
256
|
+
}
|
|
257
|
+
}
|
|
164
258
|
|
|
165
259
|
/**
|
|
166
260
|
* Decorator for setting and getting string Property metadata.
|
|
@@ -169,36 +263,93 @@ class AutocompleteStringDecoratorConfigInternal extends PropertyDecoratorConfigI
|
|
|
169
263
|
* @returns The method that defines the metadata.
|
|
170
264
|
*/
|
|
171
265
|
function string(metadata) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
266
|
+
switch (metadata.displayStyle) {
|
|
267
|
+
case 'dropdown':
|
|
268
|
+
return baseProperty(new DropdownStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_DROPDOWN);
|
|
269
|
+
case 'autocomplete':
|
|
270
|
+
return baseProperty(new AutocompleteStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_AUTOCOMPLETE);
|
|
271
|
+
case 'textbox':
|
|
272
|
+
return baseProperty(new TextboxStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_TEXTBOX);
|
|
273
|
+
case 'password':
|
|
274
|
+
return baseProperty(new PasswordStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING_PASSWORD);
|
|
275
|
+
default:
|
|
276
|
+
return baseProperty(new DefaultStringDecoratorConfigInternal(metadata), DecoratorTypes.STRING);
|
|
183
277
|
}
|
|
184
278
|
}
|
|
185
279
|
|
|
186
280
|
/**
|
|
187
|
-
*
|
|
281
|
+
* Encapsulates all functionality of lodash.
|
|
188
282
|
*/
|
|
189
|
-
class
|
|
283
|
+
class LodashUtilities {
|
|
284
|
+
/**
|
|
285
|
+
* Performs a deep comparison between two values to determine if they are
|
|
286
|
+
* equivalent.
|
|
287
|
+
*
|
|
288
|
+
* **Note:** This method supports comparing arrays, array buffers, booleans,
|
|
289
|
+
* date objects, error objects, maps, numbers, `Object` objects, regexps,
|
|
290
|
+
* sets, strings, symbols, and typed arrays. `Object` objects are compared
|
|
291
|
+
* by their own, not inherited, enumerable properties. Functions and DOM
|
|
292
|
+
* nodes are **not** supported.
|
|
293
|
+
*
|
|
294
|
+
* @param value - The value to compare.
|
|
295
|
+
* @param other - The other value to compare.
|
|
296
|
+
* @returns Returns `true` if the values are equivalent, else `false`.
|
|
297
|
+
*/
|
|
298
|
+
static isEqual(value, other) {
|
|
299
|
+
return isEqual(value, other);
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* This method is like _.clone except that it recursively clones value.
|
|
303
|
+
*
|
|
304
|
+
* @param value - The value to recursively clone.
|
|
305
|
+
* @returns Returns the deep cloned value.
|
|
306
|
+
*/
|
|
307
|
+
static cloneDeep(value) {
|
|
308
|
+
return cloneDeep(value);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* The opposite of `_.pick`; this method creates an object composed of the
|
|
312
|
+
* own and inherited enumerable properties of `object` that are not omitted.
|
|
313
|
+
*
|
|
314
|
+
* @param object - The source object.
|
|
315
|
+
* @param paths - The property names to omit, specified
|
|
316
|
+
* individually or in arrays.
|
|
317
|
+
* @returns Returns the new object.
|
|
318
|
+
*/
|
|
319
|
+
static omit(object, ...paths) {
|
|
320
|
+
return omit(object, ...paths);
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Checks if `value` is `null` or `undefined`.
|
|
324
|
+
*
|
|
325
|
+
* @param value - The value to check.
|
|
326
|
+
* @returns Returns `true` if `value` is nullish, else `false`.
|
|
327
|
+
*/
|
|
328
|
+
static isNil(value) {
|
|
329
|
+
return isNil(value);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* The opposite of `_.pickBy`; this method creates an object composed of the
|
|
333
|
+
* own and inherited enumerable properties of `object` that `predicate`
|
|
334
|
+
* doesn't return truthy for.
|
|
335
|
+
*
|
|
336
|
+
* @param object - The source object.
|
|
337
|
+
* @param predicate - The function invoked per property.
|
|
338
|
+
* @returns Returns the new object.
|
|
339
|
+
*/
|
|
340
|
+
static omitBy(object, predicate) {
|
|
341
|
+
return omitBy(object, predicate);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Checks if value is classified as an Array object.
|
|
345
|
+
*
|
|
346
|
+
* @param value - The value to check.
|
|
347
|
+
* @returns Returns true if value is correctly classified, else false.
|
|
348
|
+
*/
|
|
349
|
+
static isArray(value) {
|
|
350
|
+
return isArray(value);
|
|
351
|
+
}
|
|
190
352
|
}
|
|
191
|
-
__decorate([
|
|
192
|
-
string({
|
|
193
|
-
omitForCreate: true,
|
|
194
|
-
omitForUpdate: true,
|
|
195
|
-
display: false,
|
|
196
|
-
displayStyle: 'line',
|
|
197
|
-
displayName: 'ID',
|
|
198
|
-
required: true
|
|
199
|
-
}),
|
|
200
|
-
__metadata("design:type", String)
|
|
201
|
-
], Entity.prototype, "id", void 0);
|
|
202
353
|
|
|
203
354
|
const DAY_IN_MS = 1000 * 60 * 60 * 24;
|
|
204
355
|
/**
|
|
@@ -225,14 +376,14 @@ class DateUtilities {
|
|
|
225
376
|
const res = [{ displayName: '-', value: undefined }];
|
|
226
377
|
for (let hour = 0; hour < 24; hour++) {
|
|
227
378
|
for (let minute = 0; minute < 60; minute += minuteSteps) {
|
|
228
|
-
res.push(
|
|
379
|
+
res.push(DateUtilities.getTimeDropdownValue(format, hour, minute));
|
|
229
380
|
}
|
|
230
381
|
}
|
|
231
382
|
return res;
|
|
232
383
|
}
|
|
233
384
|
static getTimeDropdownValue(format, hour, minute) {
|
|
234
|
-
const displayHour =
|
|
235
|
-
const displayMinute =
|
|
385
|
+
const displayHour = DateUtilities.getFormattedHour(format, LodashUtilities.cloneDeep(hour));
|
|
386
|
+
const displayMinute = DateUtilities.getFormattedMinute(format, hour, minute);
|
|
236
387
|
return {
|
|
237
388
|
displayName: `${displayHour}:${displayMinute}`,
|
|
238
389
|
value: {
|
|
@@ -270,10 +421,7 @@ class DateUtilities {
|
|
|
270
421
|
*/
|
|
271
422
|
static getTimeFromDate(value) {
|
|
272
423
|
if (!value) {
|
|
273
|
-
return
|
|
274
|
-
hours: undefined,
|
|
275
|
-
minutes: undefined
|
|
276
|
-
};
|
|
424
|
+
return undefined;
|
|
277
425
|
}
|
|
278
426
|
else {
|
|
279
427
|
return {
|
|
@@ -287,10 +435,10 @@ class DateUtilities {
|
|
|
287
435
|
*
|
|
288
436
|
* @param startDate - The start date.
|
|
289
437
|
* @param endDate - The end date.
|
|
290
|
-
* @param
|
|
438
|
+
* @param filter - The custom filter from the metadata.
|
|
291
439
|
* @returns All dates between the two provided dates. Includes start and end date.
|
|
292
440
|
*/
|
|
293
|
-
static getDatesBetween(startDate, endDate,
|
|
441
|
+
static getDatesBetween(startDate, endDate, filter) {
|
|
294
442
|
const res = [];
|
|
295
443
|
while (startDate.getFullYear() < endDate.getFullYear()
|
|
296
444
|
|| startDate.getMonth() < endDate.getMonth()
|
|
@@ -298,8 +446,8 @@ class DateUtilities {
|
|
|
298
446
|
res.push(new Date(startDate));
|
|
299
447
|
startDate.setTime(startDate.getTime() + DAY_IN_MS);
|
|
300
448
|
}
|
|
301
|
-
if (
|
|
302
|
-
return res.filter(d =>
|
|
449
|
+
if (filter) {
|
|
450
|
+
return res.filter(d => filter(d));
|
|
303
451
|
}
|
|
304
452
|
else {
|
|
305
453
|
return res;
|
|
@@ -308,14 +456,14 @@ class DateUtilities {
|
|
|
308
456
|
/**
|
|
309
457
|
* Get all valid times for the dropdown of a datetime property.
|
|
310
458
|
*
|
|
311
|
-
* @param date - The date of the datetime.
|
|
312
459
|
* @param times - All given times to filter.
|
|
460
|
+
* @param date - The date of the datetime.
|
|
313
461
|
* @param min - The function that defines the minimum time.
|
|
314
462
|
* @param max - The function that defines the maximum time.
|
|
315
463
|
* @param filter - A filter function to do more specific time filtering. This could be e.g. The removal of lunch breaks.
|
|
316
464
|
* @returns All valid dropdown values for the datetime property.
|
|
317
465
|
*/
|
|
318
|
-
static getValidTimesForDropdown(
|
|
466
|
+
static getValidTimesForDropdown(times, date, min, max, filter) {
|
|
319
467
|
if (min) {
|
|
320
468
|
const minTime = min(date);
|
|
321
469
|
times = times.filter(t => !t.value
|
|
@@ -335,6 +483,152 @@ class DateUtilities {
|
|
|
335
483
|
}
|
|
336
484
|
return times;
|
|
337
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* Checks if the time object has processable hours and minutes properties.
|
|
488
|
+
* Doesn't check custom validators like min/max from the metadata configuration.
|
|
489
|
+
*
|
|
490
|
+
* @param time - The time to check.
|
|
491
|
+
* @returns Whether or not the time object is unprocessable.
|
|
492
|
+
*/
|
|
493
|
+
static timeIsUnprocessable(time) {
|
|
494
|
+
if (!time
|
|
495
|
+
|| time.hours == null
|
|
496
|
+
|| typeof time.hours !== 'number'
|
|
497
|
+
|| Number.isNaN(time.hours)
|
|
498
|
+
|| time.minutes == null
|
|
499
|
+
|| typeof time.minutes !== 'number'
|
|
500
|
+
|| Number.isNaN(time.minutes)) {
|
|
501
|
+
return true;
|
|
502
|
+
}
|
|
503
|
+
return false;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* The default filter function to user when none was provided by the user.
|
|
508
|
+
*/
|
|
509
|
+
DateUtilities.defaultDateFilter = () => true;
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Provides functionality regarding files.
|
|
513
|
+
*/
|
|
514
|
+
class FileUtilities {
|
|
515
|
+
/**
|
|
516
|
+
* Gets the accept value for the html input.
|
|
517
|
+
*
|
|
518
|
+
* @param mimeTypes - The mimeTypes to get the accept string from.
|
|
519
|
+
* @returns A comma separated string of all the provided mime types.
|
|
520
|
+
*/
|
|
521
|
+
static getAcceptString(mimeTypes) {
|
|
522
|
+
if (!mimeTypes?.length) {
|
|
523
|
+
return '*';
|
|
524
|
+
}
|
|
525
|
+
return mimeTypes.join(', ');
|
|
526
|
+
}
|
|
527
|
+
// TODO: Find a way to use blobs with jest
|
|
528
|
+
/* istanbul ignore next */
|
|
529
|
+
/**
|
|
530
|
+
* Reads a url to display the given file.
|
|
531
|
+
*
|
|
532
|
+
* @param file - The file to get the url from.
|
|
533
|
+
* @returns A promise of the url. Undefined if no file was provided.
|
|
534
|
+
*/
|
|
535
|
+
static async getDataURLFromFile(file) {
|
|
536
|
+
if (!file) {
|
|
537
|
+
return undefined;
|
|
538
|
+
}
|
|
539
|
+
return new Promise((resolve, reject) => {
|
|
540
|
+
const reader = new FileReader();
|
|
541
|
+
reader.onload = e => resolve(e.target?.result);
|
|
542
|
+
reader.onerror = e => reject(e);
|
|
543
|
+
reader.readAsDataURL(file);
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
// TODO: Find a way to use blobs with jest
|
|
547
|
+
/* istanbul ignore next */
|
|
548
|
+
/**
|
|
549
|
+
* Gets a file from the given url.
|
|
550
|
+
*
|
|
551
|
+
* @param url - The url to get the file from.
|
|
552
|
+
* @returns A promise of the File.
|
|
553
|
+
*/
|
|
554
|
+
static async getFileFromUrl(url) {
|
|
555
|
+
const res = await fetch(url);
|
|
556
|
+
if (!res.ok) {
|
|
557
|
+
// TODO make error more robust
|
|
558
|
+
throw new Error(`Error fetching the file from the url ${url}`);
|
|
559
|
+
}
|
|
560
|
+
return await res.blob();
|
|
561
|
+
}
|
|
562
|
+
// TODO: Find a way to use blobs with jest
|
|
563
|
+
/* istanbul ignore next */
|
|
564
|
+
/**
|
|
565
|
+
* Gets the file data with the blob from the given File Data.
|
|
566
|
+
*
|
|
567
|
+
* @param data - The File Data to get the file data with blob from.
|
|
568
|
+
* @returns FileDataWithFile.
|
|
569
|
+
*/
|
|
570
|
+
static async getFileData(data) {
|
|
571
|
+
if (data.file) {
|
|
572
|
+
return {
|
|
573
|
+
file: data.file,
|
|
574
|
+
name: data.name,
|
|
575
|
+
url: data.url,
|
|
576
|
+
type: data.type,
|
|
577
|
+
size: data.size
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
return {
|
|
582
|
+
file: await FileUtilities.getFileFromUrl(data.url),
|
|
583
|
+
name: data.name,
|
|
584
|
+
url: data.url,
|
|
585
|
+
type: data.type,
|
|
586
|
+
size: data.size
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Checks if the given file has a valid mime type.
|
|
592
|
+
*
|
|
593
|
+
* @param type - The type of the file to check.
|
|
594
|
+
* @param allowedMimeTypes - The allowed mime types.
|
|
595
|
+
* @returns Whether or not the given file has a valid mime type.
|
|
596
|
+
*/
|
|
597
|
+
static isMimeTypeValid(type, allowedMimeTypes) {
|
|
598
|
+
if (allowedMimeTypes.includes('*')) {
|
|
599
|
+
return true;
|
|
600
|
+
}
|
|
601
|
+
for (const t of allowedMimeTypes) {
|
|
602
|
+
if (t === type) {
|
|
603
|
+
return true;
|
|
604
|
+
}
|
|
605
|
+
if (t.endsWith('*') && type.startsWith(t.split('*')[0])) {
|
|
606
|
+
return true;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
return false;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Transform the given value to Megabytes.
|
|
613
|
+
*
|
|
614
|
+
* @param value - The original value.
|
|
615
|
+
* @param unit - If the value is B, KB or GB.
|
|
616
|
+
* @returns The given value as bytes.
|
|
617
|
+
*/
|
|
618
|
+
static transformToMegaBytes(value, unit) {
|
|
619
|
+
const bytes = this.transformToBytes(LodashUtilities.cloneDeep(value), unit);
|
|
620
|
+
return bytes / 1000000;
|
|
621
|
+
}
|
|
622
|
+
static transformToBytes(value, unit) {
|
|
623
|
+
switch (unit) {
|
|
624
|
+
case 'B':
|
|
625
|
+
return value;
|
|
626
|
+
case 'KB':
|
|
627
|
+
return value * 1000;
|
|
628
|
+
case 'GB':
|
|
629
|
+
return value * 1000000000;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
338
632
|
}
|
|
339
633
|
|
|
340
634
|
/**
|
|
@@ -373,6 +667,26 @@ class EntityUtilities {
|
|
|
373
667
|
}
|
|
374
668
|
return res;
|
|
375
669
|
}
|
|
670
|
+
/**
|
|
671
|
+
* Gets all properties on the given entity which are files.
|
|
672
|
+
*
|
|
673
|
+
* @param entity - The entity to check for file properties.
|
|
674
|
+
* @param omit - Whether to leave out values that are omitted for create or delete.
|
|
675
|
+
* @returns The keys of all file properties on the given entity.
|
|
676
|
+
*/
|
|
677
|
+
static getFileProperties(entity, omit) {
|
|
678
|
+
const res = [];
|
|
679
|
+
for (const key of EntityUtilities.keysOf(entity)) {
|
|
680
|
+
const type = EntityUtilities.getPropertyType(entity, key);
|
|
681
|
+
if (type === DecoratorTypes.FILE_DEFAULT || type === DecoratorTypes.FILE_IMAGE) {
|
|
682
|
+
const metadata = EntityUtilities.getPropertyMetadata(entity, key);
|
|
683
|
+
if (!(metadata.omitForCreate && omit === 'create') && !(metadata.omitForUpdate && omit === 'update')) {
|
|
684
|
+
res.push(key);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
return res;
|
|
689
|
+
}
|
|
376
690
|
/**
|
|
377
691
|
* Gets the metadata included in an property.
|
|
378
692
|
*
|
|
@@ -385,16 +699,11 @@ class EntityUtilities {
|
|
|
385
699
|
static getPropertyMetadata(entity, propertyKey,
|
|
386
700
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
387
701
|
type) {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
if (!metadata) {
|
|
391
|
-
throw new Error(`Could not find metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
|
|
392
|
-
}
|
|
393
|
-
return metadata;
|
|
394
|
-
}
|
|
395
|
-
catch (error) {
|
|
702
|
+
const metadata = ReflectUtilities.getMetadata('metadata', entity, propertyKey);
|
|
703
|
+
if (metadata == null) {
|
|
396
704
|
throw new Error(`Could not find metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
|
|
397
705
|
}
|
|
706
|
+
return metadata;
|
|
398
707
|
}
|
|
399
708
|
/**
|
|
400
709
|
* Gets the type of the property-metadata.
|
|
@@ -406,8 +715,8 @@ class EntityUtilities {
|
|
|
406
715
|
*/
|
|
407
716
|
static getPropertyType(entity, propertyKey) {
|
|
408
717
|
try {
|
|
409
|
-
const propertyType =
|
|
410
|
-
if (
|
|
718
|
+
const propertyType = ReflectUtilities.getMetadata('type', entity, propertyKey);
|
|
719
|
+
if (propertyType == null) {
|
|
411
720
|
throw new Error(`Could not find type metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
|
|
412
721
|
}
|
|
413
722
|
return propertyType;
|
|
@@ -428,12 +737,10 @@ class EntityUtilities {
|
|
|
428
737
|
static new(target, entity) {
|
|
429
738
|
for (const key in target) {
|
|
430
739
|
const type = EntityUtilities.getPropertyType(target, key);
|
|
431
|
-
|
|
432
|
-
let value = entity ? Reflect.get(entity, key) : undefined;
|
|
740
|
+
let value = entity ? ReflectUtilities.get(entity, key) : undefined;
|
|
433
741
|
switch (type) {
|
|
434
742
|
case DecoratorTypes.OBJECT:
|
|
435
743
|
const objectMetadata = EntityUtilities.getPropertyMetadata(target, key, DecoratorTypes.OBJECT);
|
|
436
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
437
744
|
value = new objectMetadata.EntityClass(value);
|
|
438
745
|
break;
|
|
439
746
|
case DecoratorTypes.ARRAY:
|
|
@@ -451,7 +758,7 @@ class EntityUtilities {
|
|
|
451
758
|
default:
|
|
452
759
|
break;
|
|
453
760
|
}
|
|
454
|
-
|
|
761
|
+
ReflectUtilities.set(target, key, value);
|
|
455
762
|
}
|
|
456
763
|
}
|
|
457
764
|
/**
|
|
@@ -488,37 +795,52 @@ class EntityUtilities {
|
|
|
488
795
|
if (metadata.omitForUpdate && omit === 'update') {
|
|
489
796
|
return true;
|
|
490
797
|
}
|
|
491
|
-
if (metadata.required &&
|
|
798
|
+
if (metadata.required && entity[key] == null) {
|
|
492
799
|
return false;
|
|
493
800
|
}
|
|
494
801
|
switch (type) {
|
|
495
802
|
case DecoratorTypes.BOOLEAN_DROPDOWN:
|
|
803
|
+
break;
|
|
496
804
|
case DecoratorTypes.BOOLEAN_CHECKBOX:
|
|
497
805
|
case DecoratorTypes.BOOLEAN_TOGGLE:
|
|
498
|
-
|
|
806
|
+
const entityBoolean = entity[key];
|
|
807
|
+
const booleanMetadata = metadata;
|
|
808
|
+
if (!EntityUtilities.isBooleanValid(entityBoolean, booleanMetadata)) {
|
|
809
|
+
return false;
|
|
810
|
+
}
|
|
811
|
+
break;
|
|
499
812
|
case DecoratorTypes.STRING_DROPDOWN:
|
|
500
|
-
|
|
813
|
+
break;
|
|
501
814
|
case DecoratorTypes.STRING:
|
|
502
815
|
case DecoratorTypes.STRING_AUTOCOMPLETE:
|
|
503
816
|
const entityString = entity[key];
|
|
504
817
|
const stringMetadata = metadata;
|
|
505
|
-
if (!
|
|
818
|
+
if (!EntityUtilities.isStringValid(entityString, stringMetadata)) {
|
|
506
819
|
return false;
|
|
507
820
|
}
|
|
508
821
|
break;
|
|
509
822
|
case DecoratorTypes.STRING_TEXTBOX:
|
|
510
823
|
const entityTextbox = entity[key];
|
|
511
824
|
const textboxMetadata = metadata;
|
|
512
|
-
if (!
|
|
825
|
+
if (!EntityUtilities.isTextboxValid(entityTextbox, textboxMetadata)) {
|
|
826
|
+
return false;
|
|
827
|
+
}
|
|
828
|
+
break;
|
|
829
|
+
case DecoratorTypes.STRING_PASSWORD:
|
|
830
|
+
const entityPassword = entity[key];
|
|
831
|
+
const passwordMetadata = metadata;
|
|
832
|
+
const confirmPassword = ReflectUtilities.getMetadata('confirmPassword', entity, key);
|
|
833
|
+
if (!EntityUtilities.isPasswordValid(entityPassword, passwordMetadata, confirmPassword)) {
|
|
513
834
|
return false;
|
|
514
835
|
}
|
|
515
836
|
break;
|
|
516
837
|
case DecoratorTypes.NUMBER_DROPDOWN:
|
|
517
838
|
return true;
|
|
518
839
|
case DecoratorTypes.NUMBER:
|
|
840
|
+
case DecoratorTypes.NUMBER_SLIDER:
|
|
519
841
|
const entityNumber = entity[key];
|
|
520
842
|
const numberMetadata = metadata;
|
|
521
|
-
if (!
|
|
843
|
+
if (!EntityUtilities.isNumberValid(entityNumber, numberMetadata)) {
|
|
522
844
|
return false;
|
|
523
845
|
}
|
|
524
846
|
break;
|
|
@@ -532,6 +854,9 @@ class EntityUtilities {
|
|
|
532
854
|
break;
|
|
533
855
|
case DecoratorTypes.ARRAY_STRING_CHIPS:
|
|
534
856
|
case DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS:
|
|
857
|
+
case DecoratorTypes.ARRAY_DATE:
|
|
858
|
+
case DecoratorTypes.ARRAY_DATE_TIME:
|
|
859
|
+
case DecoratorTypes.ARRAY_DATE_RANGE:
|
|
535
860
|
case DecoratorTypes.ARRAY:
|
|
536
861
|
const entityArray = entity[key];
|
|
537
862
|
const arrayMetadata = metadata;
|
|
@@ -542,21 +867,36 @@ class EntityUtilities {
|
|
|
542
867
|
case DecoratorTypes.DATE:
|
|
543
868
|
const entityDate = new Date(entity[key]);
|
|
544
869
|
const dateMetadata = metadata;
|
|
545
|
-
if (!
|
|
870
|
+
if (!EntityUtilities.isDateValid(entityDate, dateMetadata)) {
|
|
546
871
|
return false;
|
|
547
872
|
}
|
|
548
873
|
break;
|
|
549
874
|
case DecoratorTypes.DATE_RANGE:
|
|
550
|
-
const entityDateRange = cloneDeep(entity[key]);
|
|
875
|
+
const entityDateRange = LodashUtilities.cloneDeep(entity[key]);
|
|
551
876
|
const dateRangeMetadata = metadata;
|
|
552
|
-
if (!
|
|
877
|
+
if (!EntityUtilities.isDateRangeValid(entityDateRange, dateRangeMetadata)) {
|
|
553
878
|
return false;
|
|
554
879
|
}
|
|
555
880
|
break;
|
|
556
881
|
case DecoratorTypes.DATE_TIME:
|
|
557
882
|
const entityDateTime = new Date(entity[key]);
|
|
558
883
|
const dateTimeMetadata = metadata;
|
|
559
|
-
if (!
|
|
884
|
+
if (!EntityUtilities.isDateTimeValid(entityDateTime, dateTimeMetadata)) {
|
|
885
|
+
return false;
|
|
886
|
+
}
|
|
887
|
+
break;
|
|
888
|
+
case DecoratorTypes.FILE_DEFAULT:
|
|
889
|
+
case DecoratorTypes.FILE_IMAGE:
|
|
890
|
+
const entityFile = entity[key];
|
|
891
|
+
const entityFileMetadata = metadata;
|
|
892
|
+
if (!EntityUtilities.isFileDataValid(entityFile, entityFileMetadata)) {
|
|
893
|
+
return false;
|
|
894
|
+
}
|
|
895
|
+
break;
|
|
896
|
+
case DecoratorTypes.CUSTOM:
|
|
897
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
898
|
+
const customMetadata = metadata;
|
|
899
|
+
if (!customMetadata.isValid(entity[key], omit)) {
|
|
560
900
|
return false;
|
|
561
901
|
}
|
|
562
902
|
break;
|
|
@@ -565,6 +905,12 @@ class EntityUtilities {
|
|
|
565
905
|
}
|
|
566
906
|
return true;
|
|
567
907
|
}
|
|
908
|
+
static isBooleanValid(value, metadata) {
|
|
909
|
+
if (metadata.required && !value) {
|
|
910
|
+
return false;
|
|
911
|
+
}
|
|
912
|
+
return true;
|
|
913
|
+
}
|
|
568
914
|
static isStringValid(value, metadata) {
|
|
569
915
|
if (metadata.maxLength && value.length > metadata.maxLength) {
|
|
570
916
|
return false;
|
|
@@ -586,6 +932,21 @@ class EntityUtilities {
|
|
|
586
932
|
}
|
|
587
933
|
return true;
|
|
588
934
|
}
|
|
935
|
+
static isPasswordValid(value, metadata, confirmPassword) {
|
|
936
|
+
if (value !== confirmPassword) {
|
|
937
|
+
return false;
|
|
938
|
+
}
|
|
939
|
+
if (metadata.maxLength && value.length > metadata.maxLength) {
|
|
940
|
+
return false;
|
|
941
|
+
}
|
|
942
|
+
if (metadata.minLength && value.length < metadata.minLength) {
|
|
943
|
+
return false;
|
|
944
|
+
}
|
|
945
|
+
if (metadata.regex && !value.match(metadata.regex)) {
|
|
946
|
+
return false;
|
|
947
|
+
}
|
|
948
|
+
return true;
|
|
949
|
+
}
|
|
589
950
|
static isNumberValid(value, metadata) {
|
|
590
951
|
if (metadata.max && value > metadata.max) {
|
|
591
952
|
return false;
|
|
@@ -608,8 +969,13 @@ class EntityUtilities {
|
|
|
608
969
|
return true;
|
|
609
970
|
}
|
|
610
971
|
static isDateRangeValid(value, metadata) {
|
|
611
|
-
if (metadata.required
|
|
612
|
-
|
|
972
|
+
if (metadata.required) {
|
|
973
|
+
if (!value.start) {
|
|
974
|
+
return false;
|
|
975
|
+
}
|
|
976
|
+
if (!value.end) {
|
|
977
|
+
return false;
|
|
978
|
+
}
|
|
613
979
|
}
|
|
614
980
|
value.start = new Date(value.start);
|
|
615
981
|
value.end = new Date(value.end);
|
|
@@ -679,6 +1045,27 @@ class EntityUtilities {
|
|
|
679
1045
|
}
|
|
680
1046
|
return true;
|
|
681
1047
|
}
|
|
1048
|
+
static isFileDataValid(value, metadata) {
|
|
1049
|
+
const files = metadata.multiple ? value : [value];
|
|
1050
|
+
let fileSizeTotal = 0;
|
|
1051
|
+
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
1052
|
+
for (let i = 0; i < files.length; i++) {
|
|
1053
|
+
if (!files[i].name || !files[i].file && !files[i].url) {
|
|
1054
|
+
return false;
|
|
1055
|
+
}
|
|
1056
|
+
if (!FileUtilities.isMimeTypeValid(files[i].type, metadata.allowedMimeTypes)) {
|
|
1057
|
+
return false;
|
|
1058
|
+
}
|
|
1059
|
+
if (FileUtilities.transformToMegaBytes(files[i].size, 'B') > metadata.maxSize) {
|
|
1060
|
+
return false;
|
|
1061
|
+
}
|
|
1062
|
+
fileSizeTotal += files[i].size;
|
|
1063
|
+
if (FileUtilities.transformToMegaBytes(fileSizeTotal, 'B') > metadata.maxSizeTotal) {
|
|
1064
|
+
return false;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
return true;
|
|
1068
|
+
}
|
|
682
1069
|
/**
|
|
683
1070
|
* Checks if an entity is "dirty" (if its values have changed).
|
|
684
1071
|
*
|
|
@@ -686,19 +1073,21 @@ class EntityUtilities {
|
|
|
686
1073
|
* @param entityPriorChanges - The entity before the changes.
|
|
687
1074
|
* @returns Whether or not the entity is dirty.
|
|
688
1075
|
*/
|
|
689
|
-
static
|
|
1076
|
+
static async isDirty(entity, entityPriorChanges) {
|
|
690
1077
|
if (!entityPriorChanges) {
|
|
691
1078
|
return false;
|
|
692
1079
|
}
|
|
693
1080
|
else {
|
|
694
|
-
const differences =
|
|
1081
|
+
const differences = await EntityUtilities.differencesForDirty(entity, entityPriorChanges);
|
|
695
1082
|
return differences.length ? true : false;
|
|
696
1083
|
}
|
|
697
1084
|
}
|
|
698
|
-
static differencesForDirty(entity, entityPriorChanges) {
|
|
1085
|
+
static async differencesForDirty(entity, entityPriorChanges) {
|
|
699
1086
|
const res = [];
|
|
700
1087
|
for (const key in entity) {
|
|
701
|
-
|
|
1088
|
+
const metadata = EntityUtilities.getPropertyMetadata(entity, key);
|
|
1089
|
+
const type = EntityUtilities.getPropertyType(entity, key);
|
|
1090
|
+
if (!(await EntityUtilities.isEqual(entity[key], entityPriorChanges[key], metadata, type))) {
|
|
702
1091
|
res.push({
|
|
703
1092
|
key: key,
|
|
704
1093
|
before: entityPriorChanges[key],
|
|
@@ -715,48 +1104,121 @@ class EntityUtilities {
|
|
|
715
1104
|
* @param entityPriorChanges - The second entity to compare.
|
|
716
1105
|
* @returns The difference between the two Entities in form of a Partial.
|
|
717
1106
|
*/
|
|
718
|
-
static difference(entity, entityPriorChanges) {
|
|
1107
|
+
static async difference(entity, entityPriorChanges) {
|
|
719
1108
|
const res = {};
|
|
720
1109
|
for (const key in entity) {
|
|
721
|
-
|
|
1110
|
+
const metadata = EntityUtilities.getPropertyMetadata(entity, key);
|
|
1111
|
+
const type = EntityUtilities.getPropertyType(entity, key);
|
|
1112
|
+
if (!(await EntityUtilities.isEqual(entity[key], entityPriorChanges[key], metadata, type))) {
|
|
722
1113
|
res[key] = entity[key];
|
|
723
1114
|
}
|
|
724
1115
|
}
|
|
725
1116
|
return res;
|
|
726
1117
|
}
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
1118
|
+
/**
|
|
1119
|
+
* Checks if two given values are equal.
|
|
1120
|
+
* It uses the isEqual method from LodashUtilities and extends it with functionality regarding Dates.
|
|
1121
|
+
*
|
|
1122
|
+
* @param value - The updated value.
|
|
1123
|
+
* @param valuePriorChanges - The value before any changes.
|
|
1124
|
+
* @param metadata - The metadata of the property.
|
|
1125
|
+
* @param type - The type of the property.
|
|
1126
|
+
* @returns Whether or not the given values are equal.
|
|
1127
|
+
*/
|
|
1128
|
+
static async isEqual(value, valuePriorChanges, metadata, type) {
|
|
1129
|
+
switch (type) {
|
|
1130
|
+
case DecoratorTypes.DATE_RANGE:
|
|
1131
|
+
return EntityUtilities.isEqualDateRange(value, valuePriorChanges, metadata.filter);
|
|
1132
|
+
case DecoratorTypes.DATE:
|
|
1133
|
+
return EntityUtilities.isEqualDate(value, valuePriorChanges);
|
|
1134
|
+
case DecoratorTypes.DATE_TIME:
|
|
1135
|
+
return EntityUtilities.isEqualDateTime(value, valuePriorChanges);
|
|
1136
|
+
case DecoratorTypes.ARRAY_DATE:
|
|
1137
|
+
case DecoratorTypes.ARRAY_DATE_TIME:
|
|
1138
|
+
return EntityUtilities.isEqualArrayDate(value, valuePriorChanges);
|
|
1139
|
+
case DecoratorTypes.ARRAY_DATE_RANGE:
|
|
1140
|
+
return EntityUtilities.isEqualArrayDateRange(value, valuePriorChanges, metadata.filter);
|
|
1141
|
+
case DecoratorTypes.FILE_IMAGE:
|
|
1142
|
+
case DecoratorTypes.FILE_DEFAULT:
|
|
1143
|
+
return EntityUtilities.isEqualFile(value, valuePriorChanges, metadata.multiple);
|
|
1144
|
+
case DecoratorTypes.CUSTOM:
|
|
1145
|
+
// eslint-disable-next-line max-len, @typescript-eslint/no-explicit-any
|
|
1146
|
+
return EntityUtilities.isEqualCustom(value, valuePriorChanges, metadata);
|
|
1147
|
+
default:
|
|
1148
|
+
return LodashUtilities.isEqual(value, valuePriorChanges);
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
static isEqualArrayDate(value, valuePriorChanges) {
|
|
1152
|
+
const newValue = value.map(v => new Date(v)).sort();
|
|
1153
|
+
const newValuePriorChanges = valuePriorChanges.map(v => new Date(v)).sort();
|
|
1154
|
+
return LodashUtilities.isEqual(newValue, newValuePriorChanges);
|
|
1155
|
+
}
|
|
1156
|
+
static isEqualArrayDateRange(value, valuePriorChanges, filter) {
|
|
1157
|
+
const dateRanges = value.sort();
|
|
1158
|
+
const dateRangesPriorChanges = valuePriorChanges.sort();
|
|
1159
|
+
if (dateRanges.length !== dateRangesPriorChanges.length) {
|
|
1160
|
+
return false;
|
|
1161
|
+
}
|
|
1162
|
+
for (let i = 0; i < dateRanges.length; i++) {
|
|
1163
|
+
if (!EntityUtilities.isEqualDateRange(dateRanges[i], dateRangesPriorChanges[i], filter)) {
|
|
1164
|
+
return false;
|
|
755
1165
|
}
|
|
756
|
-
catch (error) { }
|
|
757
|
-
;
|
|
758
1166
|
}
|
|
759
|
-
return
|
|
1167
|
+
return true;
|
|
1168
|
+
}
|
|
1169
|
+
static isEqualDateTime(value, valuePriorChanges) {
|
|
1170
|
+
const date = new Date(value);
|
|
1171
|
+
const datePriorChanges = new Date(valuePriorChanges);
|
|
1172
|
+
return LodashUtilities.isEqual(date, datePriorChanges);
|
|
1173
|
+
}
|
|
1174
|
+
static isEqualDate(value, valuePriorChanges) {
|
|
1175
|
+
const date = new Date(value);
|
|
1176
|
+
const datePriorChanges = new Date(valuePriorChanges);
|
|
1177
|
+
date.setHours(0, 0, 0, 0);
|
|
1178
|
+
datePriorChanges.setHours(0, 0, 0, 0);
|
|
1179
|
+
return LodashUtilities.isEqual(date, datePriorChanges);
|
|
1180
|
+
}
|
|
1181
|
+
static isEqualDateRange(value, valuePriorChanges, filter) {
|
|
1182
|
+
const dateRange = LodashUtilities.cloneDeep(value);
|
|
1183
|
+
dateRange.start = new Date(value.start);
|
|
1184
|
+
dateRange.end = new Date(value.end);
|
|
1185
|
+
dateRange.values = DateUtilities.getDatesBetween(dateRange.start, dateRange.end, filter);
|
|
1186
|
+
const dateRangePriorChanges = LodashUtilities.cloneDeep(valuePriorChanges);
|
|
1187
|
+
dateRangePriorChanges.start = new Date(valuePriorChanges.start);
|
|
1188
|
+
dateRangePriorChanges.end = new Date(valuePriorChanges.end);
|
|
1189
|
+
dateRangePriorChanges.values = DateUtilities.getDatesBetween(dateRangePriorChanges.start, dateRangePriorChanges.end, filter);
|
|
1190
|
+
return LodashUtilities.isEqual(dateRange, dateRangePriorChanges);
|
|
1191
|
+
}
|
|
1192
|
+
// TODO: Find a way to use blobs with jest
|
|
1193
|
+
/* istanbul ignore next */
|
|
1194
|
+
static async isEqualFile(value, valuePriorChanges, multiple) {
|
|
1195
|
+
const files = multiple ? value.sort() : [value].sort();
|
|
1196
|
+
const filesPriorChanges = multiple ? valuePriorChanges.sort() : [valuePriorChanges].sort();
|
|
1197
|
+
if (files.length !== filesPriorChanges.length) {
|
|
1198
|
+
return false;
|
|
1199
|
+
}
|
|
1200
|
+
for (let i = 0; i < files.length; i++) {
|
|
1201
|
+
// checks this before actually getting any files due to performance reasons.
|
|
1202
|
+
if (!LodashUtilities.isEqual(files[i]?.name, filesPriorChanges[i]?.name)
|
|
1203
|
+
|| !LodashUtilities.isEqual(files[i]?.url, filesPriorChanges[i]?.url)) {
|
|
1204
|
+
return false;
|
|
1205
|
+
}
|
|
1206
|
+
files[i] = filesPriorChanges[i].file && !files[i].file ? await FileUtilities.getFileData(files[i]) : files[i];
|
|
1207
|
+
// eslint-disable-next-line max-len
|
|
1208
|
+
filesPriorChanges[i] = files[i].file && !filesPriorChanges[i].file ? await FileUtilities.getFileData(filesPriorChanges[i]) : filesPriorChanges[i];
|
|
1209
|
+
if (!LodashUtilities.isEqual(await files[i].file?.text(), await filesPriorChanges[i].file?.text())) {
|
|
1210
|
+
return false;
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
return true;
|
|
1214
|
+
}
|
|
1215
|
+
static isEqualCustom(value, valuePriorChanges,
|
|
1216
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1217
|
+
metadata) {
|
|
1218
|
+
if (!metadata.isEqual(value, valuePriorChanges, metadata)) {
|
|
1219
|
+
return false;
|
|
1220
|
+
}
|
|
1221
|
+
return true;
|
|
760
1222
|
}
|
|
761
1223
|
/**
|
|
762
1224
|
* Compare function for sorting entity keys by their order value.
|
|
@@ -778,7 +1240,7 @@ class EntityUtilities {
|
|
|
778
1240
|
else if (metadataB.position.order === -1) {
|
|
779
1241
|
return -1;
|
|
780
1242
|
}
|
|
781
|
-
return
|
|
1243
|
+
return metadataA.position.order - metadataB.position.order;
|
|
782
1244
|
}
|
|
783
1245
|
/**
|
|
784
1246
|
* Gets the bootstrap column values for "lg", "md", "sm".
|
|
@@ -807,7 +1269,7 @@ class EntityUtilities {
|
|
|
807
1269
|
*/
|
|
808
1270
|
static resetChangesOnEntity(entity, entityPriorChanges) {
|
|
809
1271
|
for (const key in entityPriorChanges) {
|
|
810
|
-
|
|
1272
|
+
ReflectUtilities.set(entity, key, ReflectUtilities.get(entityPriorChanges, key));
|
|
811
1273
|
}
|
|
812
1274
|
}
|
|
813
1275
|
/**
|
|
@@ -821,17 +1283,17 @@ class EntityUtilities {
|
|
|
821
1283
|
static getEntityRows(entity, hideOmitForCreate = false, hideOmitForEdit = false) {
|
|
822
1284
|
const res = [];
|
|
823
1285
|
const keys = EntityUtilities.keysOf(entity, hideOmitForCreate, hideOmitForEdit);
|
|
824
|
-
const numberOfRows =
|
|
1286
|
+
const numberOfRows = EntityUtilities.getNumberOfRows(keys, entity);
|
|
825
1287
|
for (let i = 1; i <= numberOfRows; i++) {
|
|
826
1288
|
const row = {
|
|
827
1289
|
row: i,
|
|
828
|
-
keys:
|
|
1290
|
+
keys: EntityUtilities.getKeysForRow(keys, entity, i)
|
|
829
1291
|
};
|
|
830
1292
|
res.push(row);
|
|
831
1293
|
}
|
|
832
1294
|
const lastRow = {
|
|
833
1295
|
row: numberOfRows + 1,
|
|
834
|
-
keys:
|
|
1296
|
+
keys: EntityUtilities.getKeysForRow(keys, entity, -1)
|
|
835
1297
|
};
|
|
836
1298
|
res.push(lastRow);
|
|
837
1299
|
return res;
|
|
@@ -855,7 +1317,7 @@ class EntityUtilities {
|
|
|
855
1317
|
* @returns An array of keys of the entity.
|
|
856
1318
|
*/
|
|
857
1319
|
static keysOf(entity, hideOmitForCreate = false, hideOmitForEdit = false) {
|
|
858
|
-
let keys =
|
|
1320
|
+
let keys = ReflectUtilities.ownKeys(entity);
|
|
859
1321
|
if (hideOmitForCreate) {
|
|
860
1322
|
const omitForCreateKeys = EntityUtilities.getOmitForCreate(entity);
|
|
861
1323
|
keys = keys.filter(k => !omitForCreateKeys.includes(k));
|
|
@@ -873,19 +1335,39 @@ EntityUtilities.construct = EntityUtilities.new;
|
|
|
873
1335
|
EntityUtilities.build = EntityUtilities.new;
|
|
874
1336
|
|
|
875
1337
|
/**
|
|
876
|
-
* A
|
|
877
|
-
* Offers basic CRUD-functionality.
|
|
878
|
-
* You should create a service for every Entity you have.
|
|
879
|
-
* If you extend from this you need to make sure that the extended Service can be injected.
|
|
1338
|
+
* A base Entity class with a builtin id.
|
|
880
1339
|
*/
|
|
881
|
-
class
|
|
882
|
-
constructor(
|
|
883
|
-
this
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
1340
|
+
class Entity {
|
|
1341
|
+
constructor(entity) {
|
|
1342
|
+
EntityUtilities.new(this, entity);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
__decorate([
|
|
1346
|
+
string({
|
|
1347
|
+
omitForCreate: true,
|
|
1348
|
+
omitForUpdate: true,
|
|
1349
|
+
display: false,
|
|
1350
|
+
displayStyle: 'line',
|
|
1351
|
+
displayName: 'ID',
|
|
1352
|
+
required: true
|
|
1353
|
+
}),
|
|
1354
|
+
__metadata("design:type", String)
|
|
1355
|
+
], Entity.prototype, "id", void 0);
|
|
1356
|
+
|
|
1357
|
+
/**
|
|
1358
|
+
* A generic EntityService class.
|
|
1359
|
+
* Offers basic CRUD-functionality.
|
|
1360
|
+
* You should create a service for every Entity you have.
|
|
1361
|
+
* If you extend from this you need to make sure that the extended Service can be injected.
|
|
1362
|
+
*/
|
|
1363
|
+
class EntityService {
|
|
1364
|
+
constructor(http) {
|
|
1365
|
+
this.http = http;
|
|
1366
|
+
/**
|
|
1367
|
+
* The key which holds the id value.
|
|
1368
|
+
*
|
|
1369
|
+
* @default 'id'
|
|
1370
|
+
*/
|
|
889
1371
|
this.idKey = 'id';
|
|
890
1372
|
/**
|
|
891
1373
|
* A subject of all the entity values.
|
|
@@ -909,7 +1391,54 @@ class EntityService {
|
|
|
909
1391
|
* @returns A Promise of the created entity.
|
|
910
1392
|
*/
|
|
911
1393
|
async create(entity) {
|
|
912
|
-
const body = omit(entity, EntityUtilities.getOmitForCreate(entity));
|
|
1394
|
+
const body = LodashUtilities.omit(entity, EntityUtilities.getOmitForCreate(entity));
|
|
1395
|
+
const filePropertyKeys = EntityUtilities.getFileProperties(entity);
|
|
1396
|
+
if (!filePropertyKeys.length) {
|
|
1397
|
+
return await this.createWithJson(body);
|
|
1398
|
+
}
|
|
1399
|
+
else {
|
|
1400
|
+
return await this.createWithFormData(body, filePropertyKeys, entity);
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
// TODO: Find a way to use blobs with jest
|
|
1404
|
+
/* istanbul ignore next */
|
|
1405
|
+
/**
|
|
1406
|
+
* Creates the entity with form data when the entity contains files in contrast to creating it with a normal json body.
|
|
1407
|
+
* All file values are stored inside their respective property key and their name.
|
|
1408
|
+
* Form data is able to handle setting multiple files to the same key.
|
|
1409
|
+
*
|
|
1410
|
+
* @param body - The body Of the request.
|
|
1411
|
+
* @param filePropertyKeys - All property keys that are files and need to be added to the form data.
|
|
1412
|
+
* @param entity - The entity to create. This is needed in addition to the body because the body doesn't contain any metadata.
|
|
1413
|
+
* @returns The created entity from the server.
|
|
1414
|
+
*/
|
|
1415
|
+
async createWithFormData(body, filePropertyKeys, entity) {
|
|
1416
|
+
const formData = new FormData();
|
|
1417
|
+
formData.append('body', JSON.stringify(LodashUtilities.omit(body, filePropertyKeys)));
|
|
1418
|
+
for (const key of filePropertyKeys) {
|
|
1419
|
+
if (EntityUtilities.getPropertyMetadata(entity, key, DecoratorTypes.FILE_DEFAULT).multiple) {
|
|
1420
|
+
const fileDataValues = body[key];
|
|
1421
|
+
for (const value of fileDataValues) {
|
|
1422
|
+
formData.append(key, (await FileUtilities.getFileData(value)).file, value.name);
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
else {
|
|
1426
|
+
const fileData = body[key];
|
|
1427
|
+
formData.append(key, (await FileUtilities.getFileData(fileData)).file, fileData.name);
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
const e = await firstValueFrom(this.http.post(this.baseUrl, formData));
|
|
1431
|
+
this.entities.push(e);
|
|
1432
|
+
this.entitiesSubject.next(this.entities);
|
|
1433
|
+
return e;
|
|
1434
|
+
}
|
|
1435
|
+
/**
|
|
1436
|
+
* Creates the entity with a normal json body in contrast to creating it with form data when the entity contains files.
|
|
1437
|
+
*
|
|
1438
|
+
* @param body - The body Of the request.
|
|
1439
|
+
* @returns The created entity from the server.
|
|
1440
|
+
*/
|
|
1441
|
+
async createWithJson(body) {
|
|
913
1442
|
const e = await firstValueFrom(this.http.post(this.baseUrl, body));
|
|
914
1443
|
this.entities.push(e);
|
|
915
1444
|
this.entitiesSubject.next(this.entities);
|
|
@@ -934,9 +1463,57 @@ class EntityService {
|
|
|
934
1463
|
* It Is used to get changed values and only update them instead of sending the whole entity data.
|
|
935
1464
|
*/
|
|
936
1465
|
async update(entity, entityPriorChanges) {
|
|
937
|
-
const
|
|
938
|
-
const
|
|
939
|
-
|
|
1466
|
+
const body = LodashUtilities.omit(await EntityUtilities.difference(entity, entityPriorChanges), EntityUtilities.getOmitForUpdate(entity));
|
|
1467
|
+
const filePropertyKeys = EntityUtilities.getFileProperties(entityPriorChanges);
|
|
1468
|
+
if (!filePropertyKeys.length) {
|
|
1469
|
+
await this.updateWithJson(body, entityPriorChanges[this.idKey]);
|
|
1470
|
+
}
|
|
1471
|
+
else {
|
|
1472
|
+
await this.updateWithFormData(body, filePropertyKeys, entity, entityPriorChanges[this.idKey]);
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
// TODO: Find a way to use blobs with jest
|
|
1476
|
+
/* istanbul ignore next */
|
|
1477
|
+
/**
|
|
1478
|
+
* Updates the entity with form data when the entity contains files in contrast to creating it with a normal json body.
|
|
1479
|
+
* All file values are stored inside their respective property key and their name.
|
|
1480
|
+
* Form data is able to handle setting multiple files to the same key.
|
|
1481
|
+
*
|
|
1482
|
+
* @param body - The request body. Already contains only properties that have changed.
|
|
1483
|
+
* @param filePropertyKeys - The keys of all properties which are files and need to separately be appended to the form data.
|
|
1484
|
+
* @param entity - The original entity. Is needed to get the metadata of all the files.
|
|
1485
|
+
* @param id - The id of the entity to update.
|
|
1486
|
+
*/
|
|
1487
|
+
async updateWithFormData(body, filePropertyKeys, entity, id) {
|
|
1488
|
+
const formData = new FormData();
|
|
1489
|
+
formData.append('body', JSON.stringify(LodashUtilities.omitBy(body, LodashUtilities.isNil)));
|
|
1490
|
+
for (const key of filePropertyKeys) {
|
|
1491
|
+
if (EntityUtilities.getPropertyMetadata(entity, key, DecoratorTypes.FILE_DEFAULT).multiple) {
|
|
1492
|
+
// eslint-disable-next-line max-len
|
|
1493
|
+
const fileDataValues = body[key];
|
|
1494
|
+
for (const value of fileDataValues) {
|
|
1495
|
+
formData.append(key, (await FileUtilities.getFileData(value)).file, value.name);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
else {
|
|
1499
|
+
// eslint-disable-next-line max-len
|
|
1500
|
+
const fileData = body[key];
|
|
1501
|
+
formData.append(key, (await FileUtilities.getFileData(fileData)).file, fileData.name);
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
const updatedEntity = await firstValueFrom(this.http.patch(`${this.baseUrl}/${id}`, formData));
|
|
1505
|
+
this.entities[this.entities.findIndex(e => e[this.idKey] === id)] = updatedEntity;
|
|
1506
|
+
this.entitiesSubject.next(this.entities);
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* Updates the entity with a normal json body in contrast to updating it with form data when the entity contains files.
|
|
1510
|
+
*
|
|
1511
|
+
* @param body - The body of the Request. Has already removed all unnecessary values.
|
|
1512
|
+
* @param id - The id of the entity to update.
|
|
1513
|
+
*/
|
|
1514
|
+
async updateWithJson(body, id) {
|
|
1515
|
+
const updatedEntity = await firstValueFrom(this.http.patch(`${this.baseUrl}/${id}`, LodashUtilities.omitBy(body, LodashUtilities.isNil)));
|
|
1516
|
+
this.entities[this.entities.findIndex(e => e[this.idKey] === id)] = updatedEntity;
|
|
940
1517
|
this.entitiesSubject.next(this.entities);
|
|
941
1518
|
}
|
|
942
1519
|
/**
|
|
@@ -971,7 +1548,6 @@ class BaseBuilder {
|
|
|
971
1548
|
validateInput(data) {
|
|
972
1549
|
// By default, no validation is done
|
|
973
1550
|
}
|
|
974
|
-
;
|
|
975
1551
|
/**
|
|
976
1552
|
* Sets the value for the given key if no user value was provided.
|
|
977
1553
|
*
|
|
@@ -980,7 +1556,7 @@ class BaseBuilder {
|
|
|
980
1556
|
* @returns The Builder.
|
|
981
1557
|
*/
|
|
982
1558
|
withDefault(key, value) {
|
|
983
|
-
if (
|
|
1559
|
+
if (this.inputData == null || this.inputData[key] == null) {
|
|
984
1560
|
this.data[key] = value;
|
|
985
1561
|
}
|
|
986
1562
|
return this;
|
|
@@ -1018,18 +1594,18 @@ class ConfirmDialogDataBuilder extends BaseBuilder {
|
|
|
1018
1594
|
}
|
|
1019
1595
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
1020
1596
|
generateBaseData(data) {
|
|
1021
|
-
return new ConfirmDialogDataInternal(data?.text
|
|
1597
|
+
return new ConfirmDialogDataInternal(data?.text ?? ['Do you really want to do this?'], data?.type ?? 'default', data?.confirmButtonLabel ?? 'Confirm', data?.cancelButtonLabel ?? 'Cancel', data?.title ?? 'Confirmation', data?.requireConfirmation ?? false, data?.confirmationText);
|
|
1022
1598
|
}
|
|
1023
1599
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
1024
1600
|
validateInput(data) {
|
|
1025
1601
|
if (!data) {
|
|
1026
1602
|
return;
|
|
1027
1603
|
}
|
|
1028
|
-
if (data.requireConfirmation && !data.confirmationText) {
|
|
1604
|
+
if (data.requireConfirmation === true && !data.confirmationText) {
|
|
1029
1605
|
throw new Error(`Missing required Input data "confirmationText".
|
|
1030
1606
|
You can only omit this value when "requireConfirmation" is false.`);
|
|
1031
1607
|
}
|
|
1032
|
-
if (
|
|
1608
|
+
if (data.requireConfirmation !== true && data.confirmationText) {
|
|
1033
1609
|
throw new Error('The "confirmationText" will never be shown because "requireConfirmation" is not set to true');
|
|
1034
1610
|
}
|
|
1035
1611
|
if (data.type === 'info-only' && data.cancelButtonLabel) {
|
|
@@ -1067,10 +1643,10 @@ class NgxMatEntityConfirmDialogComponent {
|
|
|
1067
1643
|
}
|
|
1068
1644
|
}
|
|
1069
1645
|
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 });
|
|
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:
|
|
1646
|
+
NgxMatEntityConfirmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityConfirmDialogComponent, selector: "ngx-mat-entity-confirm-dialog", ngImport: i0, template: "<h2 mat-dialog-title *ngIf=\"data.title\">{{data.title}}</h2>\n\n<mat-dialog-content>\n <p *ngFor=\"let paragraph of data.text\">{{paragraph}}</p>\n <div *ngIf=\"data.requireConfirmation\" class=\"checkbox-wrapper\">\n <mat-checkbox [(ngModel)]=\"confirm\" name=\"confirm\">\n {{data.confirmationText}}\n </mat-checkbox>\n </div>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button *ngIf=\"data.type === 'delete'\" mat-raised-button color=\"warn\" (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel}}\n </button>\n <button *ngIf=\"data.type !== 'delete'\" mat-raised-button (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel}}\n </button>\n <button *ngIf=\"data.type !== 'info-only'\" mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: [".checkbox-wrapper{min-height:50px;display:flex}.checkbox-wrapper>mat-checkbox{align-self:center}mat-dialog-actions{display:flex;justify-content:space-between}\n"], components: [{ type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i6.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: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.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]" }] });
|
|
1071
1647
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityConfirmDialogComponent, decorators: [{
|
|
1072
1648
|
type: Component,
|
|
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"] }]
|
|
1649
|
+
args: [{ selector: 'ngx-mat-entity-confirm-dialog', template: "<h2 mat-dialog-title *ngIf=\"data.title\">{{data.title}}</h2>\n\n<mat-dialog-content>\n <p *ngFor=\"let paragraph of data.text\">{{paragraph}}</p>\n <div *ngIf=\"data.requireConfirmation\" class=\"checkbox-wrapper\">\n <mat-checkbox [(ngModel)]=\"confirm\" name=\"confirm\">\n {{data.confirmationText}}\n </mat-checkbox>\n </div>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button *ngIf=\"data.type === 'delete'\" mat-raised-button color=\"warn\" (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel}}\n </button>\n <button *ngIf=\"data.type !== 'delete'\" mat-raised-button (click)=\"confirmAction()\" [disabled]=\"data.requireConfirmation && !confirm\" class=\"confirm-button\">\n {{data.confirmButtonLabel}}\n </button>\n <button *ngIf=\"data.type !== 'info-only'\" mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: [".checkbox-wrapper{min-height:50px;display:flex}.checkbox-wrapper>mat-checkbox{align-self:center}mat-dialog-actions{display:flex;justify-content:space-between}\n"] }]
|
|
1074
1650
|
}], ctorParameters: function () { return [{ type: i1.MatDialogRef }, { type: undefined, decorators: [{
|
|
1075
1651
|
type: Inject,
|
|
1076
1652
|
args: [MAT_DIALOG_DATA]
|
|
@@ -1153,7 +1729,7 @@ class CreateDialogDataBuilder extends BaseBuilder {
|
|
|
1153
1729
|
.withDefault('text', ['Do you really want to create this entity?'])
|
|
1154
1730
|
.withDefault('title', 'Create')
|
|
1155
1731
|
.getResult();
|
|
1156
|
-
return new CreateDialogDataInternal(data?.title
|
|
1732
|
+
return new CreateDialogDataInternal(data?.title ?? 'Create', data?.createButtonLabel ?? 'Create', data?.cancelButtonLabel ?? 'Cancel', data?.createRequiresConfirmDialog ?? false, confirmCreateDialogData);
|
|
1157
1733
|
}
|
|
1158
1734
|
}
|
|
1159
1735
|
|
|
@@ -1180,181 +1756,1127 @@ class AddArrayItemDialogDataBuilder extends BaseBuilder {
|
|
|
1180
1756
|
.withDefault('createButtonLabel', 'Add')
|
|
1181
1757
|
.withDefault('title', 'Add to array')
|
|
1182
1758
|
.getResult();
|
|
1183
|
-
return new AddArrayItemDialogDataInternal(data.entity, createDialogData, data.getValidationErrorMessage
|
|
1759
|
+
return new AddArrayItemDialogDataInternal(data.entity, createDialogData, data.getValidationErrorMessage ?? getValidationErrorMessage);
|
|
1184
1760
|
}
|
|
1185
1761
|
}
|
|
1186
1762
|
|
|
1187
1763
|
/**
|
|
1188
|
-
* The
|
|
1189
|
-
*
|
|
1764
|
+
* The abstract base class of any ngx-mat-entity input.
|
|
1765
|
+
* Extend from this when implementing your own custom decorator.
|
|
1190
1766
|
*
|
|
1191
|
-
*
|
|
1192
|
-
*
|
|
1193
|
-
* The
|
|
1767
|
+
* It already provides:
|
|
1768
|
+
*
|
|
1769
|
+
* - entity: The entity which the property is on. (type-safe due to the Generic "EntityType")
|
|
1770
|
+
* - key: The key of the property. (type-safe due to the Generic "EntityType")
|
|
1771
|
+
* - getValidationErrorMessage: The function that generates the error message when the input is invalid.
|
|
1772
|
+
* - isReadOnly: Whether or not the input is read only. Can be used to disable elements.
|
|
1773
|
+
* - propertyValue: Just the typed version of the property, its the same as entity[key].
|
|
1774
|
+
* - metadata: The metadata of the property. (type-safe due to the Generic "CustomMetadataType")
|
|
1775
|
+
* - ngOnInit: Gets the metadata for the property, be aware of this when overriding this method.
|
|
1776
|
+
* - emitChange: Should be called when the input has changed. This is needed to trigger validation and dirty checks.
|
|
1194
1777
|
*/
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
this.
|
|
1199
|
-
this.selection = new SelectionModel(true, []);
|
|
1200
|
-
this.DecoratorTypes = DecoratorTypes;
|
|
1201
|
-
this.EntityUtilities = EntityUtilities;
|
|
1202
|
-
this.DateUtilities = DateUtilities;
|
|
1203
|
-
this.defaultDateFilter = () => true;
|
|
1778
|
+
// eslint-disable-next-line max-len
|
|
1779
|
+
class NgxMatEntityBaseInputComponent {
|
|
1780
|
+
constructor() {
|
|
1781
|
+
this.inputChangeEvent = new EventEmitter();
|
|
1204
1782
|
}
|
|
1783
|
+
// eslint-disable-next-line jsdoc/require-returns
|
|
1205
1784
|
/**
|
|
1206
|
-
*
|
|
1207
|
-
*
|
|
1208
|
-
* @param index - The index of the element in the ngFor.
|
|
1209
|
-
* @returns The index.
|
|
1785
|
+
* The property value of entity[key] correctly typed.
|
|
1786
|
+
* Uses getters and setters so that inputs are always linked to the original value.
|
|
1210
1787
|
*/
|
|
1211
|
-
|
|
1212
|
-
return
|
|
1788
|
+
get propertyValue() {
|
|
1789
|
+
return this.entity[this.key];
|
|
1790
|
+
}
|
|
1791
|
+
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
1792
|
+
set propertyValue(value) {
|
|
1793
|
+
this.entity[this.key] = value;
|
|
1213
1794
|
}
|
|
1214
1795
|
ngOnInit() {
|
|
1215
|
-
|
|
1216
|
-
throw new Error('Missing required Input data "entity"');
|
|
1217
|
-
}
|
|
1218
|
-
if (!this.propertyKey) {
|
|
1219
|
-
throw new Error('Missing required Input data "propertyKey"');
|
|
1220
|
-
}
|
|
1221
|
-
this.type = EntityUtilities.getPropertyType(this.entity, this.propertyKey);
|
|
1222
|
-
this.metadata = EntityUtilities.getPropertyMetadata(this.entity, this.propertyKey, this.type);
|
|
1223
|
-
this.metadataDefaultString = this.metadata;
|
|
1224
|
-
this.metadataTextboxString = this.metadata;
|
|
1225
|
-
this.metadataAutocompleteString = this.metadata;
|
|
1226
|
-
this.autocompleteStrings = this.metadataAutocompleteString.autocompleteValues;
|
|
1227
|
-
this.filteredAutocompleteStrings = cloneDeep(this.autocompleteStrings);
|
|
1228
|
-
this.metadataDropdownString = this.metadata;
|
|
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
|
-
}
|
|
1234
|
-
this.metadataDefaultNumber = this.metadata;
|
|
1235
|
-
this.metadataDropdownNumber = this.metadata;
|
|
1236
|
-
this.metadataDefaultObject = this.metadata;
|
|
1237
|
-
this.objectProperty = this.entity[this.propertyKey];
|
|
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]);
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1796
|
+
this.metadata = EntityUtilities.getPropertyMetadata(this.entity, this.key);
|
|
1306
1797
|
}
|
|
1307
1798
|
/**
|
|
1308
|
-
*
|
|
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.
|
|
1799
|
+
* Should emit when the input has changed. This is needed to trigger validation and dirty checks.
|
|
1313
1800
|
*/
|
|
1314
|
-
|
|
1315
|
-
|
|
1801
|
+
emitChange() {
|
|
1802
|
+
this.inputChangeEvent.emit();
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
NgxMatEntityBaseInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityBaseInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1806
|
+
NgxMatEntityBaseInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityBaseInputComponent, selector: "ngx-mat-entity-base-input", inputs: { entity: "entity", key: "key", getValidationErrorMessage: "getValidationErrorMessage", isReadOnly: "isReadOnly" }, outputs: { inputChangeEvent: "inputChangeEvent" }, ngImport: i0, template: '', isInline: true });
|
|
1807
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityBaseInputComponent, decorators: [{
|
|
1808
|
+
type: Component,
|
|
1809
|
+
args: [{
|
|
1810
|
+
selector: 'ngx-mat-entity-base-input',
|
|
1811
|
+
template: ''
|
|
1812
|
+
}]
|
|
1813
|
+
}], propDecorators: { entity: [{
|
|
1814
|
+
type: Input
|
|
1815
|
+
}], key: [{
|
|
1816
|
+
type: Input
|
|
1817
|
+
}], getValidationErrorMessage: [{
|
|
1818
|
+
type: Input
|
|
1819
|
+
}], isReadOnly: [{
|
|
1820
|
+
type: Input
|
|
1821
|
+
}], inputChangeEvent: [{
|
|
1822
|
+
type: Output
|
|
1823
|
+
}] } });
|
|
1824
|
+
|
|
1825
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
1826
|
+
class StringInputComponent extends NgxMatEntityBaseInputComponent {
|
|
1827
|
+
}
|
|
1828
|
+
StringInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1829
|
+
StringInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: StringInputComponent, selector: "string-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n (ngModelChange)=\"emitChange()\"\n [disabled]=\"isReadOnly\"\n >\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i4.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i4.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
1830
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringInputComponent, decorators: [{
|
|
1831
|
+
type: Component,
|
|
1832
|
+
args: [{ selector: 'string-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n (ngModelChange)=\"emitChange()\"\n [disabled]=\"isReadOnly\"\n >\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
1833
|
+
}] });
|
|
1834
|
+
|
|
1835
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
1836
|
+
class StringTextboxInputComponent extends NgxMatEntityBaseInputComponent {
|
|
1837
|
+
}
|
|
1838
|
+
StringTextboxInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringTextboxInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1839
|
+
StringTextboxInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: StringTextboxInputComponent, selector: "string-textbox-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <textarea\n matInput\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"10\"\n [required]=\"metadata.required\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n (ngModelChange)=\"emitChange()\"\n [disabled]=\"isReadOnly\"\n >\n </textarea>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i3$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i4.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
1840
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringTextboxInputComponent, decorators: [{
|
|
1841
|
+
type: Component,
|
|
1842
|
+
args: [{ selector: 'string-textbox-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <textarea\n matInput\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"10\"\n [required]=\"metadata.required\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n (ngModelChange)=\"emitChange()\"\n [disabled]=\"isReadOnly\"\n >\n </textarea>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
1843
|
+
}] });
|
|
1844
|
+
|
|
1845
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
1846
|
+
class StringAutocompleteInputComponent extends NgxMatEntityBaseInputComponent {
|
|
1847
|
+
ngOnInit() {
|
|
1848
|
+
super.ngOnInit();
|
|
1849
|
+
this.autocompleteStrings = this.metadata.autocompleteValues;
|
|
1850
|
+
this.filteredAutocompleteStrings = LodashUtilities.cloneDeep(this.autocompleteStrings);
|
|
1316
1851
|
}
|
|
1317
1852
|
/**
|
|
1318
|
-
*
|
|
1853
|
+
* Dynamically filters the Autocomplete options when the user inputs something.
|
|
1854
|
+
*
|
|
1855
|
+
* @param input - The input of the user.
|
|
1319
1856
|
*/
|
|
1320
|
-
|
|
1321
|
-
if (
|
|
1322
|
-
this.
|
|
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;
|
|
1857
|
+
filterAutocompleteStrings(input) {
|
|
1858
|
+
if (input) {
|
|
1859
|
+
this.filteredAutocompleteStrings = this.autocompleteStrings.filter(s => s.toLowerCase().includes(input.toLowerCase()));
|
|
1326
1860
|
}
|
|
1327
|
-
|
|
1328
|
-
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
StringAutocompleteInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringAutocompleteInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1864
|
+
StringAutocompleteInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: StringAutocompleteInputComponent, selector: "string-autocomplete-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matAutocomplete]=\"auto\"\n (keyup)=\"filterAutocompleteStrings(propertyValue)\"\n [required]=\"metadata.required\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n (ngModelChange)=\"emitChange()\"\n [disabled]=\"isReadOnly\"\n >\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let value of filteredAutocompleteStrings\" [value]=\"value\">\n {{value}}\n </mat-option>\n </mat-autocomplete>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$1.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { type: i3$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i4.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i4.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
1865
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringAutocompleteInputComponent, decorators: [{
|
|
1866
|
+
type: Component,
|
|
1867
|
+
args: [{ selector: 'string-autocomplete-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matAutocomplete]=\"auto\"\n (keyup)=\"filterAutocompleteStrings(propertyValue)\"\n [required]=\"metadata.required\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n (ngModelChange)=\"emitChange()\"\n [disabled]=\"isReadOnly\"\n >\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let value of filteredAutocompleteStrings\" [value]=\"value\">\n {{value}}\n </mat-option>\n </mat-autocomplete>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
1868
|
+
}] });
|
|
1869
|
+
|
|
1870
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
1871
|
+
class StringDropdownInputComponent extends NgxMatEntityBaseInputComponent {
|
|
1872
|
+
}
|
|
1873
|
+
StringDropdownInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringDropdownInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1874
|
+
StringDropdownInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: StringDropdownInputComponent, selector: "string-dropdown-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select (ngModelChange)=\"emitChange()\" [(ngModel)]=\"propertyValue\" [name]=\"key.toString()\" #model=\"ngModel\" [required]=\"metadata.required\" [disabled]=\"isReadOnly\">\n <mat-option *ngFor=\"let value of metadata.dropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
1875
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringDropdownInputComponent, decorators: [{
|
|
1876
|
+
type: Component,
|
|
1877
|
+
args: [{ selector: 'string-dropdown-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select (ngModelChange)=\"emitChange()\" [(ngModel)]=\"propertyValue\" [name]=\"key.toString()\" #model=\"ngModel\" [required]=\"metadata.required\" [disabled]=\"isReadOnly\">\n <mat-option *ngFor=\"let value of metadata.dropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
1878
|
+
}] });
|
|
1879
|
+
|
|
1880
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
1881
|
+
class StringPasswordInputComponent extends NgxMatEntityBaseInputComponent {
|
|
1882
|
+
constructor() {
|
|
1883
|
+
super(...arguments);
|
|
1884
|
+
this.hide = true;
|
|
1885
|
+
this.hideConfirm = true;
|
|
1886
|
+
}
|
|
1887
|
+
ngOnInit() {
|
|
1888
|
+
super.ngOnInit();
|
|
1889
|
+
this.confirmRequired = this.metadata.required;
|
|
1890
|
+
this.confirmPassword = LodashUtilities.cloneDeep(this.propertyValue);
|
|
1891
|
+
ReflectUtilities.defineMetadata('confirmPassword', this.confirmPassword, this.entity, this.key);
|
|
1892
|
+
}
|
|
1893
|
+
passwordInput() {
|
|
1894
|
+
this.confirmRequired = Boolean(this.propertyValue);
|
|
1895
|
+
ReflectUtilities.defineMetadata('confirmPassword', this.confirmPassword, this.entity, this.key);
|
|
1896
|
+
this.emitChange();
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
StringPasswordInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringPasswordInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1900
|
+
StringPasswordInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: StringPasswordInputComponent, selector: "string-password-input", usesInheritance: true, ngImport: i0, template: "<div class=\"password-row\">\n <mat-form-field [class.w-50]=\"metadata.needsConfirmation\" [class.w-100]=\"!metadata.needsConfirmation\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n [type]=\"hide ? 'password' : 'text'\"\n matInput\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n (ngModelChange)=\"passwordInput()\"\n [disabled]=\"isReadOnly\"\n >\n <button (click)=\"hide = !hide\" [disabled]=\"isReadOnly\" mat-icon-button matSuffix>\n <i *ngIf=\"hide\" class=\"fas fa-eye-slash\"></i>\n <i *ngIf=\"!hide\" class=\"fas fa-eye\"></i>\n </button>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n <div *ngIf=\"metadata.needsConfirmation\" style=\"margin-left: 5px;margin-right: 5px;\"></div>\n <mat-form-field class=\"w-50\" *ngIf=\"metadata.needsConfirmation\">\n <mat-label>{{metadata.confirmationDisplayName}}</mat-label>\n <input\n [type]=\"hideConfirm ? 'password' : 'text'\"\n matInput\n [(ngModel)]=\"confirmPassword\"\n [name]=\"key.toString() + 'confirmPassword'\"\n #confirmModel=\"ngModel\"\n [required]=\"metadata.required || confirmRequired\"\n (ngModelChange)=\"passwordInput()\"\n [disabled]=\"isReadOnly\"\n >\n <button (click)=\"hideConfirm = !hideConfirm\" [disabled]=\"isReadOnly\" mat-icon-button matSuffix>\n <i *ngIf=\"hideConfirm\" class=\"fas fa-eye-slash\"></i>\n <i *ngIf=\"!hideConfirm\" class=\"fas fa-eye\"></i>\n </button>\n <mat-error>{{getValidationErrorMessage(confirmModel)}}</mat-error>\n </mat-form-field>\n</div>\n\n<mat-error *ngIf=\"metadata.needsConfirmation && propertyValue && confirmPassword && (confirmPassword !== propertyValue)\">\n {{metadata.passwordsDontMatchErrorMessage}}\n</mat-error>", styles: [".password-row{display:flex;justify-content:space-between}.w-50{width:50%}.w-100{width:100%}\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"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i4.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i4.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
1901
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: StringPasswordInputComponent, decorators: [{
|
|
1902
|
+
type: Component,
|
|
1903
|
+
args: [{ selector: 'string-password-input', template: "<div class=\"password-row\">\n <mat-form-field [class.w-50]=\"metadata.needsConfirmation\" [class.w-100]=\"!metadata.needsConfirmation\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n [type]=\"hide ? 'password' : 'text'\"\n matInput\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n [minlength]=\"metadata.minLength ?? null\"\n [maxlength]=\"metadata.maxLength ?? null\"\n (ngModelChange)=\"passwordInput()\"\n [disabled]=\"isReadOnly\"\n >\n <button (click)=\"hide = !hide\" [disabled]=\"isReadOnly\" mat-icon-button matSuffix>\n <i *ngIf=\"hide\" class=\"fas fa-eye-slash\"></i>\n <i *ngIf=\"!hide\" class=\"fas fa-eye\"></i>\n </button>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n <div *ngIf=\"metadata.needsConfirmation\" style=\"margin-left: 5px;margin-right: 5px;\"></div>\n <mat-form-field class=\"w-50\" *ngIf=\"metadata.needsConfirmation\">\n <mat-label>{{metadata.confirmationDisplayName}}</mat-label>\n <input\n [type]=\"hideConfirm ? 'password' : 'text'\"\n matInput\n [(ngModel)]=\"confirmPassword\"\n [name]=\"key.toString() + 'confirmPassword'\"\n #confirmModel=\"ngModel\"\n [required]=\"metadata.required || confirmRequired\"\n (ngModelChange)=\"passwordInput()\"\n [disabled]=\"isReadOnly\"\n >\n <button (click)=\"hideConfirm = !hideConfirm\" [disabled]=\"isReadOnly\" mat-icon-button matSuffix>\n <i *ngIf=\"hideConfirm\" class=\"fas fa-eye-slash\"></i>\n <i *ngIf=\"!hideConfirm\" class=\"fas fa-eye\"></i>\n </button>\n <mat-error>{{getValidationErrorMessage(confirmModel)}}</mat-error>\n </mat-form-field>\n</div>\n\n<mat-error *ngIf=\"metadata.needsConfirmation && propertyValue && confirmPassword && (confirmPassword !== propertyValue)\">\n {{metadata.passwordsDontMatchErrorMessage}}\n</mat-error>", styles: [".password-row{display:flex;justify-content:space-between}.w-50{width:50%}.w-100{width:100%}\n"] }]
|
|
1904
|
+
}] });
|
|
1905
|
+
|
|
1906
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
1907
|
+
class BooleanCheckboxInputComponent extends NgxMatEntityBaseInputComponent {
|
|
1908
|
+
ngOnInit() {
|
|
1909
|
+
super.ngOnInit();
|
|
1910
|
+
this.propertyValue = this.propertyValue ?? false;
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
BooleanCheckboxInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BooleanCheckboxInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1914
|
+
BooleanCheckboxInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: BooleanCheckboxInputComponent, selector: "boolean-checkbox-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-checkbox\n color=\"primary\"\n (ngModelChange)=\"emitChange()\"\n (click)=\"model.control.markAsTouched()\"\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n [disabled]=\"isReadOnly\"\n [class.disabled]=\"isReadOnly\"\n [class.mat-checkbox-disabled]=\"false\"\n >\n </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)]=\"propertyValue\"\n [name]=\"key.toString() + 'Helper'\"\n #model=\"ngModel\"\n [pattern]=\"metadata.required ? 'true' : '[\\\\s\\\\S]*'\"\n [required]=\"metadata.required\"\n [disabled]=\"isReadOnly\"\n >\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["::ng-deep .hideUnderline .mat-form-field-underline{opacity:0%}::ng-deep .disabled .mat-checkbox-ripple{display:none}::ng-deep .disabled:hover{cursor:default}mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4.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: i4.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
1915
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BooleanCheckboxInputComponent, decorators: [{
|
|
1916
|
+
type: Component,
|
|
1917
|
+
args: [{ selector: 'boolean-checkbox-input', template: "<mat-form-field class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-checkbox\n color=\"primary\"\n (ngModelChange)=\"emitChange()\"\n (click)=\"model.control.markAsTouched()\"\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n [disabled]=\"isReadOnly\"\n [class.disabled]=\"isReadOnly\"\n [class.mat-checkbox-disabled]=\"false\"\n >\n </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)]=\"propertyValue\"\n [name]=\"key.toString() + 'Helper'\"\n #model=\"ngModel\"\n [pattern]=\"metadata.required ? 'true' : '[\\\\s\\\\S]*'\"\n [required]=\"metadata.required\"\n [disabled]=\"isReadOnly\"\n >\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["::ng-deep .hideUnderline .mat-form-field-underline{opacity:0%}::ng-deep .disabled .mat-checkbox-ripple{display:none}::ng-deep .disabled:hover{cursor:default}mat-form-field{width:100%}\n"] }]
|
|
1918
|
+
}] });
|
|
1919
|
+
|
|
1920
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
1921
|
+
class BooleanToggleInputComponent extends NgxMatEntityBaseInputComponent {
|
|
1922
|
+
ngOnInit() {
|
|
1923
|
+
super.ngOnInit();
|
|
1924
|
+
this.propertyValue = this.propertyValue ?? false;
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
BooleanToggleInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BooleanToggleInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1928
|
+
BooleanToggleInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: BooleanToggleInputComponent, selector: "boolean-toggle-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-slide-toggle\n color=\"primary\"\n (click)=\"model.control.markAsTouched()\"\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n [disabled]=\"isReadOnly\"\n >\n </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)]=\"propertyValue\"\n [name]=\"key.toString() + 'Helper'\"\n #model=\"ngModel\"\n [pattern]=\"metadata.required ? 'true' : '[\\\\s\\\\S]*'\"\n [required]=\"metadata.required\"\n (ngModelChange)=\"emitChange()\"\n >\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["::ng-deep .hideUnderline .mat-form-field-underline{opacity:0%}mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex", "name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "checked"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4.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: i4.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
1929
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BooleanToggleInputComponent, decorators: [{
|
|
1930
|
+
type: Component,
|
|
1931
|
+
args: [{ selector: 'boolean-toggle-input', template: "<mat-form-field class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-slide-toggle\n color=\"primary\"\n (click)=\"model.control.markAsTouched()\"\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n [disabled]=\"isReadOnly\"\n >\n </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)]=\"propertyValue\"\n [name]=\"key.toString() + 'Helper'\"\n #model=\"ngModel\"\n [pattern]=\"metadata.required ? 'true' : '[\\\\s\\\\S]*'\"\n [required]=\"metadata.required\"\n (ngModelChange)=\"emitChange()\"\n >\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["::ng-deep .hideUnderline .mat-form-field-underline{opacity:0%}mat-form-field{width:100%}\n"] }]
|
|
1932
|
+
}] });
|
|
1933
|
+
|
|
1934
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
1935
|
+
class BooleanDropdownInputComponent extends NgxMatEntityBaseInputComponent {
|
|
1936
|
+
}
|
|
1937
|
+
BooleanDropdownInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BooleanDropdownInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1938
|
+
BooleanDropdownInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: BooleanDropdownInputComponent, selector: "boolean-dropdown-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select\n (ngModelChange)=\"emitChange()\"\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [disabled]=\"isReadOnly\"\n >\n <mat-option [value]=\"undefined\">-</mat-option>\n <mat-option [value]=\"true\">{{metadata.dropdownTrue}}</mat-option>\n <mat-option [value]=\"false\">{{metadata.dropdownFalse}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
1939
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BooleanDropdownInputComponent, decorators: [{
|
|
1940
|
+
type: Component,
|
|
1941
|
+
args: [{ selector: 'boolean-dropdown-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select\n (ngModelChange)=\"emitChange()\"\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [disabled]=\"isReadOnly\"\n >\n <mat-option [value]=\"undefined\">-</mat-option>\n <mat-option [value]=\"true\">{{metadata.dropdownTrue}}</mat-option>\n <mat-option [value]=\"false\">{{metadata.dropdownFalse}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
1942
|
+
}] });
|
|
1943
|
+
|
|
1944
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
1945
|
+
class NumberInputComponent extends NgxMatEntityBaseInputComponent {
|
|
1946
|
+
}
|
|
1947
|
+
NumberInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NumberInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1948
|
+
NumberInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NumberInputComponent, selector: "number-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n type=\"number\"\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ?? null\"\n [max]=\"metadata.max ?? null\"\n (ngModelChange)=\"emitChange()\"\n [disabled]=\"isReadOnly\"\n >\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i4.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i4.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
1949
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NumberInputComponent, decorators: [{
|
|
1950
|
+
type: Component,
|
|
1951
|
+
args: [{ selector: 'number-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n type=\"number\"\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ?? null\"\n [max]=\"metadata.max ?? null\"\n (ngModelChange)=\"emitChange()\"\n [disabled]=\"isReadOnly\"\n >\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
1952
|
+
}] });
|
|
1953
|
+
|
|
1954
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
1955
|
+
class NumberDropdownInputComponent extends NgxMatEntityBaseInputComponent {
|
|
1956
|
+
}
|
|
1957
|
+
NumberDropdownInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NumberDropdownInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1958
|
+
NumberDropdownInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NumberDropdownInputComponent, selector: "number-dropdown-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select (ngModelChange)=\"emitChange()\" [(ngModel)]=\"propertyValue\" [name]=\"key.toString()\" #model=\"ngModel\" [required]=\"metadata.required\" [disabled]=\"isReadOnly\">\n <mat-option *ngFor=\"let value of metadata.dropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
1959
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NumberDropdownInputComponent, decorators: [{
|
|
1960
|
+
type: Component,
|
|
1961
|
+
args: [{ selector: 'number-dropdown-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select (ngModelChange)=\"emitChange()\" [(ngModel)]=\"propertyValue\" [name]=\"key.toString()\" #model=\"ngModel\" [required]=\"metadata.required\" [disabled]=\"isReadOnly\">\n <mat-option *ngFor=\"let value of metadata.dropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
1962
|
+
}] });
|
|
1963
|
+
|
|
1964
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
1965
|
+
class NumberSliderInputComponent extends NgxMatEntityBaseInputComponent {
|
|
1966
|
+
}
|
|
1967
|
+
NumberSliderInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NumberSliderInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1968
|
+
NumberSliderInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NumberSliderInputComponent, selector: "number-slider-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field floatLabel=\"always\" class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <!-- hidden input is needed so that the slider can be used inside a mat-form-field -->\n <input matInput\n #hiddenInput\n type=\"number\"\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString() + 'Helper'\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ?? null\"\n [max]=\"metadata.max ?? null\"\n (ngModelChange)=\"emitChange()\"\n [disabled]=\"isReadOnly\"\n >\n <mat-slider\n id=\"slider\"\n color=\"primary\"\n (click)=\"model.control.markAsTouched()\"\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n [min]=\"metadata.min ?? null\"\n [max]=\"metadata.max ?? null\"\n [step]=\"metadata.step\"\n [thumbLabel]=\"true\"\n [displayWith]=\"metadata.formatThumbLabelValue\"\n [tickInterval]=\"metadata.tickInterval\"\n [disabled]=\"isReadOnly\"\n >\n </mat-slider>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}input{opacity:0%}mat-slider{width:100%;position:absolute;top:-7px;left:0}::ng-deep .hideUnderline .mat-form-field-underline{opacity:0%}::ng-deep #slider .mat-slider-thumb-label{top:-15px;display:flex;transform:rotate(45deg) scale(1);border-radius:50%}::ng-deep #slider.mat-slider-min-value.cdk-focused .mat-slider-thumb-label{background-color:#000000de}::ng-deep #slider .mat-slider-thumb{transform:scale(0)}::ng-deep #slider .mat-slider-thumb-label-text{opacity:1}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$4.MatSlider, selector: "mat-slider", inputs: ["disabled", "color", "tabIndex", "invert", "max", "min", "step", "thumbLabel", "tickInterval", "value", "displayWith", "valueText", "vertical"], outputs: ["change", "input", "valueChange"], exportAs: ["matSlider"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i4.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i4.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
1969
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NumberSliderInputComponent, decorators: [{
|
|
1970
|
+
type: Component,
|
|
1971
|
+
args: [{ selector: 'number-slider-input', template: "<mat-form-field floatLabel=\"always\" class=\"hideUnderline\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <!-- hidden input is needed so that the slider can be used inside a mat-form-field -->\n <input matInput\n #hiddenInput\n type=\"number\"\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString() + 'Helper'\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ?? null\"\n [max]=\"metadata.max ?? null\"\n (ngModelChange)=\"emitChange()\"\n [disabled]=\"isReadOnly\"\n >\n <mat-slider\n id=\"slider\"\n color=\"primary\"\n (click)=\"model.control.markAsTouched()\"\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n [min]=\"metadata.min ?? null\"\n [max]=\"metadata.max ?? null\"\n [step]=\"metadata.step\"\n [thumbLabel]=\"true\"\n [displayWith]=\"metadata.formatThumbLabelValue\"\n [tickInterval]=\"metadata.tickInterval\"\n [disabled]=\"isReadOnly\"\n >\n </mat-slider>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}input{opacity:0%}mat-slider{width:100%;position:absolute;top:-7px;left:0}::ng-deep .hideUnderline .mat-form-field-underline{opacity:0%}::ng-deep #slider .mat-slider-thumb-label{top:-15px;display:flex;transform:rotate(45deg) scale(1);border-radius:50%}::ng-deep #slider.mat-slider-min-value.cdk-focused .mat-slider-thumb-label{background-color:#000000de}::ng-deep #slider .mat-slider-thumb{transform:scale(0)}::ng-deep #slider .mat-slider-thumb-label-text{opacity:1}\n"] }]
|
|
1972
|
+
}] });
|
|
1973
|
+
|
|
1974
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
1975
|
+
/**
|
|
1976
|
+
* The base data needed for all arrays that are displayed as a table.
|
|
1977
|
+
*/
|
|
1978
|
+
class ArrayTableComponent extends NgxMatEntityBaseInputComponent {
|
|
1979
|
+
constructor(matDialog) {
|
|
1980
|
+
super();
|
|
1981
|
+
this.matDialog = matDialog;
|
|
1982
|
+
this.input = undefined;
|
|
1983
|
+
this.dataSource = new MatTableDataSource();
|
|
1984
|
+
this.selection = new SelectionModel(true, []);
|
|
1985
|
+
}
|
|
1986
|
+
ngOnInit() {
|
|
1987
|
+
super.ngOnInit();
|
|
1988
|
+
this.propertyValue = this.propertyValue ?? [];
|
|
1989
|
+
const givenDisplayColumns = this.metadata.displayColumns.map((v) => v.displayName);
|
|
1990
|
+
if (givenDisplayColumns.find(s => s === 'select')) {
|
|
1991
|
+
throw new Error(`The name "select" for a display column is reserved.
|
|
1992
|
+
Please choose a different name.`);
|
|
1329
1993
|
}
|
|
1330
|
-
this.
|
|
1994
|
+
this.displayedColumns = this.isReadOnly ? givenDisplayColumns : ['select'].concat(givenDisplayColumns);
|
|
1995
|
+
this.dataSource.data = this.propertyValue;
|
|
1331
1996
|
}
|
|
1332
1997
|
/**
|
|
1333
|
-
*
|
|
1998
|
+
* Toggles all array-items in the table.
|
|
1999
|
+
*
|
|
1334
2000
|
*/
|
|
1335
|
-
|
|
1336
|
-
if (
|
|
1337
|
-
this.
|
|
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);
|
|
2001
|
+
masterToggle() {
|
|
2002
|
+
if (this.isAllSelected()) {
|
|
2003
|
+
this.selection.clear();
|
|
1343
2004
|
}
|
|
1344
2005
|
else {
|
|
1345
|
-
|
|
2006
|
+
this.dataSource.data.forEach(row => this.selection.select(row));
|
|
1346
2007
|
}
|
|
1347
2008
|
}
|
|
2009
|
+
/**
|
|
2010
|
+
* Checks if all array-items in the table have been selected.
|
|
2011
|
+
* This is needed to display the "masterToggle"-checkbox correctly.
|
|
2012
|
+
*
|
|
2013
|
+
* @returns Whether or not all array-items in the table have been selected.
|
|
2014
|
+
*/
|
|
2015
|
+
isAllSelected() {
|
|
2016
|
+
const numSelected = this.selection.selected.length;
|
|
2017
|
+
const numRows = this.dataSource.data.length;
|
|
2018
|
+
return numSelected === numRows;
|
|
2019
|
+
}
|
|
1348
2020
|
/**
|
|
1349
2021
|
* 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
2022
|
*/
|
|
1353
2023
|
add() {
|
|
1354
|
-
if (this.
|
|
1355
|
-
this.
|
|
2024
|
+
if (this.input != null) {
|
|
2025
|
+
if (!this.metadata.allowDuplicates
|
|
2026
|
+
&& this.propertyValue?.find(async (v) => await EntityUtilities.isEqual(this.input, v, this.metadata, this.metadata.itemType)) != null) {
|
|
2027
|
+
this.matDialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
2028
|
+
data: this.metadata.duplicatesErrorDialog,
|
|
2029
|
+
autoFocus: false,
|
|
2030
|
+
restoreFocus: false
|
|
2031
|
+
});
|
|
2032
|
+
return;
|
|
2033
|
+
}
|
|
2034
|
+
this.propertyValue?.push(LodashUtilities.cloneDeep(this.input));
|
|
2035
|
+
this.dataSource.data = this.propertyValue ?? [];
|
|
2036
|
+
this.resetInput();
|
|
2037
|
+
this.emitChange();
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
/**
|
|
2041
|
+
* Is split up from the add method to override this functionality more easily.
|
|
2042
|
+
*/
|
|
2043
|
+
resetInput() {
|
|
2044
|
+
this.input = undefined;
|
|
2045
|
+
}
|
|
2046
|
+
/**
|
|
2047
|
+
* Removes all selected entries from the entity array.
|
|
2048
|
+
*/
|
|
2049
|
+
remove() {
|
|
2050
|
+
this.selection.selected.forEach(s => {
|
|
2051
|
+
this.propertyValue?.splice(this.propertyValue.indexOf(s), 1);
|
|
2052
|
+
});
|
|
2053
|
+
this.dataSource.data = this.propertyValue ?? [];
|
|
2054
|
+
this.selection.clear();
|
|
2055
|
+
this.emitChange();
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
ArrayTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayTableComponent, deps: [{ token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
|
|
2059
|
+
ArrayTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ArrayTableComponent, selector: "ngx-mat-entity-array-table", usesInheritance: true, ngImport: i0, template: '', isInline: true });
|
|
2060
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayTableComponent, decorators: [{
|
|
2061
|
+
type: Component,
|
|
2062
|
+
args: [{
|
|
2063
|
+
selector: 'ngx-mat-entity-array-table',
|
|
2064
|
+
template: ''
|
|
2065
|
+
}]
|
|
2066
|
+
}], ctorParameters: function () { return [{ type: i1.MatDialog }]; } });
|
|
2067
|
+
|
|
2068
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
2069
|
+
class ArrayDateInputComponent extends ArrayTableComponent {
|
|
2070
|
+
constructor() {
|
|
2071
|
+
super(...arguments);
|
|
2072
|
+
this.DateUtilities = DateUtilities;
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
ArrayDateInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayDateInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2076
|
+
ArrayDateInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ArrayDateInputComponent, selector: "array-date-input", usesInheritance: true, ngImport: i0, template: "<div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n <div style=\"padding-bottom: 10px;\">\n <b>{{metadata.displayName}}</b>\n </div>\n <div *ngIf=\"!isReadOnly\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"input\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ? metadata.min(input) : undefined\"\n [max]=\"metadata.max ? metadata.max(input) : undefined\"\n [matDatepickerFilter]=\"metadata.filter ?? DateUtilities.defaultDateFilter\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n \n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"model.errors\"\n (click)=\"add()\">\n {{metadata.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadata.removeButtonLabel}}\n </button>\n </div>\n </div>\n\n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadata.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <div class=\"array-error\" *ngIf=\"metadata.required && !dataSource.data.length\">\n {{metadata.missingErrorMessage}}\n </div>\n</div>", styles: ["mat-form-field{width:100%}.buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.mat-column-select{flex:0 0 75px}.array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$5.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i2$5.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i4$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i4$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2$5.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }, { type: i4$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i4$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i4$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i4$2.MatCellDef, selector: "[matCellDef]" }, { type: i4$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i4$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }] });
|
|
2077
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayDateInputComponent, decorators: [{
|
|
2078
|
+
type: Component,
|
|
2079
|
+
args: [{ selector: 'array-date-input', template: "<div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n <div style=\"padding-bottom: 10px;\">\n <b>{{metadata.displayName}}</b>\n </div>\n <div *ngIf=\"!isReadOnly\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"input\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ? metadata.min(input) : undefined\"\n [max]=\"metadata.max ? metadata.max(input) : undefined\"\n [matDatepickerFilter]=\"metadata.filter ?? DateUtilities.defaultDateFilter\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n \n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"model.errors\"\n (click)=\"add()\">\n {{metadata.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadata.removeButtonLabel}}\n </button>\n </div>\n </div>\n\n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadata.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <div class=\"array-error\" *ngIf=\"metadata.required && !dataSource.data.length\">\n {{metadata.missingErrorMessage}}\n </div>\n</div>", styles: ["mat-form-field{width:100%}.buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.mat-column-select{flex:0 0 75px}.array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"] }]
|
|
2080
|
+
}] });
|
|
2081
|
+
|
|
2082
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
2083
|
+
class ArrayDateTimeInputComponent extends ArrayTableComponent {
|
|
2084
|
+
constructor() {
|
|
2085
|
+
super(...arguments);
|
|
2086
|
+
this.DateUtilities = DateUtilities;
|
|
2087
|
+
}
|
|
2088
|
+
ngOnInit() {
|
|
2089
|
+
super.ngOnInit();
|
|
2090
|
+
this.time = DateUtilities.getTimeFromDate(this.entity[this.key]);
|
|
2091
|
+
this.timeDropdownValues = this.metadata.times;
|
|
2092
|
+
if (this.entity[this.key] != null) {
|
|
2093
|
+
this.dateTime = new Date(this.entity[this.key]);
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
resetInput() {
|
|
2097
|
+
this.input = undefined;
|
|
2098
|
+
this.time = undefined;
|
|
2099
|
+
}
|
|
2100
|
+
/**
|
|
2101
|
+
* Adds a date time to the array.
|
|
2102
|
+
*/
|
|
2103
|
+
addDateTime() {
|
|
2104
|
+
if (this.input && this.time) {
|
|
2105
|
+
this.input = new Date(this.input);
|
|
2106
|
+
this.input.setHours(this.time.hours, this.time.minutes, 0, 0);
|
|
2107
|
+
this.add();
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
ArrayDateTimeInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayDateTimeInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2112
|
+
ArrayDateTimeInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ArrayDateTimeInputComponent, selector: "array-date-time-input", usesInheritance: true, ngImport: i0, template: "<div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n <div style=\"padding-bottom: 10px;\">\n <b>{{metadata.displayName}}</b>\n </div>\n <div *ngIf=\"!isReadOnly\">\n <div class=\"date-time\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"input\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minDate ? metadata.minDate(input) : undefined\"\n [max]=\"metadata.maxDate ? metadata.maxDate(input) : undefined\"\n [matDatepickerFilter]=\"metadata.filterDate ?? DateUtilities.defaultDateFilter\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n <mat-form-field class=\"timepicker\">\n <mat-label>{{metadata.timeDisplayName}}</mat-label>\n <mat-select\n [(ngModel)]=\"time\"\n [name]=\"key.toString() + 'time'\"\n #timeModel=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-option *ngFor=\"let validTime of DateUtilities.getValidTimesForDropdown(\n metadata.times,\n input,\n metadata.minTime,\n metadata.maxTime,\n metadata.filterTime\n )\"\n [value]=\"validTime.value\"\n >\n {{validTime.displayName}}\n </mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(timeModel)}}</mat-error>\n </mat-form-field>\n </div>\n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"model.errors || timeModel.errors || DateUtilities.timeIsUnprocessable(time)\"\n (click)=\"addDateTime()\">\n {{metadata.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadata.removeButtonLabel}}\n </button>\n </div>\n </div>\n\n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadata.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <div class=\"array-error\" *ngIf=\"metadata.required && !dataSource.data.length\">\n {{metadata.missingErrorMessage}}\n </div>\n</div>", styles: ["mat-form-field{width:100%}.buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.mat-column-select{flex:0 0 75px}.array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}.date-time{display:flex;align-items:baseline}.date-time .timepicker{margin-left:10px}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$5.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i2$5.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { type: i2$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i4$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i4$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2$5.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i4$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i4$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i4$2.MatCellDef, selector: "[matCellDef]" }, { type: i4$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i4$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i4$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }] });
|
|
2113
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayDateTimeInputComponent, decorators: [{
|
|
2114
|
+
type: Component,
|
|
2115
|
+
args: [{ selector: 'array-date-time-input', template: "<div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n <div style=\"padding-bottom: 10px;\">\n <b>{{metadata.displayName}}</b>\n </div>\n <div *ngIf=\"!isReadOnly\">\n <div class=\"date-time\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"input\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minDate ? metadata.minDate(input) : undefined\"\n [max]=\"metadata.maxDate ? metadata.maxDate(input) : undefined\"\n [matDatepickerFilter]=\"metadata.filterDate ?? DateUtilities.defaultDateFilter\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n <mat-form-field class=\"timepicker\">\n <mat-label>{{metadata.timeDisplayName}}</mat-label>\n <mat-select\n [(ngModel)]=\"time\"\n [name]=\"key.toString() + 'time'\"\n #timeModel=\"ngModel\"\n [required]=\"metadata.required\"\n >\n <mat-option *ngFor=\"let validTime of DateUtilities.getValidTimesForDropdown(\n metadata.times,\n input,\n metadata.minTime,\n metadata.maxTime,\n metadata.filterTime\n )\"\n [value]=\"validTime.value\"\n >\n {{validTime.displayName}}\n </mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(timeModel)}}</mat-error>\n </mat-form-field>\n </div>\n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"model.errors || timeModel.errors || DateUtilities.timeIsUnprocessable(time)\"\n (click)=\"addDateTime()\">\n {{metadata.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadata.removeButtonLabel}}\n </button>\n </div>\n </div>\n\n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadata.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <div class=\"array-error\" *ngIf=\"metadata.required && !dataSource.data.length\">\n {{metadata.missingErrorMessage}}\n </div>\n</div>", styles: ["mat-form-field{width:100%}.buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.mat-column-select{flex:0 0 75px}.array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}.date-time{display:flex;align-items:baseline}.date-time .timepicker{margin-left:10px}\n"] }]
|
|
2116
|
+
}] });
|
|
2117
|
+
|
|
2118
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
2119
|
+
class ArrayDateRangeInputComponent extends ArrayTableComponent {
|
|
2120
|
+
constructor() {
|
|
2121
|
+
super(...arguments);
|
|
2122
|
+
this.DateUtilities = DateUtilities;
|
|
2123
|
+
}
|
|
2124
|
+
ngOnInit() {
|
|
2125
|
+
super.ngOnInit();
|
|
2126
|
+
this.input = {
|
|
2127
|
+
start: undefined,
|
|
2128
|
+
end: undefined,
|
|
2129
|
+
values: undefined
|
|
2130
|
+
};
|
|
2131
|
+
}
|
|
2132
|
+
/**
|
|
2133
|
+
* Adds a DateRange to the array.
|
|
2134
|
+
*/
|
|
2135
|
+
addDateRange() {
|
|
2136
|
+
if (this.input && this.dateRangeStart && this.dateRangeEnd) {
|
|
2137
|
+
this.input.start = new Date(this.dateRangeStart);
|
|
2138
|
+
this.input.end = new Date(this.dateRangeEnd);
|
|
2139
|
+
const values = DateUtilities.getDatesBetween(this.input.start, this.input.end, this.metadata.filter);
|
|
2140
|
+
this.input.values = values.length ? values : undefined;
|
|
2141
|
+
this.add();
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
resetInput() {
|
|
2145
|
+
this.input = undefined;
|
|
2146
|
+
this.dateRangeStart = undefined;
|
|
2147
|
+
this.dateRangeEnd = undefined;
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
ArrayDateRangeInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayDateRangeInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2151
|
+
ArrayDateRangeInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ArrayDateRangeInputComponent, selector: "array-date-range-input", usesInheritance: true, ngImport: i0, template: "<div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n <div style=\"padding-bottom: 10px;\">\n <b>{{metadata.displayName}}</b>\n </div>\n <div *ngIf=\"!isReadOnly\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n \n <mat-date-range-input [rangePicker]=\"picker\" [required]=\"metadata.required\" [dateFilter]=\"metadata.filter ? metadata.filter : DateUtilities.defaultDateFilter\">\n <input matStartDate\n [(ngModel)]=\"dateRangeStart\"\n [name]=\"key.toString() + 'start'\"\n #startModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minStart ? metadata.minStart(input?.start) : undefined\"\n [max]=\"metadata.maxStart ? metadata.maxStart(input?.start) : undefined\"\n [placeholder]=\"metadata.placeholderStart\"\n >\n <input matEndDate\n [(ngModel)]=\"dateRangeEnd\"\n [name]=\"key.toString() + 'end'\"\n #endModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minEnd ? metadata.minEnd(input?.end) : undefined\"\n [max]=\"metadata.maxEnd ? metadata.maxEnd(input?.end) : undefined\"\n [placeholder]=\"metadata.placeholderEnd\"\n >\n </mat-date-range-input>\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-date-range-picker #picker></mat-date-range-picker>\n \n <mat-error *ngIf=\"startModel.errors\">{{getValidationErrorMessage(startModel)}}</mat-error>\n <mat-error *ngIf=\"!startModel.errors && endModel.errors\">{{getValidationErrorMessage(endModel)}}</mat-error>\n </mat-form-field>\n \n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"startModel.errors || endModel.errors\"\n (click)=\"addDateRange()\">\n {{metadata.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadata.removeButtonLabel}}\n </button>\n </div>\n </div>\n\n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadata.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <div class=\"array-error\" *ngIf=\"metadata.required && !dataSource.data.length\">\n {{metadata.missingErrorMessage}}\n </div>\n</div>", styles: ["mat-form-field{width:100%}.buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.mat-column-select{flex:0 0 75px}.array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$5.MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { type: i2$5.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i2$5.MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i4$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i4$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.MatLabel, selector: "mat-label" }, { type: i2$5.MatStartDate, selector: "input[matStartDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2$5.MatEndDate, selector: "input[matEndDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }, { type: i4$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i4$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i4$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i4$2.MatCellDef, selector: "[matCellDef]" }, { type: i4$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i4$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }] });
|
|
2152
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayDateRangeInputComponent, decorators: [{
|
|
2153
|
+
type: Component,
|
|
2154
|
+
args: [{ selector: 'array-date-range-input', template: "<div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n <div style=\"padding-bottom: 10px;\">\n <b>{{metadata.displayName}}</b>\n </div>\n <div *ngIf=\"!isReadOnly\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n \n <mat-date-range-input [rangePicker]=\"picker\" [required]=\"metadata.required\" [dateFilter]=\"metadata.filter ? metadata.filter : DateUtilities.defaultDateFilter\">\n <input matStartDate\n [(ngModel)]=\"dateRangeStart\"\n [name]=\"key.toString() + 'start'\"\n #startModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minStart ? metadata.minStart(input?.start) : undefined\"\n [max]=\"metadata.maxStart ? metadata.maxStart(input?.start) : undefined\"\n [placeholder]=\"metadata.placeholderStart\"\n >\n <input matEndDate\n [(ngModel)]=\"dateRangeEnd\"\n [name]=\"key.toString() + 'end'\"\n #endModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minEnd ? metadata.minEnd(input?.end) : undefined\"\n [max]=\"metadata.maxEnd ? metadata.maxEnd(input?.end) : undefined\"\n [placeholder]=\"metadata.placeholderEnd\"\n >\n </mat-date-range-input>\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-date-range-picker #picker></mat-date-range-picker>\n \n <mat-error *ngIf=\"startModel.errors\">{{getValidationErrorMessage(startModel)}}</mat-error>\n <mat-error *ngIf=\"!startModel.errors && endModel.errors\">{{getValidationErrorMessage(endModel)}}</mat-error>\n </mat-form-field>\n \n <div class=\"buttons\">\n <button mat-raised-button\n [disabled]=\"startModel.errors || endModel.errors\"\n (click)=\"addDateRange()\">\n {{metadata.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove()\">\n {{metadata.removeButtonLabel}}\n </button>\n </div>\n </div>\n\n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\" [indeterminate]=\"selection.hasValue() && !isAllSelected()\"></mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadata.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <div class=\"array-error\" *ngIf=\"metadata.required && !dataSource.data.length\">\n {{metadata.missingErrorMessage}}\n </div>\n</div>", styles: ["mat-form-field{width:100%}.buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.mat-column-select{flex:0 0 75px}.array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"] }]
|
|
2155
|
+
}] });
|
|
2156
|
+
|
|
2157
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
2158
|
+
class ArrayStringChipsInputComponent extends NgxMatEntityBaseInputComponent {
|
|
2159
|
+
constructor() {
|
|
2160
|
+
super(...arguments);
|
|
2161
|
+
this.chipsInput = '';
|
|
2162
|
+
}
|
|
2163
|
+
/**
|
|
2164
|
+
* Handles adding strings to the chipsArray.
|
|
2165
|
+
* Checks validation and also creates a new array if it is undefined.
|
|
2166
|
+
* This is needed because two things are validated: The array itself
|
|
2167
|
+
* and the contents of the array. And we need a way to display an
|
|
2168
|
+
* mat-error. As the only validation for the array is whether or not
|
|
2169
|
+
* it contains values, we can set it to undefined when the last element is removed
|
|
2170
|
+
* (removeStringChipArrayValue). That way we can use the "required" validator.
|
|
2171
|
+
*
|
|
2172
|
+
* @param event - The event that fires when a new chip is completed.
|
|
2173
|
+
*/
|
|
2174
|
+
addStringChipArrayValue(event) {
|
|
2175
|
+
const value = (event.value || '').trim();
|
|
2176
|
+
if (value) {
|
|
2177
|
+
if (this.metadata.minLength && value.length < this.metadata.minLength) {
|
|
2178
|
+
return;
|
|
2179
|
+
}
|
|
2180
|
+
if (this.metadata.maxLength && value.length > this.metadata.maxLength) {
|
|
2181
|
+
return;
|
|
2182
|
+
}
|
|
2183
|
+
if (this.metadata.regex && !value.match(this.metadata.regex)) {
|
|
2184
|
+
return;
|
|
2185
|
+
}
|
|
2186
|
+
this.propertyValue = this.propertyValue ?? [];
|
|
2187
|
+
this.propertyValue.push(value);
|
|
2188
|
+
}
|
|
2189
|
+
event.chipInput?.clear();
|
|
2190
|
+
}
|
|
2191
|
+
/**
|
|
2192
|
+
* Removes the given value from the array.
|
|
2193
|
+
* Sets the array to undefined if it is now empty.
|
|
2194
|
+
* This is needed because two things are validated: The array itself
|
|
2195
|
+
* and the contents of the array. And we need a way to display an
|
|
2196
|
+
* mat-error. As the only validation for the array is whether or not
|
|
2197
|
+
* it is empty, setting it to undefined here enables us to use the "required" validator.
|
|
2198
|
+
*
|
|
2199
|
+
* @param value - The string to remove from the array.
|
|
2200
|
+
*/
|
|
2201
|
+
removeStringChipArrayValue(value) {
|
|
2202
|
+
this.propertyValue?.splice(this.propertyValue.indexOf(value), 1);
|
|
2203
|
+
this.propertyValue = this.propertyValue?.length ? this.propertyValue : undefined;
|
|
2204
|
+
}
|
|
2205
|
+
/**
|
|
2206
|
+
* Handles adding a string to the array when an autocomplete value has been selected.
|
|
2207
|
+
*
|
|
2208
|
+
* @param event - The autocomplete selected event.
|
|
2209
|
+
* @param chipsInput - The element where the user typed the value.
|
|
2210
|
+
*/
|
|
2211
|
+
selected(event, chipsInput) {
|
|
2212
|
+
const value = (event.option.viewValue || '').trim();
|
|
2213
|
+
if (this.metadata.minLength && value.length < this.metadata.minLength) {
|
|
2214
|
+
return;
|
|
2215
|
+
}
|
|
2216
|
+
if (this.metadata.maxLength && value.length > this.metadata.maxLength) {
|
|
2217
|
+
return;
|
|
2218
|
+
}
|
|
2219
|
+
if (this.metadata.regex && !value.match(this.metadata.regex)) {
|
|
2220
|
+
return;
|
|
2221
|
+
}
|
|
2222
|
+
this.propertyValue = this.propertyValue ?? [];
|
|
2223
|
+
this.propertyValue.push(value);
|
|
2224
|
+
chipsInput.value = '';
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
ArrayStringChipsInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayStringChipsInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2228
|
+
ArrayStringChipsInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ArrayStringChipsInputComponent, selector: "array-string-chips-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n (ngModelChange)=\"emitChange()\"\n [(ngModel)]=\"propertyValue\" [name]=\"key.toString()\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n [disabled]=\"isReadOnly\"\n >\n <mat-chip *ngFor=\"let value of propertyValue\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input matInput\n [matChipInputFor]=\"chipList\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addStringChipArrayValue($event)\"\n [(ngModel)]=\"chipsInput\" [name]=\"key.toString()\" #chipsModel=\"ngModel\"\n [minlength]='metadata.minLength ?? null'\n [maxlength]='metadata.maxLength ?? null'\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n >\n <mat-error *ngIf=\"chipsModel.errors\">{{getValidationErrorMessage(chipsModel)}}</mat-error>\n </mat-chip-list>\n <mat-error *ngIf=\"!chipsModel.errors\">{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$6.MatChipList, selector: "mat-chip-list", inputs: ["errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2$6.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { type: i2$6.MatChipRemove, selector: "[matChipRemove]" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i2$6.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { type: i4.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: i4.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i4.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i4.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
2229
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayStringChipsInputComponent, decorators: [{
|
|
2230
|
+
type: Component,
|
|
2231
|
+
args: [{ selector: 'array-string-chips-input', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n (ngModelChange)=\"emitChange()\"\n [(ngModel)]=\"propertyValue\" [name]=\"key.toString()\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n [disabled]=\"isReadOnly\"\n >\n <mat-chip *ngFor=\"let value of propertyValue\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input matInput\n [matChipInputFor]=\"chipList\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addStringChipArrayValue($event)\"\n [(ngModel)]=\"chipsInput\" [name]=\"key.toString()\" #chipsModel=\"ngModel\"\n [minlength]='metadata.minLength ?? null'\n [maxlength]='metadata.maxLength ?? null'\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n >\n <mat-error *ngIf=\"chipsModel.errors\">{{getValidationErrorMessage(chipsModel)}}</mat-error>\n </mat-chip-list>\n <mat-error *ngIf=\"!chipsModel.errors\">{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
2232
|
+
}] });
|
|
2233
|
+
|
|
2234
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
2235
|
+
class ArrayStringAutocompleteChipsComponent extends NgxMatEntityBaseInputComponent {
|
|
2236
|
+
constructor() {
|
|
2237
|
+
super(...arguments);
|
|
2238
|
+
this.chipsInput = '';
|
|
2239
|
+
}
|
|
2240
|
+
ngOnInit() {
|
|
2241
|
+
super.ngOnInit();
|
|
2242
|
+
this.filteredAutocompleteStrings = LodashUtilities.cloneDeep(this.metadata.autocompleteValues);
|
|
2243
|
+
}
|
|
2244
|
+
/**
|
|
2245
|
+
* Handles adding strings to the chipsArray.
|
|
2246
|
+
* Checks validation and also creates a new array if it is undefined.
|
|
2247
|
+
* This is needed because two things are validated: The array itself
|
|
2248
|
+
* and the contents of the array. And we need a way to display an
|
|
2249
|
+
* mat-error. As the only validation for the array is whether or not
|
|
2250
|
+
* it contains values, we can set it to undefined when the last element is removed
|
|
2251
|
+
* (removeStringChipArrayValue). That way we can use the "required" validator.
|
|
2252
|
+
*
|
|
2253
|
+
* @param event - The event that fires when a new chip is completed.
|
|
2254
|
+
*/
|
|
2255
|
+
addStringChipArrayValue(event) {
|
|
2256
|
+
const value = (event.value || '').trim();
|
|
2257
|
+
if (value) {
|
|
2258
|
+
if (this.metadata.minLength && value.length < this.metadata.minLength) {
|
|
2259
|
+
return;
|
|
2260
|
+
}
|
|
2261
|
+
if (this.metadata.maxLength && value.length > this.metadata.maxLength) {
|
|
2262
|
+
return;
|
|
2263
|
+
}
|
|
2264
|
+
if (this.metadata.regex && !value.match(this.metadata.regex)) {
|
|
2265
|
+
return;
|
|
2266
|
+
}
|
|
2267
|
+
this.propertyValue = this.propertyValue ?? [];
|
|
2268
|
+
this.propertyValue.push(value);
|
|
2269
|
+
}
|
|
2270
|
+
event.chipInput?.clear();
|
|
2271
|
+
}
|
|
2272
|
+
/**
|
|
2273
|
+
* Removes the given value from the array.
|
|
2274
|
+
* Sets the array to undefined if it is now empty.
|
|
2275
|
+
* This is needed because two things are validated: The array itself
|
|
2276
|
+
* and the contents of the array. And we need a way to display an
|
|
2277
|
+
* mat-error. As the only validation for the array is whether or not
|
|
2278
|
+
* it is empty, setting it to undefined here enables us to use the "required" validator.
|
|
2279
|
+
*
|
|
2280
|
+
* @param value - The string to remove from the array.
|
|
2281
|
+
*/
|
|
2282
|
+
removeStringChipArrayValue(value) {
|
|
2283
|
+
this.propertyValue?.splice(this.propertyValue.indexOf(value), 1);
|
|
2284
|
+
this.propertyValue = this.propertyValue?.length ? this.propertyValue : undefined;
|
|
2285
|
+
}
|
|
2286
|
+
/**
|
|
2287
|
+
* Handles adding a string to the array when an autocomplete value has been selected.
|
|
2288
|
+
*
|
|
2289
|
+
* @param event - The autocomplete selected event.
|
|
2290
|
+
* @param chipsInput - The element where the user typed the value.
|
|
2291
|
+
*/
|
|
2292
|
+
selected(event, chipsInput) {
|
|
2293
|
+
const value = (event.option.viewValue || '').trim();
|
|
2294
|
+
if (this.metadata.minLength && value.length < this.metadata.minLength) {
|
|
2295
|
+
return;
|
|
2296
|
+
}
|
|
2297
|
+
if (this.metadata.maxLength && value.length > this.metadata.maxLength) {
|
|
2298
|
+
return;
|
|
2299
|
+
}
|
|
2300
|
+
if (this.metadata.regex && !value.match(this.metadata.regex)) {
|
|
2301
|
+
return;
|
|
2302
|
+
}
|
|
2303
|
+
this.propertyValue = this.propertyValue ?? [];
|
|
2304
|
+
this.propertyValue.push(value);
|
|
2305
|
+
chipsInput.value = '';
|
|
2306
|
+
}
|
|
2307
|
+
/**
|
|
2308
|
+
* Dynamically filters the Autocomplete options when the user inputs something.
|
|
2309
|
+
*
|
|
2310
|
+
* @param input - The input of the user.
|
|
2311
|
+
*/
|
|
2312
|
+
filterAutocompleteStrings(input) {
|
|
2313
|
+
if (input != null) {
|
|
2314
|
+
const filterValue = input.toLowerCase();
|
|
2315
|
+
this.filteredAutocompleteStrings = this.metadata.autocompleteValues.filter(s => s.toLowerCase().includes(filterValue));
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
ArrayStringAutocompleteChipsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayStringAutocompleteChipsComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2320
|
+
ArrayStringAutocompleteChipsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: ArrayStringAutocompleteChipsComponent, selector: "array-string-autocomplete-chips", usesInheritance: true, ngImport: i0, template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n (ngModelChange)=\"emitChange()\"\n [(ngModel)]=\"propertyValue\" [name]=\"key.toString()\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n [disabled]=\"isReadOnly\"\n >\n <mat-chip *ngFor=\"let value of propertyValue\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input matInput\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addStringChipArrayValue($event)\"\n (keyup)=\"filterAutocompleteStrings(chipsInput)\"\n [(ngModel)]=\"chipsInput\" [name]=\"key.toString()\" #chipsModel=\"ngModel\"\n #chipsElement\n [minlength]='metadata.minLength ?? null'\n [maxlength]='metadata.maxLength ?? null'\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n >\n <mat-error *ngIf=\"chipsModel.errors\">{{getValidationErrorMessage(chipsModel)}}</mat-error>\n </mat-chip-list>\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event, chipsElement)\">\n <mat-option *ngFor=\"let value of metadata.autocompleteValues\" [value]=\"value\">\n {{value}}\n </mat-option>\n </mat-autocomplete>\n <mat-error *ngIf=\"!chipsModel.errors\">{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$6.MatChipList, selector: "mat-chip-list", inputs: ["errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { type: i2$1.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { type: i3$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2$6.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { type: i2$6.MatChipRemove, selector: "[matChipRemove]" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i2$6.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { type: i2$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { type: i4.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: i4.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { type: i4.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i4.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
2321
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ArrayStringAutocompleteChipsComponent, decorators: [{
|
|
2322
|
+
type: Component,
|
|
2323
|
+
args: [{ selector: 'array-string-autocomplete-chips', template: "<mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n (ngModelChange)=\"emitChange()\"\n [(ngModel)]=\"propertyValue\" [name]=\"key.toString()\" #model=\"ngModel\"\n [required]=\"metadata.required\"\n [disabled]=\"isReadOnly\"\n >\n <mat-chip *ngFor=\"let value of propertyValue\" (removed)=\"removeStringChipArrayValue(value)\">\n {{value}}\n <button matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input matInput\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n [matChipInputAddOnBlur]=\"true\"\n (matChipInputTokenEnd)=\"addStringChipArrayValue($event)\"\n (keyup)=\"filterAutocompleteStrings(chipsInput)\"\n [(ngModel)]=\"chipsInput\" [name]=\"key.toString()\" #chipsModel=\"ngModel\"\n #chipsElement\n [minlength]='metadata.minLength ?? null'\n [maxlength]='metadata.maxLength ?? null'\n [pattern]=\"metadata.regex ?? '[\\\\s\\\\S]*'\"\n >\n <mat-error *ngIf=\"chipsModel.errors\">{{getValidationErrorMessage(chipsModel)}}</mat-error>\n </mat-chip-list>\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event, chipsElement)\">\n <mat-option *ngFor=\"let value of metadata.autocompleteValues\" [value]=\"value\">\n {{value}}\n </mat-option>\n </mat-autocomplete>\n <mat-error *ngIf=\"!chipsModel.errors\">{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
2324
|
+
}] });
|
|
2325
|
+
|
|
2326
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
2327
|
+
class DateInputComponent extends NgxMatEntityBaseInputComponent {
|
|
2328
|
+
constructor() {
|
|
2329
|
+
super(...arguments);
|
|
2330
|
+
this.DateUtilities = DateUtilities;
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
DateInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2334
|
+
DateInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: DateInputComponent, selector: "date-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n (ngModelChange)=\"emitChange()\"\n matInput\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ? metadata.min(propertyValue) : undefined\"\n [max]=\"metadata.max ? metadata.max(propertyValue) : undefined\"\n [matDatepickerFilter]=\"metadata.filter ?? DateUtilities.defaultDateFilter\"\n [disabled]=\"isReadOnly\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$5.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i2$5.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2$5.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
2335
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateInputComponent, decorators: [{
|
|
2336
|
+
type: Component,
|
|
2337
|
+
args: [{ selector: 'date-input', template: "<mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n (ngModelChange)=\"emitChange()\"\n matInput\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.min ? metadata.min(propertyValue) : undefined\"\n [max]=\"metadata.max ? metadata.max(propertyValue) : undefined\"\n [matDatepickerFilter]=\"metadata.filter ?? DateUtilities.defaultDateFilter\"\n [disabled]=\"isReadOnly\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
2338
|
+
}] });
|
|
2339
|
+
|
|
2340
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
2341
|
+
const EMPTY_DATERANGE = {
|
|
2342
|
+
start: undefined,
|
|
2343
|
+
end: undefined,
|
|
2344
|
+
values: undefined
|
|
2345
|
+
};
|
|
2346
|
+
class DateRangeInputComponent extends NgxMatEntityBaseInputComponent {
|
|
2347
|
+
constructor() {
|
|
2348
|
+
super(...arguments);
|
|
2349
|
+
this.defaultDateFilter = DateUtilities.defaultDateFilter;
|
|
2350
|
+
}
|
|
2351
|
+
ngOnInit() {
|
|
2352
|
+
super.ngOnInit();
|
|
2353
|
+
this.dateRange = LodashUtilities.cloneDeep(this.propertyValue) ?? EMPTY_DATERANGE;
|
|
2354
|
+
this.dateRangeStart = new Date(this.dateRange.start);
|
|
2355
|
+
this.dateRangeEnd = new Date(this.dateRange.end);
|
|
2356
|
+
this.setDateRangeValues();
|
|
2357
|
+
}
|
|
2358
|
+
/**
|
|
2359
|
+
* Updates the date range values based on the start and end date.
|
|
2360
|
+
*/
|
|
2361
|
+
setDateRangeValues() {
|
|
2362
|
+
if (this.dateRangeStart && this.dateRangeEnd) {
|
|
2363
|
+
this.dateRange.start = new Date(this.dateRangeStart);
|
|
2364
|
+
this.dateRange.end = new Date(this.dateRangeEnd);
|
|
2365
|
+
const values = DateUtilities.getDatesBetween(new Date(this.dateRange.start), new Date(this.dateRange.end), this.metadata.filter);
|
|
2366
|
+
this.dateRange.values = values.length ? values : undefined;
|
|
2367
|
+
}
|
|
2368
|
+
else {
|
|
2369
|
+
this.dateRange.values = undefined;
|
|
2370
|
+
}
|
|
2371
|
+
this.propertyValue = this.dateRange;
|
|
2372
|
+
this.emitChange();
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
DateRangeInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateRangeInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2376
|
+
DateRangeInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: DateRangeInputComponent, selector: "date-range-input", usesInheritance: true, ngImport: i0, template: "<mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n \n <mat-date-range-input [rangePicker]=\"picker\" [required]=\"metadata.required\" [dateFilter]=\"metadata.filter ?? defaultDateFilter\" [disabled]=\"isReadOnly\">\n <input matStartDate\n [(ngModel)]=\"dateRangeStart\"\n [name]=\"key.toString() + 'start'\"\n #startModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minStart ? metadata.minStart(dateRange.start) : undefined\"\n [max]=\"metadata.maxStart ? metadata.maxStart(dateRange.start) : undefined\"\n [placeholder]=\"metadata.placeholderStart\"\n (ngModelChange)=\"setDateRangeValues()\"\n >\n <input matEndDate\n [(ngModel)]=\"dateRangeEnd\"\n [name]=\"key.toString() + 'end'\"\n #endModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minEnd ? metadata.minEnd(dateRange.end) : undefined\"\n [max]=\"metadata.maxEnd ? metadata.maxEnd(dateRange.end) : undefined\"\n [placeholder]=\"metadata.placeholderEnd\"\n (ngModelChange)=\"setDateRangeValues()\"\n >\n </mat-date-range-input>\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-date-range-picker #picker></mat-date-range-picker>\n\n <mat-error *ngIf=\"startModel.errors\">{{getValidationErrorMessage(startModel)}}</mat-error>\n <mat-error *ngIf=\"!startModel.errors && endModel.errors\">{{getValidationErrorMessage(endModel)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$5.MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { type: i2$5.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i2$5.MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i2$5.MatStartDate, selector: "input[matStartDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2$5.MatEndDate, selector: "input[matEndDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }] });
|
|
2377
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateRangeInputComponent, decorators: [{
|
|
2378
|
+
type: Component,
|
|
2379
|
+
args: [{ selector: 'date-range-input', template: "<mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n \n <mat-date-range-input [rangePicker]=\"picker\" [required]=\"metadata.required\" [dateFilter]=\"metadata.filter ?? defaultDateFilter\" [disabled]=\"isReadOnly\">\n <input matStartDate\n [(ngModel)]=\"dateRangeStart\"\n [name]=\"key.toString() + 'start'\"\n #startModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minStart ? metadata.minStart(dateRange.start) : undefined\"\n [max]=\"metadata.maxStart ? metadata.maxStart(dateRange.start) : undefined\"\n [placeholder]=\"metadata.placeholderStart\"\n (ngModelChange)=\"setDateRangeValues()\"\n >\n <input matEndDate\n [(ngModel)]=\"dateRangeEnd\"\n [name]=\"key.toString() + 'end'\"\n #endModel=\"ngModel\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minEnd ? metadata.minEnd(dateRange.end) : undefined\"\n [max]=\"metadata.maxEnd ? metadata.maxEnd(dateRange.end) : undefined\"\n [placeholder]=\"metadata.placeholderEnd\"\n (ngModelChange)=\"setDateRangeValues()\"\n >\n </mat-date-range-input>\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-date-range-picker #picker></mat-date-range-picker>\n\n <mat-error *ngIf=\"startModel.errors\">{{getValidationErrorMessage(startModel)}}</mat-error>\n <mat-error *ngIf=\"!startModel.errors && endModel.errors\">{{getValidationErrorMessage(endModel)}}</mat-error>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
2380
|
+
}] });
|
|
2381
|
+
|
|
2382
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
2383
|
+
class DateTimeInputComponent extends NgxMatEntityBaseInputComponent {
|
|
2384
|
+
constructor() {
|
|
2385
|
+
super(...arguments);
|
|
2386
|
+
this.DateUtilities = DateUtilities;
|
|
2387
|
+
this.defaultDateFilter = () => true;
|
|
2388
|
+
}
|
|
2389
|
+
ngOnInit() {
|
|
2390
|
+
super.ngOnInit();
|
|
2391
|
+
this.time = DateUtilities.getTimeFromDate(this.propertyValue);
|
|
2392
|
+
this.timeDropdownValues = this.metadata.times;
|
|
2393
|
+
if (this.propertyValue) {
|
|
2394
|
+
this.propertyValue = new Date(this.propertyValue);
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
/**
|
|
2398
|
+
* Checks if two times are equal. Is needed for the dropdown.
|
|
2399
|
+
*
|
|
2400
|
+
* @param time1 - The first time to compare.
|
|
2401
|
+
* @param time2 - The second time to compare.
|
|
2402
|
+
* @returns Whether or not the time objects are the same.
|
|
2403
|
+
*/
|
|
2404
|
+
compareTimes(time1, time2) {
|
|
2405
|
+
if (time1 && time2 && time1.hours === time2.hours && time1.minutes === time2.minutes) {
|
|
2406
|
+
return true;
|
|
2407
|
+
}
|
|
2408
|
+
return false;
|
|
2409
|
+
}
|
|
2410
|
+
/**
|
|
2411
|
+
* Sets the time on a datetime property.
|
|
2412
|
+
*/
|
|
2413
|
+
setTime() {
|
|
2414
|
+
if (!this.propertyValue) {
|
|
2415
|
+
this.emitChange();
|
|
2416
|
+
return;
|
|
2417
|
+
}
|
|
2418
|
+
if (this.time?.hours != null && this.time?.minutes != null) {
|
|
2419
|
+
this.propertyValue.setHours(this.time.hours, this.time.minutes, 0, 0);
|
|
2420
|
+
}
|
|
2421
|
+
else {
|
|
2422
|
+
this.propertyValue.setHours(0, 0, 0, 0);
|
|
2423
|
+
}
|
|
2424
|
+
this.emitChange();
|
|
2425
|
+
}
|
|
2426
|
+
}
|
|
2427
|
+
DateTimeInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateTimeInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2428
|
+
DateTimeInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: DateTimeInputComponent, selector: "date-time-input", usesInheritance: true, ngImport: i0, template: "<div class=\"date-time\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minDate ? metadata.minDate(propertyValue) : undefined\"\n [max]=\"metadata.maxDate ? metadata.maxDate(propertyValue) : undefined\"\n [matDatepickerFilter]=\"metadata.filterDate ?? defaultDateFilter\"\n (dateInput)=\"setTime()\"\n [disabled]=\"isReadOnly\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n <mat-form-field class=\"timepicker\">\n <mat-label>{{metadata.timeDisplayName}}</mat-label>\n <mat-select\n [(ngModel)]=\"time\"\n [name]=\"key.toString() + 'time'\"\n #timeModel=\"ngModel\"\n [required]=\"metadata.required\"\n [compareWith]=\"compareTimes\"\n (ngModelChange)=\"setTime()\"\n [disabled]=\"isReadOnly\"\n >\n <mat-option *ngFor=\"let validTime of DateUtilities.getValidTimesForDropdown(\n metadata.times,\n propertyValue,\n metadata.minTime,\n metadata.maxTime,\n metadata.filterTime\n )\"\n [value]=\"validTime.value\"\n >\n {{validTime.displayName}}\n </mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(timeModel)}}</mat-error>\n </mat-form-field>\n</div>", styles: ["mat-form-field{width:100%}.date-time{display:flex;align-items:baseline}.date-time .timepicker{margin-left:10px}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$5.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i2$5.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { type: i2$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2$5.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
2429
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateTimeInputComponent, decorators: [{
|
|
2430
|
+
type: Component,
|
|
2431
|
+
args: [{ selector: 'date-time-input', template: "<div class=\"date-time\">\n <mat-form-field appearance=\"standard\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <input\n matInput\n [(ngModel)]=\"propertyValue\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [matDatepicker]=\"picker\"\n [required]=\"metadata.required\"\n [min]=\"metadata.minDate ? metadata.minDate(propertyValue) : undefined\"\n [max]=\"metadata.maxDate ? metadata.maxDate(propertyValue) : undefined\"\n [matDatepickerFilter]=\"metadata.filterDate ?? defaultDateFilter\"\n (dateInput)=\"setTime()\"\n [disabled]=\"isReadOnly\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n </mat-form-field>\n <mat-form-field class=\"timepicker\">\n <mat-label>{{metadata.timeDisplayName}}</mat-label>\n <mat-select\n [(ngModel)]=\"time\"\n [name]=\"key.toString() + 'time'\"\n #timeModel=\"ngModel\"\n [required]=\"metadata.required\"\n [compareWith]=\"compareTimes\"\n (ngModelChange)=\"setTime()\"\n [disabled]=\"isReadOnly\"\n >\n <mat-option *ngFor=\"let validTime of DateUtilities.getValidTimesForDropdown(\n metadata.times,\n propertyValue,\n metadata.minTime,\n metadata.maxTime,\n metadata.filterTime\n )\"\n [value]=\"validTime.value\"\n >\n {{validTime.displayName}}\n </mat-option>\n </mat-select>\n <mat-error>{{getValidationErrorMessage(timeModel)}}</mat-error>\n </mat-form-field>\n</div>", styles: ["mat-form-field{width:100%}.date-time{display:flex;align-items:baseline}.date-time .timepicker{margin-left:10px}\n"] }]
|
|
2432
|
+
}] });
|
|
2433
|
+
|
|
2434
|
+
/**
|
|
2435
|
+
* Adds drag and drop functionality to an element.
|
|
2436
|
+
*/
|
|
2437
|
+
class DragDropDirective {
|
|
2438
|
+
constructor() {
|
|
2439
|
+
/**
|
|
2440
|
+
* Emits the dropped files to the parent.
|
|
2441
|
+
*/
|
|
2442
|
+
this.files = new EventEmitter();
|
|
2443
|
+
}
|
|
2444
|
+
/**
|
|
2445
|
+
* Prevents the event default.
|
|
2446
|
+
*
|
|
2447
|
+
* @param evt - The Event when dragged files hover over the parent.
|
|
2448
|
+
*/
|
|
2449
|
+
onDragOver(evt) {
|
|
2450
|
+
evt.preventDefault();
|
|
2451
|
+
evt.stopPropagation();
|
|
2452
|
+
}
|
|
2453
|
+
/**
|
|
2454
|
+
* Prevents the event default.
|
|
2455
|
+
*
|
|
2456
|
+
* @param evt - The Event when dragged files leave the parent.
|
|
2457
|
+
*/
|
|
2458
|
+
onDragLeave(evt) {
|
|
2459
|
+
evt.preventDefault();
|
|
2460
|
+
evt.stopPropagation();
|
|
2461
|
+
}
|
|
2462
|
+
/**
|
|
2463
|
+
* Prevents the event default and emits the dropped files with the output.
|
|
2464
|
+
*
|
|
2465
|
+
* @param evt - The Event when files are dropped.
|
|
2466
|
+
*/
|
|
2467
|
+
onDrop(evt) {
|
|
2468
|
+
evt.preventDefault();
|
|
2469
|
+
evt.stopPropagation();
|
|
2470
|
+
if (evt.dataTransfer && evt.dataTransfer.files.length > 0) {
|
|
2471
|
+
this.files.emit(Array.from(evt.dataTransfer.files));
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2475
|
+
DragDropDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DragDropDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2476
|
+
DragDropDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: DragDropDirective, selector: "[dragDrop]", outputs: { files: "files" }, host: { listeners: { "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "drop": "onDrop($event)" } }, ngImport: i0 });
|
|
2477
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DragDropDirective, decorators: [{
|
|
2478
|
+
type: Directive,
|
|
2479
|
+
args: [{
|
|
2480
|
+
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
2481
|
+
selector: '[dragDrop]'
|
|
2482
|
+
}]
|
|
2483
|
+
}], ctorParameters: function () { return []; }, propDecorators: { files: [{
|
|
2484
|
+
type: Output
|
|
2485
|
+
}], onDragOver: [{
|
|
2486
|
+
type: HostListener,
|
|
2487
|
+
args: ['dragover', ['$event']]
|
|
2488
|
+
}], onDragLeave: [{
|
|
2489
|
+
type: HostListener,
|
|
2490
|
+
args: ['dragleave', ['$event']]
|
|
2491
|
+
}], onDrop: [{
|
|
2492
|
+
type: HostListener,
|
|
2493
|
+
args: ['drop', ['$event']]
|
|
2494
|
+
}] } });
|
|
2495
|
+
|
|
2496
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
2497
|
+
class FileInputComponent {
|
|
2498
|
+
constructor(dialog) {
|
|
2499
|
+
this.dialog = dialog;
|
|
2500
|
+
this.FileUtilities = FileUtilities;
|
|
2501
|
+
this.fileDataChangeEvent = new EventEmitter();
|
|
2502
|
+
}
|
|
2503
|
+
async ngOnInit() {
|
|
2504
|
+
this.metadata = EntityUtilities.getPropertyMetadata(this.entity, this.key, DecoratorTypes.FILE_DEFAULT);
|
|
2505
|
+
if (this.metadata.multiple) {
|
|
2506
|
+
this.initMultiFile();
|
|
2507
|
+
}
|
|
2508
|
+
else {
|
|
2509
|
+
this.initSingleFile();
|
|
2510
|
+
}
|
|
2511
|
+
this.fileDataChangeEvent.emit(this.singleFileData ?? this.multiFileData);
|
|
2512
|
+
}
|
|
2513
|
+
initMultiFile() {
|
|
2514
|
+
this.multiFileData = this.entity[this.key];
|
|
2515
|
+
if (this.multiFileData) {
|
|
2516
|
+
this.filenames = this.multiFileData.map(f => f.name);
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
initSingleFile() {
|
|
2520
|
+
this.singleFileData = this.entity[this.key];
|
|
2521
|
+
if (this.singleFileData) {
|
|
2522
|
+
this.filenames = LodashUtilities.cloneDeep([this.singleFileData.name]);
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
async setFileFromInput(event) {
|
|
2526
|
+
const files = event.target.files ?? [];
|
|
2527
|
+
await this.setFile(Array.from(files));
|
|
2528
|
+
}
|
|
2529
|
+
async setFile(files) {
|
|
2530
|
+
// validation done inline
|
|
2531
|
+
if (files.find(f => !FileUtilities.isMimeTypeValid(f.type, this.metadata.allowedMimeTypes))) {
|
|
2532
|
+
this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
2533
|
+
data: this.metadata.mimeTypeErrorDialog,
|
|
2534
|
+
autoFocus: false,
|
|
2535
|
+
restoreFocus: false
|
|
2536
|
+
});
|
|
2537
|
+
this.resetFileInputs();
|
|
2538
|
+
return;
|
|
2539
|
+
}
|
|
2540
|
+
if (files.find(f => FileUtilities.transformToMegaBytes(f.size, 'B') > this.metadata.maxSize)) {
|
|
2541
|
+
this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
2542
|
+
data: this.metadata.maxSizeErrorDialog,
|
|
2543
|
+
autoFocus: false,
|
|
2544
|
+
restoreFocus: false
|
|
2545
|
+
});
|
|
2546
|
+
this.resetFileInputs();
|
|
2547
|
+
return;
|
|
2548
|
+
}
|
|
2549
|
+
let fileSizeTotal = 0;
|
|
2550
|
+
for (const file of files) {
|
|
2551
|
+
fileSizeTotal += file.size;
|
|
2552
|
+
}
|
|
2553
|
+
if (FileUtilities.transformToMegaBytes(fileSizeTotal, 'B') > this.metadata.maxSizeTotal) {
|
|
2554
|
+
this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
2555
|
+
data: this.metadata.maxSizeTotalErrorDialog,
|
|
2556
|
+
autoFocus: false,
|
|
2557
|
+
restoreFocus: false
|
|
2558
|
+
});
|
|
2559
|
+
this.resetFileInputs();
|
|
2560
|
+
return;
|
|
2561
|
+
}
|
|
2562
|
+
if (this.metadata.multiple) {
|
|
2563
|
+
await this.setMultiFile(Array.from(files));
|
|
2564
|
+
}
|
|
2565
|
+
else {
|
|
2566
|
+
await this.setSingleFile(files[0]);
|
|
2567
|
+
}
|
|
2568
|
+
this.fileDataChangeEvent.emit(this.singleFileData ?? this.multiFileData);
|
|
2569
|
+
}
|
|
2570
|
+
resetFileInputs() {
|
|
2571
|
+
this.filenames = undefined;
|
|
2572
|
+
this.singleFileData = undefined;
|
|
2573
|
+
this.multiFileData = undefined;
|
|
2574
|
+
this.fileDataChangeEvent.emit();
|
|
2575
|
+
}
|
|
2576
|
+
async setMultiFile(files) {
|
|
2577
|
+
const data = [];
|
|
2578
|
+
for (const file of files) {
|
|
2579
|
+
const fileData = {
|
|
2580
|
+
file: file,
|
|
2581
|
+
name: file.name,
|
|
2582
|
+
type: file.type,
|
|
2583
|
+
size: file.size
|
|
2584
|
+
};
|
|
2585
|
+
data.push(fileData);
|
|
2586
|
+
}
|
|
2587
|
+
this.multiFileData = LodashUtilities.cloneDeep(data);
|
|
2588
|
+
this.filenames = this.multiFileData.map(f => f.name);
|
|
2589
|
+
}
|
|
2590
|
+
async setSingleFile(file) {
|
|
2591
|
+
this.singleFileData = {
|
|
2592
|
+
file: file,
|
|
2593
|
+
name: file.name,
|
|
2594
|
+
type: file.type,
|
|
2595
|
+
size: file.size
|
|
2596
|
+
};
|
|
2597
|
+
this.filenames = LodashUtilities.cloneDeep([this.singleFileData.name]);
|
|
2598
|
+
}
|
|
2599
|
+
removeFile(name) {
|
|
2600
|
+
if (this.metadata.multiple) {
|
|
2601
|
+
this.filenames?.splice(this.filenames.indexOf(name), 1);
|
|
2602
|
+
if (!this.filenames?.length) {
|
|
2603
|
+
this.filenames = undefined;
|
|
2604
|
+
}
|
|
2605
|
+
const fileDataToRemove = this.multiFileData?.find(f => f.name === name);
|
|
2606
|
+
this.multiFileData?.splice(this.multiFileData.indexOf(fileDataToRemove), 1);
|
|
2607
|
+
if (!this.multiFileData?.length) {
|
|
2608
|
+
this.multiFileData = undefined;
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
else {
|
|
2612
|
+
this.filenames = undefined;
|
|
2613
|
+
this.singleFileData = undefined;
|
|
2614
|
+
}
|
|
2615
|
+
this.fileDataChangeEvent.emit(this.singleFileData ?? this.multiFileData);
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
FileInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FileInputComponent, deps: [{ token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
|
|
2619
|
+
FileInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: FileInputComponent, selector: "file-input", inputs: { entity: "entity", key: "key", getValidationErrorMessage: "getValidationErrorMessage", isReadOnly: "isReadOnly" }, outputs: { fileDataChangeEvent: "fileDataChangeEvent" }, ngImport: i0, template: "<input #fileInput\n type=\"file\" hidden\n [multiple]=\"metadata.multiple\"\n [accept]=\"FileUtilities.getAcceptString(metadata.allowedMimeTypes)\"\n (change)=\"setFileFromInput($event)\"\n>\n\n<mat-form-field [class.readOnly]=\"isReadOnly\" floatLabel=\"always\" (click)=\"!isReadOnly ? fileInput.click() : null\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n [(ngModel)]=\"filenames\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [disabled]=\"isReadOnly\"\n >\n <mat-chip *ngFor=\"let name of filenames\" (removed)=\"removeFile(name)\">\n {{name}}\n <button matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input [matChipInputFor]=\"chipList\" [readonly]=\"true\">\n </mat-chip-list>\n <button mat-icon-button matSuffix [disabled]=\"isReadOnly\">\n <i class=\"fas fa-upload\"></i>\n </button>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>\n\n<div *ngIf=\"metadata.dragAndDrop && !isReadOnly\" class=\"dropdown\" dragDrop (files)=\"setFile($event)\">\n <i class=\"fas fa-file-arrow-up\"></i>\n</div>", styles: ["mat-form-field{width:100%}.readOnly:hover,.readOnly:hover input:hover{cursor:default}input:hover,mat-form-field:hover{cursor:pointer}.dropdown{display:flex;align-items:center;justify-content:center;height:200px;border:2px dashed #757575;border-radius:15px;margin-top:5px;margin-bottom:5px}.dropdown i{font-size:30px}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$6.MatChipList, selector: "mat-chip-list", inputs: ["errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2$6.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { type: i2$6.MatChipRemove, selector: "[matChipRemove]" }, { type: i2$6.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { type: i1$1.MatSuffix, selector: "[matSuffix]" }, { type: i1$1.MatError, selector: "mat-error", inputs: ["id"] }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: DragDropDirective, selector: "[dragDrop]", outputs: ["files"] }] });
|
|
2620
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FileInputComponent, decorators: [{
|
|
2621
|
+
type: Component,
|
|
2622
|
+
args: [{ selector: 'file-input', template: "<input #fileInput\n type=\"file\" hidden\n [multiple]=\"metadata.multiple\"\n [accept]=\"FileUtilities.getAcceptString(metadata.allowedMimeTypes)\"\n (change)=\"setFileFromInput($event)\"\n>\n\n<mat-form-field [class.readOnly]=\"isReadOnly\" floatLabel=\"always\" (click)=\"!isReadOnly ? fileInput.click() : null\">\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-chip-list #chipList\n [(ngModel)]=\"filenames\"\n [name]=\"key.toString()\"\n #model=\"ngModel\"\n [required]=\"metadata.required\"\n [disabled]=\"isReadOnly\"\n >\n <mat-chip *ngFor=\"let name of filenames\" (removed)=\"removeFile(name)\">\n {{name}}\n <button matChipRemove>\n <i class=\"{{metadata.deleteIcon}}\"></i>\n </button>\n </mat-chip>\n <input [matChipInputFor]=\"chipList\" [readonly]=\"true\">\n </mat-chip-list>\n <button mat-icon-button matSuffix [disabled]=\"isReadOnly\">\n <i class=\"fas fa-upload\"></i>\n </button>\n <mat-error>{{getValidationErrorMessage(model)}}</mat-error>\n</mat-form-field>\n\n<div *ngIf=\"metadata.dragAndDrop && !isReadOnly\" class=\"dropdown\" dragDrop (files)=\"setFile($event)\">\n <i class=\"fas fa-file-arrow-up\"></i>\n</div>", styles: ["mat-form-field{width:100%}.readOnly:hover,.readOnly:hover input:hover{cursor:default}input:hover,mat-form-field:hover{cursor:pointer}.dropdown{display:flex;align-items:center;justify-content:center;height:200px;border:2px dashed #757575;border-radius:15px;margin-top:5px;margin-bottom:5px}.dropdown i{font-size:30px}\n"] }]
|
|
2623
|
+
}], ctorParameters: function () { return [{ type: i1.MatDialog }]; }, propDecorators: { entity: [{
|
|
2624
|
+
type: Input
|
|
2625
|
+
}], key: [{
|
|
2626
|
+
type: Input
|
|
2627
|
+
}], getValidationErrorMessage: [{
|
|
2628
|
+
type: Input
|
|
2629
|
+
}], isReadOnly: [{
|
|
2630
|
+
type: Input
|
|
2631
|
+
}], fileDataChangeEvent: [{
|
|
2632
|
+
type: Output
|
|
2633
|
+
}] } });
|
|
2634
|
+
|
|
2635
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
2636
|
+
class FileDefaultInputComponent extends NgxMatEntityBaseInputComponent {
|
|
2637
|
+
constructor() {
|
|
2638
|
+
super(...arguments);
|
|
2639
|
+
this.FileUtilities = FileUtilities;
|
|
2640
|
+
}
|
|
2641
|
+
async refreshFileData(fileData) {
|
|
2642
|
+
this.propertyValue = fileData;
|
|
2643
|
+
this.emitChange();
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
FileDefaultInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FileDefaultInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2647
|
+
FileDefaultInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: FileDefaultInputComponent, selector: "file-default-input", usesInheritance: true, ngImport: i0, template: "<div [class.file-input]=\"metadata.dragAndDrop\" [class.mat-elevation-z8]=\"metadata.dragAndDrop\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [entity]=\"entity\"\n [key]=\"key\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n >\n </file-input>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}\n"], components: [{ type: FileInputComponent, selector: "file-input", inputs: ["entity", "key", "getValidationErrorMessage", "isReadOnly"], outputs: ["fileDataChangeEvent"] }] });
|
|
2648
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FileDefaultInputComponent, decorators: [{
|
|
2649
|
+
type: Component,
|
|
2650
|
+
args: [{ selector: 'file-default-input', template: "<div [class.file-input]=\"metadata.dragAndDrop\" [class.mat-elevation-z8]=\"metadata.dragAndDrop\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [entity]=\"entity\"\n [key]=\"key\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n >\n </file-input>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}\n"] }]
|
|
2651
|
+
}] });
|
|
2652
|
+
|
|
2653
|
+
// eslint-disable-next-line max-len
|
|
2654
|
+
const placeholder = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAAMgCAMAAAAEPmswAAAANlBMVEXx8/XCy9LFztXu8PPs7/Lp7e/W3OHL0tnZ3+PN1NrS2d7i5urn6u7f5OjI0Nfc4ebP1tzk6excnoRZAAAXh0lEQVR42uzUAQ0AAAzDoN+/6eloAiK4B4gQFpAhLCBDWECGsIAMYQEZwgIyhAVkCAvIEBaQISwgQ1hAhrCADGEBGcICMoQFZAgLyBAWkCEsIENYQIawgAxhARnCAjKEBWQIC8gQFpAhLCBDWECGsIAMYQEZwgIyhAVkCAvIEBaQISwgQ1hAhrCADGEBGcICMoQFZAgLyBAWkCEsIENYQIawgAxhARnCAjKEBWQIC8gQFpAhLGDs1AEJAAAAgKD/r9sR6Ag3hAVsCAvYEBawISxgQ1jAhrCADWEBG8ICNoQFbAgL2BAWsCEsYENYwIawgA1hARvCAjaEBWwIC9gQFrAhLGBDWMCGsIANYQEbwgI2hAVsCAvYEBawISxgQ1jAhrCADWEBG8ICNoQFbAgL2BAWsCEsYENYwIawgA1hARvCAjaEBWwIC9gQFrAhLGBDWMCGsIANYQEbwgI2hAVsCAvYEBbETh2QAAAAAAj6/7odgY6QDWEBG8ICNoQFbAgL2BAWsCEsYENYwIawgA1hARvCAjaEBWwIC9gQFrAhLGBDWMCGsIANYQEbwgI2hAVsCAvYEBawISxgQ1jAhrCADWEBG8ICNoQFbAgL2BAWsCEsYENYwIawgA1hARvCAjaEBWwIC9gQFrAhLGBDWMCGsIANYQEbwgI2hAVsCAvYEBawISxgQ1jAhrCADWEBG8ICNoRF7NQBCQAAAICg/6/bEegIYUNYwIawgA1hARvCAjaEBWwIC9gQFrAhLGBDWMCGsIANYQEbwgI2hAVsCAvYEBawISxgQ1jAhrCADWEBG8ICNoQFbAgL2BAWsCEsYENYwIawgA1hARvCAjaEBWwIC9gQFrAhLGBDWMCGsIANYQEbwgI2hAVsCAvYEBawISxgQ1jAhrCADWEBG8ICNoQFbAgL2BAWsCEsYENYwIawgA1hxc6dJtcKAgEURgREwGn/m32Vd1Op/Ih3cO72fIs4BU0rADEIFgAxCBYAMQgWADEIFgAxCBbwm+3bFOKQ8zSV4r13zvky5a4bYgxjYyuch2ABD7ZJMRdnXnIlDyE1FY5HsADbhmFy5lM+x7GvcCSChXtrQufNCnXpQlvhIAQLt2XHONVmE2VIzLaOQLBwT230ZlsuBy6IeyNYuB+bOmd24TpOWrsiWLiZJhazKz8w09oNwcKd9NGbA9SZg9Y+CBZuw4ZijlMiE63tESzcg02TOZqnWVsjWLiDpqvNKXxkI35LBAv6pWJO5APzrM0QLChnozNnm5jBb4RgQbU2m0uoO3YdtkCwoFjy5jp85Ji1GsGCWpfK1X95rLAKwYJS4XK54pi1HsGCSuH8SfucjkWH5QgWFLpwrr6UVGEZggV10rVz9cVxM1yGYEGZthgJ6oHPdhYgWFClv8jeFcOsfRAsKGIHI8rENumHCBb0iLWRhvn7ZwgWtGgvuXj1kidZHyBY0MF2RiqS9T6CBRWCvNsgyVqAYEGBRsYqA8lajWBBPGlvg38rvBi+gWBBuvb6i+3vmdjLeolgQTYdx6tvme33FwgWRBO6yzBr4BvDpwgWJNN0vHqo+Sz6GYIFuRplx6sHx4PhPIIFsaJRigfDWQQLQvXid6+Yvn+OYEGmUfRq+2uMsv5EsCCSvmk7o6x3ECwIpPo6yCLpEwQL8iTl10G2smYRLIij/zrIvXAOwYIwvcrlq1kT74W/ESzIMmr51Plddazwg2BBlGDux7NH+oNgQRK5/0Fm+L4JgvWPvbvRSRiGAjBaBoqK+PP+L2s0xGSj3QiQ9I57zkN86brblvVItn1l8/2cYLEar1mmGWoOFlm/BIu1yLh9ZZE1IVisRNLtK4usEcFiFYbvwtYiS7BYg7zb7WPfFlmCRXj7bNOiFlkNgkV8j373lZ2siwkW4SX/PTi1+9pkJljEluhyhgsdMy+yBIvQDoWpXeLThYJFYMYZ6vJe4SBYxDWkuAv5Gu9Z78kSLMIajF8ZcBgRLOL6MH5l731MsAhrb/zK3vuEYBFV6ttk7L3XCRZBvRUcLpwSLGLSK3PvFYJFSHrls7BGsIhIr3wWVgkWATnu7G9hnWARj175LGwQLMLRK5+FLYJFNHp1jd1+k4NgEYpeXel5k4JgEYleXe24yUCwCESvXDkzR7CIxPzVTbYJxt4FizD0ynzDPMEiDr3yCtgCwSKMr8Ltnh58I0uwiOG1cA/bxz6oI1iE4L4+E1nLBIsY3IdsIusCgkUI3pu4q/fH3XoXLPob9OqXo4VLBIsAvD944tnCBYJFAN53PjFDukCw6O9Q+GPrfYlg0d2x8M+tfrMEi94+CyOm3tsEi65cKDNl6n2OYNGTA89Vpt5bBIuOHCCs8rOwSbDoaW9gtMbPwhbBohsD7k1+FjYIFv0MBkbb/CysESx6MTA6z8nCCsGiEwNYS7xOcU6w6OWlsMB4ww9794LdJgyEUXgwAsfFL/a/2Z4+T2zjWCMgnl/cbwttbxppNNwjWHgLBrByMN5wj2Ct4HztL+OxS621qTuOp/5a06HnItgw+v0uTRUI1qL2/dDao3b8qO+RRDkGGt5haGpAsJZzPbX2XDvUc/I5ExuwsrE4+QbBWsz+I9kr6VLR/XI5Nsq8SVdBsQjWIg6D5Rn5bxYbGpwYyPqPYC3iMFq+4+aTxSeevdg38xfBWsB5MJ+j/s+5Oc5cEDoxQvoPwZrvozW3SwWHCWX4RM67iX9Oh2DNc+isRFL/QVduNBRg6P0XgjVTv/nJYx9eEAYgXSyCNcNu2PpUjBMXhCEo/7AkWKVm78tM8jc2XqxEDkL4mQ7BKnZot35j48QFYRi6z3QIVqlru/kbGx8uCAORLRbBKvSD808nVoxGorrpnWCVuTIV48TKvlhEL30IVoEl1zlt5xyLlX2xaBaLYJU4J153+bCyLx7J5Q0Ey23hw+Ok+NfGiwP3iBSLRbAKDLaksdkCDtwDSnrLuwmWX29mDB57MOEelF6xCJbTGocx9R9jMeEelNxKP4Ll1tlvHGPl4psTgbVixSJYXr39wS+FuVgpE5lYsQiW0661FcgdJTiwUiY2rd8KCZbTyf7ipjAPO9yjk/o/FsHy2dstBt5fYEVDfErFIlg+g63j2FSLidHwhJ5bECyXs33GaMNLfDRVgk6xCJbLyT7jFOsVJkZFyBSLYHnsbD1C5wgOe4MElWIRLI/e7rFn+ws8eRYiUiyC5dHZelJTIZ4869C4KyRYDnu7x2TDF9gxqkWiWATL4WJrOjW14cmzFoViESyHZGtqm8rw5FmNwCsdgpXvbI8YxXqGJ8+C4heLYOXr7RE7G57gAEtS+I1+BCvfyaYwOzqFAyxR0YtFsPIle8Qh1iQOsGQFLxbByrazCQy7T2ICS1fsb+kQrGwHe4rPQN/iCaGy0MUiWNl6m8Kp+yN2YGmL/E1ogpXtYtMYHb3HDixxgYtFsLIN9gRb/G6xxF1e3AtrgpXtaM/w/vkzlrhXYGiCIljZOntAsKbsOMDSF7VYBCtbsrVV8ofBk5waBD1QreTfyPoIVh6e5NQi5kbJOv6NfAtbX9zLmVw8yanHT/buBDt1GIbCsJwRCOP+N/t62vNaphLbSZEs/98O2gOXyJFkk102BFYkAisGIzmeDMEeAitaK09REl5hJMcVg6MXHr4jb8EZVgRGcpyxl1gOviPv0stzrGv4MdLR4Iu5pZIEViQaR+cxkuOOucu/CKxIjObMYiTHIWsXUxBY0TbynPtevUiM5LhkbKEfgRWJ9TIz6GhwytZ6LAIrEgv8ZtDR4JWpZTMEViRWJM/ZCXyytGyGwIrFJRSvsGTUM0OHqwRWLK75eoUdDa7ZGYQmsOLt5CnO3EOgxd05M59NAisWV9W/MgpcszIITWAl6OUeR1ifaHH37xxMILASnOSBz5NNY/8ZGGBkSIfASjDKDZ8/YelY2lcFG0M6BFaKXh4w+UyLeyU6Cw2kBFaKQW75fHOc7CCogYUhHQIrRSN3aHMPtLjXw0CnIIGV5CT3vN8DN4eCsCb6L4YIrCRHuUYTVgi0uFdFvYGUwEpzkP/cPWxnocW9MkPQRGClGuUKPQ1sca/OOSgisJId5BsnWB/2gqqoNpASWMmaVv6ArTW00biXvkLtMaghsNIN8snXUWYeZp6rpNiORWBl2Mva+lAqZp5rtA9aCKxk36s1aWlg5rlWU1BCYOXYyQcKQmae63UKOgisLAcRoQWLgrBiQ1BBYGVpem8z8BkoCKt2DhoIrDzHztmWoXQUhHXT+dwSWJnGtvoDd2ae66ZSGRBYubbVX/ZMQVg5jXYsAivbueyzSyN/Pwo2hbcjsPJt25qfrygIodDcQGAtMHZlj5EuwFZkqBQIBNYSx16W6Ip9P0hBCJ3mBgJrkeYg+S7F9l9REEKpuYHAWmiobx4nBApCKDU3EFhLjb3k6As+vuKaHGhtbiCwlhvayh6vKAihdZEOgbWCZpI0l2L3i36ZBFD59SWwVjFOKXFVdDUYKAih101IYK0iIbKm0uMqNFyTA615WAJrNcdNL3O6TcGtV18oCKH4qpDAWtP21MnvukOxdw/+oCCE5qtCAmtlx2Hq5FE7DQ6erUKgIITqHDSB9Qea7XCaLvu+a7u+30+nYVtwT/stCkKovioksJCAgvAfe3eU6ygMBFG0GhtCSAxh/5udUWby8Z4COGCgI92ziJLLuBuc+6mQwEI+nozi9KlCAgu5KIQ4/VMhgYVMFEKc/6mQwEIeCiEcTBUSWMhDIYSDBaQEFrJQCOFhASmBhRwUQiwLve2LwEIetozCxb8KCSxk4LcT8DGjQ2BhGYUQTmZ0CCwsoxDCyYwOgYVFFEJ4mdEhsLCEQgg3MzoEFpZQCPGJ0XZDYGERhRCfGWwvBBaWUAjh6OKdwMI8CiE+drF9EFhYQCGEp4t3AgtzKIRwdfFOYGEOhRCuLt4JLMy6CvBz8U5gYU5VC/Dz4p3AwpxBgKNVMwQWJlEI4W3VDIGFGRRC+Fo1Q2BhCoUQ7na8E1iYdBHga8c7gYUJFEL4u3gnsDClFeDs4p3AwjsUQrj8uarsCP21a4Z0G+sYQwiSQoixvo9paJvHpTI4RCFEAVcrSrar/tEMY9SCeL+1zaM3OEIhhMPFDbK9VF07Bn2kTs2V45YPFEJ4XNwg20PfpKgJOallONtdgL/FDbLSqi7V2qpOHUetU1AI8eR0cYOsqKq7BRVybzlpHY5CiH+cvh+VlVN1o8oKt4ar+CNRCPHi8/2orJRrCtpDTA/DISiE2EeyUmRFVG3UfgKZdQAKIX7y+H5UVkA/BP1GZn0vCiGeHP74S7bZJek9Mus7NQL+8vh+VLZRlXSckC6GnfUCnhyOQcu2aYOOVTc80CqOQoj33O0flW3RRR0vJN5nlUUhxAR3Y9Cy9aqb8nHM+g59EPDi7hpLtloXdCKOWYVQCDHP1Ri0LJOf49VL3Rm2ohBiga9rLFkeX8er/yLNcBsKIXI4+o2ObAU//38KA7OGJY0CfvM0Bi1bofd00cHTrLUohDja3TaSfe4R5crIC/gVKIR/2Lvb5NRhGArD54RvCC3sf7N3Op07UyhJ7PQHsvU+W4BxIvlIQbkw2/zkMrFH+em/V6MgRKlIbSy50hDzX82RVYeCEMUitbHkOh9hP/60ozAsRkGIGoHaWHKVQ7D21YORI6sCkVGUC9PGkqcFTV9xZP0RBSGqRWljyb+1/J/myKrAllG8w2bwavKEwGnReXdyWXMoCPF2o1eTi719eLDUlYGdOa1kVdCvo9eSH/RwXkmbI0fWSxSEiOHmleRnTcWvpmz3RoWwYRX0afVuLLnI0FyLg1jWMwpCxHH3OnKJocUn8Ej3/QcKQoRy9Cryt/7OK7rvDygIEcvJa8hf+jyvaGX91HpcBZ1Z18aS7W7PK0kjq9+XnAS8wcUryO75vKIutE1BiJD2rifb7ut+8NmGupCCEBEdXE3dn1eSdtSFFISIZze4lvxf10soqQsnDJH3BaF3V9dSivNK2rKR9KWrgPc5u5LcyfzgogsfBPvtJuB96hcmK08/luY7BSGi2bmOMk2YMazT8Rs02vTpKvKks/pzNPr+hdGam2soWXuDhAOfyUEodSM68oRTr//mTxIOvV0Bo2l3V5BfO/R6XvGS1dAnRZDC3uWU8fro02AJFsI4uJhSfkNlx3UhM88Io2JER0nzz+mvC/vK2KFtV5dSigAWL1nMPCOyswspbzwn80tW3z1KNKd4REeJH75j3ulCIu6IZXQZ+dlHnofvJusKhyTv0GjI0UXU20bkOpeUKVIi7ojn5BJKXixsM6ZIOw+toEllIzpKeEGYPUWa7zdGC64uIJob2XrvaS5V0JizlynLBCGb/Ug0ILbN4EXK23BP2ntP1qREQ+5eJPaNfNmmyb2zowFx7b1ENGO/JSkLcxb9aMXBC5S74Z6uLMxa9KMNOy8Qz95MkSx2NCC2q+cpfcM90zh0n3v60ZObZ4nLox/ufZeFQ/aXaMS3EHgXl0d5ysK8t8Box8VzRPo5zW1h6ltgNGPvGSL9nOW2kAYWmjC7zE80sJIsT+ahhEaMniZqhSR7/f6xdy+4iQNBEEDdQYEA4Xf/y+5ukk2AYAkFKXKX3ztEWe6p6THAoouXGjUYYM1j5YyPEn2saszgX2EWK2cMsGhk/KHCwb/CTYtjJfFRopVDjRj8K8yh9m4pMr0c67bBAGsG/QZXCGlmrPA++FcY9ZwyyJr5Hg462tZNA/GDLK960dCmvhNYMxhk2cNBR7cK7wJrBoOs3QANneobgZU/yLKHg6aWdU1gxQ+ynALT1qquCKz0jTMao/T1WlcE1l121ZbGKI291CWBdZ/XrqN3A3daW9UFgZX90KqBO7091wWBFb0jy8Cd7g51TmAld0g13OlvXWcEVnCHVMOdABe3oAVW8Ojdon4S7OqLwModvdtzRoZjfRJYsaN3K2UIcfZTKLBSR+8OCImxrf8EVmjr3QEhQTb1QWBljt4dEJJk8VTvBFbm6N1DSETZ1juBFblwxpsThNnUG4GVuHBGoYE0Hz+FAivwsNCNZ/Js6x+B9VPbmiqP0pNoWX8JrLjDwpVCA4nefgoFVtph4d5KZDKdqkpgPWCxrslRwCLWskpgPWRyNwufrHAn1mJfAivqsFBekexUAivqZqGCO9GWAutRpwkdFtrYR7bFXmDlPGXvSS/SnQRWTL1BXpHPNY6Uu9AuPDMDatEhd6HlFdCl3iCvgC71BnkFdLkLbd4OdKk3yCugS71BXgFd6g367UCTeoP7zsAPHeoe9l8BU7CrX7WyXxRoUm9Yu6gA/GHvDnMThmEwgNZpF9LQUrj/ZfdvmmBMDEabSu8dIkrsz85O4g3VeQW8ZhjjPv+lAk3pa9whzgA0J8ePxBmABs3xZqP2ILCTVe/2LgI7aRYm04NA1+1iFvog3Q503S6ahZ6DwJe2FycnaQbgLY4p/lnVHQS+abj07noFXGl2TsfsIHCrydS76xVwq8lCViquV8D7fRwU24HdyPGa0aQzsJrpFM8bFa+ANfUlnnS+dADrGmo8oZobBLYwLKf4k1NRagc2M9UUD0rZWxDYVj8/cmalOotdAS2Yyhi/OBcpBqAh/WXJY4or6ZwXhxXQpGE6znMpOZdlmY+TVyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDJHhwIAAAAAAD5vzaCqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqwBwcCAAAAAED+r42gqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqirswYEAAAAAAJD/ayOoqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkp7cCAAAAAAIMjfepArAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgKcAnTNeiLeG1rEAAAAASUVORK5CYII=';
|
|
2655
|
+
|
|
2656
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
2657
|
+
class FileImageInputComponent extends NgxMatEntityBaseInputComponent {
|
|
2658
|
+
constructor() {
|
|
2659
|
+
super(...arguments);
|
|
2660
|
+
this.FileUtilities = FileUtilities;
|
|
2661
|
+
this.imageIndex = 0;
|
|
2662
|
+
this.placeHolder = placeholder;
|
|
2663
|
+
}
|
|
2664
|
+
async setSinglePreviewImage() {
|
|
2665
|
+
if (this.propertyValue) {
|
|
2666
|
+
this.propertyValue = await FileUtilities.getFileData(this.propertyValue);
|
|
2667
|
+
this.singlePreviewImage = await FileUtilities.getDataURLFromFile(this.propertyValue.file);
|
|
2668
|
+
}
|
|
2669
|
+
else {
|
|
2670
|
+
this.singlePreviewImage = undefined;
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
async setMultiPreviewImages(index) {
|
|
2674
|
+
const multiFileData = this.propertyValue;
|
|
2675
|
+
const previewImages = [];
|
|
2676
|
+
if (multiFileData?.length) {
|
|
2677
|
+
for (let i = 0; i < multiFileData.length; i++) {
|
|
2678
|
+
if (i === index) {
|
|
2679
|
+
multiFileData[index] = await FileUtilities.getFileData(multiFileData[index]);
|
|
2680
|
+
previewImages.push(await FileUtilities.getDataURLFromFile(multiFileData[index].file));
|
|
2681
|
+
}
|
|
2682
|
+
else {
|
|
2683
|
+
previewImages.push('empty');
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
this.multiPreviewImages = previewImages;
|
|
2688
|
+
}
|
|
2689
|
+
async refreshFileData(fileData) {
|
|
2690
|
+
this.propertyValue = fileData;
|
|
2691
|
+
this.emitChange();
|
|
2692
|
+
if (this.metadata.multiple) {
|
|
2693
|
+
fileData = fileData;
|
|
2694
|
+
if (!fileData?.[this.imageIndex]) {
|
|
2695
|
+
this.imageIndex = 0;
|
|
2696
|
+
}
|
|
2697
|
+
await this.setMultiPreviewImages(this.imageIndex);
|
|
2698
|
+
}
|
|
2699
|
+
else {
|
|
2700
|
+
await this.setSinglePreviewImage();
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
async prev() {
|
|
2704
|
+
if (this.imageIndex <= 0) {
|
|
2705
|
+
return;
|
|
2706
|
+
}
|
|
2707
|
+
await this.setMultiPreviewImages(this.imageIndex - 1);
|
|
2708
|
+
this.imageIndex--;
|
|
2709
|
+
}
|
|
2710
|
+
async next() {
|
|
2711
|
+
if (!this.multiPreviewImages?.length) {
|
|
2712
|
+
return;
|
|
2713
|
+
}
|
|
2714
|
+
if (this.imageIndex === (this.multiPreviewImages.length - 1)) {
|
|
2715
|
+
return;
|
|
2716
|
+
}
|
|
2717
|
+
await this.setMultiPreviewImages(this.imageIndex + 1);
|
|
2718
|
+
this.imageIndex++;
|
|
2719
|
+
}
|
|
2720
|
+
async setIndex(index) {
|
|
2721
|
+
await this.setMultiPreviewImages(index);
|
|
2722
|
+
this.imageIndex = index;
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
FileImageInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FileImageInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2726
|
+
FileImageInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: FileImageInputComponent, selector: "file-image-input", usesInheritance: true, ngImport: i0, template: "<div *ngIf=\"!metadata.dragAndDrop && !metadata.preview\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [entity]=\"entity\"\n [key]=\"key\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n >\n </file-input>\n</div>\n\n<div *ngIf=\"metadata.dragAndDrop || metadata.preview\" class=\"file-input mat-elevation-z8\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [entity]=\"entity\"\n [key]=\"key\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n >\n </file-input>\n\n <div class=\"image-preview\" *ngIf=\"metadata.preview && metadata.multiple\">\n <i (click)=\"prev()\" [class.disabled]=\"imageIndex === 0\" class=\"prev-button fa-solid fa-angle-left\"></i>\n <img *ngIf=\"multiPreviewImages?.[imageIndex]\" class=\"mat-elevation-z2\" [src]=\"multiPreviewImages?.[imageIndex]\">\n <img *ngIf=\"!multiPreviewImages?.[imageIndex]\" class=\"mat-elevation-z2\" [src]=\"metadata.previewPlaceholderUrl ?? placeHolder\">\n <i (click)=\"next()\"\n [class.disabled]=\"!multiPreviewImages || !multiPreviewImages.length || imageIndex === (multiPreviewImages.length - 1)\"\n class=\"next-button fa-solid fa-angle-right\"\n >\n </i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && metadata.multiple\">\n <button (click)=\"setIndex(imageIndex-4)\" mat-icon-button *ngIf=\"\n this.multiPreviewImages\n && multiPreviewImages[imageIndex-4]\n && imageIndex === (this.multiPreviewImages.length - 1)\"\n >\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 3}}</span>\n </button>\n <!-- eslint-disable-next-line @angular-eslint/template/conditional-complexity -->\n <button (click)=\"setIndex(imageIndex-3)\" mat-icon-button *ngIf=\"this.multiPreviewImages\n && multiPreviewImages[imageIndex-3]\n && (\n imageIndex === (this.multiPreviewImages.length - 2)\n || imageIndex === (this.multiPreviewImages.length - 1)\n )\"\n >\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 2}}</span>\n </button>\n <button (click)=\"setIndex(imageIndex-2)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex-2]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 1}}</span>\n </button>\n <button (click)=\"setIndex(imageIndex-1)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex-1]\">\n <i class=\"dot\"></i>\n <span class=\"image-index\">{{imageIndex}}</span>\n </button>\n <button mat-icon-button disabled>\n <i class=\"dot selected\"></i>\n <span class=\"image-index\">{{imageIndex + 1}}</span>\n </button>\n <button (click)=\"setIndex(imageIndex+1)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+1]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 2}}</span>\n </button>\n <button (click)=\"setIndex(imageIndex+2)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+2]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 3}}</span>\n </button>\n <button (click)=\"setIndex(imageIndex+3)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+3] && imageIndex <= 1\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 4}}</span>\n </button>\n <button (click)=\"setIndex(imageIndex+4)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+4] && imageIndex === 0\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 5}}</span>\n </button>\n </div>\n\n <div class=\"image-preview\" *ngIf=\"metadata.preview && !metadata.multiple\">\n <i class=\"prev-button disabled fa-solid fa-angle-left\"></i>\n <img class=\"mat-elevation-z2\" [src]=\"singlePreviewImage ?? metadata.previewPlaceholderUrl ?? placeHolder\">\n <i class=\"next-button disabled fa-solid fa-angle-right\"></i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && !metadata.multiple\">\n <button disabled mat-icon-button>\n <span class=\"dot selected\"></span>\n <span class=\"image-index\">1</span>\n </button>\n </div>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}.image-preview{height:250px;display:flex;align-items:center;padding-top:15px;padding-bottom:15px}.image-preview .prev-button{font-size:100px;margin-left:5px}.image-preview .next-button{font-size:100px;margin-right:5px}.image-preview .prev-button:hover,.image-preview .next-button:hover{cursor:pointer}.image-preview .prev-button.disabled,.image-preview .next-button.disabled{color:#00000042}.image-preview .prev-button.disabled:hover,.image-preview .next-button.disabled:hover{cursor:default}.image-preview img{max-width:calc(100% - 100px);max-height:100%;margin-left:auto;margin-right:auto;border-radius:3px}.preview-nav{text-align:center}.preview-nav button{display:inline-block;width:18px;height:18px;margin-left:5px;margin-right:5px}.preview-nav button .dot{height:100%;width:100%;background-color:#00000061;border-radius:50%;display:block}.preview-nav button .dot.selected{background-color:#000000de}.preview-nav button .image-index{position:absolute;height:100%;width:100%;display:block;top:-11.5px;color:#fff}.preview-nav button:hover{background-color:#000}\n"], components: [{ type: FileInputComponent, selector: "file-input", inputs: ["entity", "key", "getValidationErrorMessage", "isReadOnly"], outputs: ["fileDataChangeEvent"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
2727
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FileImageInputComponent, decorators: [{
|
|
2728
|
+
type: Component,
|
|
2729
|
+
args: [{ selector: 'file-image-input', template: "<div *ngIf=\"!metadata.dragAndDrop && !metadata.preview\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [entity]=\"entity\"\n [key]=\"key\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n >\n </file-input>\n</div>\n\n<div *ngIf=\"metadata.dragAndDrop || metadata.preview\" class=\"file-input mat-elevation-z8\">\n <file-input\n (fileDataChangeEvent)=\"refreshFileData($event)\"\n [entity]=\"entity\"\n [key]=\"key\"\n [getValidationErrorMessage]=\"getValidationErrorMessage\"\n [isReadOnly]=\"isReadOnly\"\n >\n </file-input>\n\n <div class=\"image-preview\" *ngIf=\"metadata.preview && metadata.multiple\">\n <i (click)=\"prev()\" [class.disabled]=\"imageIndex === 0\" class=\"prev-button fa-solid fa-angle-left\"></i>\n <img *ngIf=\"multiPreviewImages?.[imageIndex]\" class=\"mat-elevation-z2\" [src]=\"multiPreviewImages?.[imageIndex]\">\n <img *ngIf=\"!multiPreviewImages?.[imageIndex]\" class=\"mat-elevation-z2\" [src]=\"metadata.previewPlaceholderUrl ?? placeHolder\">\n <i (click)=\"next()\"\n [class.disabled]=\"!multiPreviewImages || !multiPreviewImages.length || imageIndex === (multiPreviewImages.length - 1)\"\n class=\"next-button fa-solid fa-angle-right\"\n >\n </i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && metadata.multiple\">\n <button (click)=\"setIndex(imageIndex-4)\" mat-icon-button *ngIf=\"\n this.multiPreviewImages\n && multiPreviewImages[imageIndex-4]\n && imageIndex === (this.multiPreviewImages.length - 1)\"\n >\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 3}}</span>\n </button>\n <!-- eslint-disable-next-line @angular-eslint/template/conditional-complexity -->\n <button (click)=\"setIndex(imageIndex-3)\" mat-icon-button *ngIf=\"this.multiPreviewImages\n && multiPreviewImages[imageIndex-3]\n && (\n imageIndex === (this.multiPreviewImages.length - 2)\n || imageIndex === (this.multiPreviewImages.length - 1)\n )\"\n >\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 2}}</span>\n </button>\n <button (click)=\"setIndex(imageIndex-2)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex-2]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex - 1}}</span>\n </button>\n <button (click)=\"setIndex(imageIndex-1)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex-1]\">\n <i class=\"dot\"></i>\n <span class=\"image-index\">{{imageIndex}}</span>\n </button>\n <button mat-icon-button disabled>\n <i class=\"dot selected\"></i>\n <span class=\"image-index\">{{imageIndex + 1}}</span>\n </button>\n <button (click)=\"setIndex(imageIndex+1)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+1]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 2}}</span>\n </button>\n <button (click)=\"setIndex(imageIndex+2)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+2]\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 3}}</span>\n </button>\n <button (click)=\"setIndex(imageIndex+3)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+3] && imageIndex <= 1\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 4}}</span>\n </button>\n <button (click)=\"setIndex(imageIndex+4)\" mat-icon-button *ngIf=\"multiPreviewImages?.[imageIndex+4] && imageIndex === 0\">\n <span class=\"dot\"></span>\n <span class=\"image-index\">{{imageIndex + 5}}</span>\n </button>\n </div>\n\n <div class=\"image-preview\" *ngIf=\"metadata.preview && !metadata.multiple\">\n <i class=\"prev-button disabled fa-solid fa-angle-left\"></i>\n <img class=\"mat-elevation-z2\" [src]=\"singlePreviewImage ?? metadata.previewPlaceholderUrl ?? placeHolder\">\n <i class=\"next-button disabled fa-solid fa-angle-right\"></i>\n </div>\n <div class=\"preview-nav\" *ngIf=\"metadata.preview && !metadata.multiple\">\n <button disabled mat-icon-button>\n <span class=\"dot selected\"></span>\n <span class=\"image-index\">1</span>\n </button>\n </div>\n</div>", styles: [".file-input{margin-top:15px;margin-bottom:15px;padding:15px;border-radius:5px}.image-preview{height:250px;display:flex;align-items:center;padding-top:15px;padding-bottom:15px}.image-preview .prev-button{font-size:100px;margin-left:5px}.image-preview .next-button{font-size:100px;margin-right:5px}.image-preview .prev-button:hover,.image-preview .next-button:hover{cursor:pointer}.image-preview .prev-button.disabled,.image-preview .next-button.disabled{color:#00000042}.image-preview .prev-button.disabled:hover,.image-preview .next-button.disabled:hover{cursor:default}.image-preview img{max-width:calc(100% - 100px);max-height:100%;margin-left:auto;margin-right:auto;border-radius:3px}.preview-nav{text-align:center}.preview-nav button{display:inline-block;width:18px;height:18px;margin-left:5px;margin-right:5px}.preview-nav button .dot{height:100%;width:100%;background-color:#00000061;border-radius:50%;display:block}.preview-nav button .dot.selected{background-color:#000000de}.preview-nav button .image-index{position:absolute;height:100%;width:100%;display:block;top:-11.5px;color:#fff}.preview-nav button:hover{background-color:#000}\n"] }]
|
|
2730
|
+
}] });
|
|
2731
|
+
|
|
2732
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
2733
|
+
class CustomInputComponent extends NgxMatEntityBaseInputComponent {
|
|
2734
|
+
constructor(viewContainerRef) {
|
|
2735
|
+
super();
|
|
2736
|
+
this.viewContainerRef = viewContainerRef;
|
|
2737
|
+
}
|
|
2738
|
+
ngOnInit() {
|
|
2739
|
+
super.ngOnInit();
|
|
2740
|
+
this.component = this.viewContainerRef.createComponent(this.metadata.component);
|
|
2741
|
+
this.component.instance.entity = this.entity;
|
|
2742
|
+
this.component.instance.key = this.key;
|
|
2743
|
+
this.component.instance.getValidationErrorMessage = this.getValidationErrorMessage;
|
|
2744
|
+
this.component.instance.inputChangeEvent.subscribe(this.inputChangeEvent);
|
|
2745
|
+
this.component.instance.isReadOnly = this.isReadOnly;
|
|
2746
|
+
}
|
|
2747
|
+
}
|
|
2748
|
+
CustomInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: CustomInputComponent, deps: [{ token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2749
|
+
CustomInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: CustomInputComponent, selector: "custom-input", usesInheritance: true, ngImport: i0, template: "", styles: [""] });
|
|
2750
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: CustomInputComponent, decorators: [{
|
|
2751
|
+
type: Component,
|
|
2752
|
+
args: [{ selector: 'custom-input', template: "", styles: [""] }]
|
|
2753
|
+
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }]; } });
|
|
2754
|
+
|
|
2755
|
+
/**
|
|
2756
|
+
* The default input component. It gets the metadata of the property from the given @Input "entity" and @Input "propertyKey"
|
|
2757
|
+
* and displays the input field accordingly.
|
|
2758
|
+
*
|
|
2759
|
+
* You can also define a method that generates error-messages and if the input should be hidden when its metadata says
|
|
2760
|
+
* that it should be omitted for creating or updating.
|
|
2761
|
+
* The last part being mostly relevant if you want to use this component inside an ngFor.
|
|
2762
|
+
*/
|
|
2763
|
+
class NgxMatEntityInputComponent {
|
|
2764
|
+
constructor(dialog) {
|
|
2765
|
+
this.dialog = dialog;
|
|
2766
|
+
this.inputChangeEvent = new EventEmitter();
|
|
2767
|
+
this.selection = new SelectionModel(true, []);
|
|
2768
|
+
this.isArrayItemValid = false;
|
|
2769
|
+
this.isDialogArrayItemValid = false;
|
|
2770
|
+
this.DecoratorTypes = DecoratorTypes;
|
|
2771
|
+
this.EntityUtilities = EntityUtilities;
|
|
2772
|
+
this.DateUtilities = DateUtilities;
|
|
2773
|
+
}
|
|
2774
|
+
/**
|
|
2775
|
+
* This is needed for the inputs to work inside an ngFor.
|
|
2776
|
+
*
|
|
2777
|
+
* @param index - The index of the element in the ngFor.
|
|
2778
|
+
* @returns The index.
|
|
2779
|
+
*/
|
|
2780
|
+
trackByFn(index) {
|
|
2781
|
+
return index;
|
|
2782
|
+
}
|
|
2783
|
+
ngOnInit() {
|
|
2784
|
+
if (!this.entity) {
|
|
2785
|
+
throw new Error('Missing required Input data "entity"');
|
|
2786
|
+
}
|
|
2787
|
+
this.internalEntity = this.entity;
|
|
2788
|
+
if (this.propertyKey == null) {
|
|
2789
|
+
throw new Error('Missing required Input data "propertyKey"');
|
|
2790
|
+
}
|
|
2791
|
+
this.internalPropertyKey = this.propertyKey;
|
|
2792
|
+
this.internalGetValidationErrorMessage = this.getValidationErrorMessage ?? getValidationErrorMessage;
|
|
2793
|
+
this.internalIsReadOnly = this.isReadOnly ?? false;
|
|
2794
|
+
this.type = EntityUtilities.getPropertyType(this.internalEntity, this.internalPropertyKey);
|
|
2795
|
+
this.metadata = EntityUtilities.getPropertyMetadata(this.internalEntity, this.internalPropertyKey, this.type);
|
|
2796
|
+
if (this.type === DecoratorTypes.OBJECT) {
|
|
2797
|
+
this.initObjectInput();
|
|
2798
|
+
}
|
|
2799
|
+
if (this.type === DecoratorTypes.ARRAY) {
|
|
2800
|
+
this.initEntityArray();
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2803
|
+
initEntityArray() {
|
|
2804
|
+
this.metadataEntityArray = this.metadata;
|
|
2805
|
+
if (this.internalEntity[this.internalPropertyKey] == null) {
|
|
2806
|
+
this.internalEntity[this.internalPropertyKey] = [];
|
|
2807
|
+
}
|
|
2808
|
+
this.entityArrayValues = this.internalEntity[this.internalPropertyKey];
|
|
2809
|
+
if (!this.metadataEntityArray.createInline && !this.metadataEntityArray.createDialogData) {
|
|
2810
|
+
this.metadataEntityArray.createDialogData = {
|
|
2811
|
+
title: 'Add'
|
|
2812
|
+
};
|
|
2813
|
+
}
|
|
2814
|
+
const givenDisplayColumns = this.metadataEntityArray.displayColumns.map((v) => v.displayName);
|
|
2815
|
+
if (givenDisplayColumns.find(s => s === 'select')) {
|
|
2816
|
+
throw new Error(`The name "select" for a display column is reserved.
|
|
2817
|
+
Please choose a different name.`);
|
|
2818
|
+
}
|
|
2819
|
+
this.displayedColumns = this.internalIsReadOnly ? givenDisplayColumns : ['select'].concat(givenDisplayColumns);
|
|
2820
|
+
this.dataSource = new MatTableDataSource();
|
|
2821
|
+
this.dataSource.data = this.entityArrayValues;
|
|
2822
|
+
this.arrayItem = new this.metadataEntityArray.EntityClass();
|
|
2823
|
+
this.arrayItemInlineRows = EntityUtilities.getEntityRows(this.arrayItem, this.hideOmitForCreate ?? true, this.hideOmitForEdit);
|
|
2824
|
+
this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
|
|
2825
|
+
this.dialogInputData = {
|
|
2826
|
+
entity: this.arrayItem,
|
|
2827
|
+
createDialogData: this.metadataEntityArray.createDialogData,
|
|
2828
|
+
getValidationErrorMessage: this.getValidationErrorMessage
|
|
2829
|
+
};
|
|
2830
|
+
this.dialogData = new AddArrayItemDialogDataBuilder(this.dialogInputData).getResult();
|
|
2831
|
+
this.arrayItemDialogRows = EntityUtilities.getEntityRows(this.dialogData.entity, true);
|
|
2832
|
+
}
|
|
2833
|
+
initObjectInput() {
|
|
2834
|
+
this.metadataDefaultObject = this.metadata;
|
|
2835
|
+
this.objectProperty = this.internalEntity[this.internalPropertyKey];
|
|
2836
|
+
this.objectPropertyRows = EntityUtilities.getEntityRows(this.objectProperty, this.hideOmitForCreate, this.hideOmitForEdit);
|
|
2837
|
+
}
|
|
2838
|
+
/**
|
|
2839
|
+
* Checks if the arrayItem is valid.
|
|
2840
|
+
*/
|
|
2841
|
+
checkIsArrayItemValid() {
|
|
2842
|
+
this.isArrayItemValid = EntityUtilities.isEntityValid(this.arrayItem, 'create');
|
|
2843
|
+
}
|
|
2844
|
+
/**
|
|
2845
|
+
* Checks if the arrayItem inside the dialog is valid.
|
|
2846
|
+
*/
|
|
2847
|
+
checkIsDialogArrayItemValid() {
|
|
2848
|
+
this.isDialogArrayItemValid = EntityUtilities.isEntityValid(this.dialogData.entity, 'create');
|
|
2849
|
+
}
|
|
2850
|
+
/**
|
|
2851
|
+
* Emits that a the value has been changed.
|
|
2852
|
+
*/
|
|
2853
|
+
emitChange() {
|
|
2854
|
+
this.inputChangeEvent.emit();
|
|
2855
|
+
}
|
|
2856
|
+
/**
|
|
2857
|
+
* Tries to add an item to the entity array.
|
|
2858
|
+
* Does this either inline if the "createInline"-metadata is set to true
|
|
2859
|
+
* or in a separate dialog if it is set to false.
|
|
2860
|
+
*/
|
|
2861
|
+
async addEntity() {
|
|
2862
|
+
if (this.metadataEntityArray.createInline) {
|
|
2863
|
+
if (!this.metadataEntityArray.allowDuplicates) {
|
|
2864
|
+
for (const v of this.entityArrayValues) {
|
|
2865
|
+
if ((await EntityUtilities.isEqual(this.arrayItem, v, this.metadata, this.metadataEntityArray.itemType))) {
|
|
2866
|
+
this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
2867
|
+
data: this.metadataEntityArray.duplicatesErrorDialog,
|
|
2868
|
+
autoFocus: false,
|
|
2869
|
+
restoreFocus: false
|
|
2870
|
+
});
|
|
2871
|
+
return;
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
this.entityArrayValues.push(LodashUtilities.cloneDeep(this.arrayItem));
|
|
1356
2876
|
this.dataSource.data = this.entityArrayValues;
|
|
1357
2877
|
EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
|
|
2878
|
+
this.checkIsArrayItemValid();
|
|
2879
|
+
this.emitChange();
|
|
1358
2880
|
}
|
|
1359
2881
|
else {
|
|
1360
2882
|
this.addArrayItemDialogRef = this.dialog.open(this.addArrayItemDialog, {
|
|
@@ -1369,9 +2891,11 @@ class NgxMatEntityInputComponent {
|
|
|
1369
2891
|
*/
|
|
1370
2892
|
addArrayItem() {
|
|
1371
2893
|
this.addArrayItemDialogRef.close();
|
|
1372
|
-
this.entityArrayValues.push(cloneDeep(this.arrayItem));
|
|
2894
|
+
this.entityArrayValues.push(LodashUtilities.cloneDeep(this.arrayItem));
|
|
1373
2895
|
this.dataSource.data = this.entityArrayValues;
|
|
1374
2896
|
EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
|
|
2897
|
+
this.checkIsArrayItemValid();
|
|
2898
|
+
this.emitChange();
|
|
1375
2899
|
}
|
|
1376
2900
|
/**
|
|
1377
2901
|
* Cancels adding the array item defined in the dialog.
|
|
@@ -1379,132 +2903,59 @@ class NgxMatEntityInputComponent {
|
|
|
1379
2903
|
cancelAddArrayItem() {
|
|
1380
2904
|
this.addArrayItemDialogRef.close();
|
|
1381
2905
|
EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
|
|
2906
|
+
this.emitChange();
|
|
1382
2907
|
}
|
|
1383
2908
|
/**
|
|
1384
|
-
* Removes all selected entries from the array.
|
|
2909
|
+
* Removes all selected entries from the entity array.
|
|
2910
|
+
*
|
|
2911
|
+
* @param selection - The selection containing the items to remove.
|
|
2912
|
+
* @param values - The values of the dataSource.
|
|
2913
|
+
* @param dataSource - The dataSource.
|
|
1385
2914
|
*/
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
2915
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2916
|
+
remove(selection, values, dataSource) {
|
|
2917
|
+
selection.selected.forEach(s => {
|
|
2918
|
+
values.splice(values.indexOf(s), 1);
|
|
1389
2919
|
});
|
|
1390
|
-
|
|
1391
|
-
|
|
2920
|
+
dataSource.data = values;
|
|
2921
|
+
selection.clear();
|
|
2922
|
+
this.emitChange();
|
|
1392
2923
|
}
|
|
1393
2924
|
/**
|
|
1394
2925
|
* Toggles all array-items in the table.
|
|
2926
|
+
*
|
|
2927
|
+
* @param selection - The selection to toggle.
|
|
2928
|
+
* @param dataSource - The dataSource of the selection.
|
|
1395
2929
|
*/
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
2930
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2931
|
+
masterToggle(selection, dataSource) {
|
|
2932
|
+
if (this.isAllSelected(selection, dataSource)) {
|
|
2933
|
+
selection.clear();
|
|
1399
2934
|
}
|
|
1400
2935
|
else {
|
|
1401
|
-
|
|
2936
|
+
dataSource.data.forEach(row => selection.select(row));
|
|
1402
2937
|
}
|
|
1403
2938
|
}
|
|
1404
2939
|
/**
|
|
1405
2940
|
* Checks if all array-items in the table have been selected.
|
|
1406
2941
|
* This is needed to display the "masterToggle"-checkbox correctly.
|
|
1407
2942
|
*
|
|
2943
|
+
* @param selection - The selection to check.
|
|
2944
|
+
* @param dataSource - The dataSource of the selection.
|
|
1408
2945
|
* @returns Whether or not all array-items in the table have been selected.
|
|
1409
2946
|
*/
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
const
|
|
2947
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2948
|
+
isAllSelected(selection, dataSource) {
|
|
2949
|
+
const numSelected = selection.selected.length;
|
|
2950
|
+
const numRows = dataSource.data.length;
|
|
1413
2951
|
return numSelected === numRows;
|
|
1414
2952
|
}
|
|
1415
|
-
/**
|
|
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.
|
|
1425
|
-
*/
|
|
1426
|
-
addStringChipArrayValue(event) {
|
|
1427
|
-
const value = (event.value || '').trim();
|
|
1428
|
-
if (value) {
|
|
1429
|
-
if (this.metadataStringChipsArray.minLength && value.length < this.metadataStringChipsArray.minLength) {
|
|
1430
|
-
return;
|
|
1431
|
-
}
|
|
1432
|
-
if (this.metadataStringChipsArray.maxLength && value.length > this.metadataStringChipsArray.maxLength) {
|
|
1433
|
-
return;
|
|
1434
|
-
}
|
|
1435
|
-
if (this.metadataStringChipsArray.regex && !value.match(this.metadataStringChipsArray.regex)) {
|
|
1436
|
-
return;
|
|
1437
|
-
}
|
|
1438
|
-
if (!this.stringChipsArrayValues) {
|
|
1439
|
-
if (!this.entity[this.propertyKey]) {
|
|
1440
|
-
this.entity[this.propertyKey] = [];
|
|
1441
|
-
}
|
|
1442
|
-
this.stringChipsArrayValues = this.entity[this.propertyKey];
|
|
1443
|
-
}
|
|
1444
|
-
this.stringChipsArrayValues.push(value);
|
|
1445
|
-
}
|
|
1446
|
-
event.chipInput.clear();
|
|
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
|
-
*/
|
|
1458
|
-
removeStringChipArrayValue(value) {
|
|
1459
|
-
this.stringChipsArrayValues.splice(this.stringChipsArrayValues.indexOf(value), 1);
|
|
1460
|
-
if (!this.stringChipsArrayValues.length) {
|
|
1461
|
-
this.entity[this.propertyKey] = undefined;
|
|
1462
|
-
this.stringChipsArrayValues = this.entity[this.propertyKey];
|
|
1463
|
-
}
|
|
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
|
-
*/
|
|
1471
|
-
selected(event, chipsInput) {
|
|
1472
|
-
const value = (event.option.viewValue || '').trim();
|
|
1473
|
-
if (this.metadataStringChipsArray.minLength && value.length < this.metadataStringChipsArray.minLength) {
|
|
1474
|
-
return;
|
|
1475
|
-
}
|
|
1476
|
-
if (this.metadataStringChipsArray.maxLength && value.length > this.metadataStringChipsArray.maxLength) {
|
|
1477
|
-
return;
|
|
1478
|
-
}
|
|
1479
|
-
if (this.metadataStringChipsArray.regex && !value.match(this.metadataStringChipsArray.regex)) {
|
|
1480
|
-
return;
|
|
1481
|
-
}
|
|
1482
|
-
if (!this.stringChipsArrayValues) {
|
|
1483
|
-
if (!this.entity[this.propertyKey]) {
|
|
1484
|
-
this.entity[this.propertyKey] = [];
|
|
1485
|
-
}
|
|
1486
|
-
this.stringChipsArrayValues = this.entity[this.propertyKey];
|
|
1487
|
-
}
|
|
1488
|
-
this.stringChipsArrayValues.push(value);
|
|
1489
|
-
chipsInput.value = '';
|
|
1490
|
-
}
|
|
1491
|
-
/**
|
|
1492
|
-
* Dynamically filters the Autocomplete options when the user inputs something.
|
|
1493
|
-
*
|
|
1494
|
-
* @param input - The input of the user.
|
|
1495
|
-
*/
|
|
1496
|
-
filterAutocompleteStrings(input) {
|
|
1497
|
-
if (input) {
|
|
1498
|
-
const filterValue = input.toLowerCase();
|
|
1499
|
-
this.filteredAutocompleteStrings = this.autocompleteStrings.filter(s => s.toLowerCase().includes(filterValue));
|
|
1500
|
-
}
|
|
1501
|
-
}
|
|
1502
2953
|
}
|
|
1503
2954
|
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]" }] });
|
|
2955
|
+
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", isReadOnly: "isReadOnly" }, outputs: { inputChangeEvent: "inputChangeEvent" }, viewQueries: [{ propertyName: "addArrayItemDialog", first: true, predicate: ["addArrayItemDialog"], descendants: true }], ngImport: i0, template: "<div [ngSwitch]=\"type\" *ngIf=\"!(hideOmitForCreate && metadata.omitForCreate) && !(hideOmitForEdit && metadata.omitForUpdate)\">\n <!-------------------------------------------->\n <!-----------------Strings-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.STRING\">\n <string-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_TEXTBOX\">\n <string-textbox-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-textbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_AUTOCOMPLETE\">\n <string-autocomplete-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-autocomplete-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_DROPDOWN\">\n <string-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-dropdown-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_PASSWORD\">\n <string-password-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-password-input>\n </div>\n\n <!-------------------------------------------->\n <!-----------------Booleans------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_CHECKBOX\">\n <boolean-checkbox-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-checkbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <boolean-toggle-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-toggle-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_DROPDOWN\">\n <boolean-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-dropdown-input>\n </div>\n\n <!-------------------------------------------->\n <!------------------Numbers------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER\">\n <number-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_DROPDOWN\">\n <number-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-dropdown-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_SLIDER\">\n <number-slider-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-slider-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Object------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.OBJECT\">\n <b>{{metadataDefaultObject.displayName}}</b>\n <!-- iterates over the object properties -->\n <div class=\"row\" *ngFor=\"let row of objectPropertyRows\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [isReadOnly]=\"internalIsReadOnly\"\n class=\"col-lg-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.getWidth(objectProperty, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div class=\"entityArray\" *ngSwitchCase=\"DecoratorTypes.ARRAY\">\n <div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n <div style=\"padding-bottom: 10px\">\n <b>{{metadataEntityArray.displayName}}</b>\n </div>\n <div *ngIf=\"metadataEntityArray.createInline && !internalIsReadOnly\">\n <div class=\"row\" *ngFor=\"let row of arrayItemInlineRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n\n <div class=\"buttons\" *ngIf=\"!internalIsReadOnly\">\n <button mat-raised-button\n [disabled]=\"metadataEntityArray.createInline && !isArrayItemValid\"\n (click)=\"addEntity()\">\n {{metadataEntityArray.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove(selection, entityArrayValues, dataSource)\">\n {{metadataEntityArray.removeButtonLabel}}\n </button>\n </div>\n \n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\" *ngIf=\"!internalIsReadOnly\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox\n [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle(selection, dataSource) : null\"\n [checked]=\"selection.hasValue() && isAllSelected(selection, dataSource)\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected(selection, dataSource)\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadataEntityArray.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n \n <div class=\"array-error\" *ngIf=\"metadataEntityArray.required && !dataSource.data.length\">\n {{metadataEntityArray.missingErrorMessage}}\n </div>\n </div>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE\">\n <array-date-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_TIME\">\n <array-date-time-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-time-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_RANGE\">\n <array-date-range-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_CHIPS\">\n <array-string-chips-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-string-chips-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS\">\n <array-string-autocomplete-chips\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-string-autocomplete-chips>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Dates-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.DATE\">\n <date-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_RANGE\">\n <date-range-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_TIME\">\n <date-time-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-time-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Files-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.FILE_DEFAULT\">\n <file-default-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </file-default-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.FILE_IMAGE\">\n <file-image-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </file-image-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Custom------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.CUSTOM\">\n <custom-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </custom-input>\n </div>\n\n <div *ngSwitchDefault>ERROR: The type {{type}} is not known.</div>\n</div>\n\n<!--------------------------------------------------------->\n<!--------------------Add Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #addArrayItemDialog>\n <h2 mat-dialog-title>{{dialogData.createDialogData.title}}</h2>\n\n <mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"dialogData.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"dialogData.getValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(dialogData.entity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(dialogData.entity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(dialogData.entity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsDialogArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n </mat-dialog-content>\n\n <mat-dialog-actions>\n <button mat-raised-button (click)=\"addArrayItem()\" [disabled]=\"!isDialogArrayItemValid\">\n {{dialogData.createDialogData.createButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancelAddArrayItem()\" class=\"cancel-button\">\n {{dialogData.createDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n\n</ng-template>", styles: ["mat-form-field{width:100%}::ng-deep .mat-form-field.mat-form-field-disabled .mat-form-field-wrapper .mat-form-field-underline{background-image:none;height:1px;background-color:#0000006b}::ng-deep .mat-form-field.mat-form-field-disabled .mat-chip.mat-standard-chip.mat-chip-disabled{opacity:1}::ng-deep .mat-form-field.mat-form-field-disabled .mat-chip.mat-standard-chip.mat-chip-disabled button{opacity:.2}::ng-deep .mat-form-field.mat-form-field-disabled .mat-select-disabled .mat-select-value{color:#000}::ng-deep .mat-form-field.mat-form-field-disabled .mat-date-range-input-inner:disabled{color:#000}::ng-deep .mat-form-field .mat-slide-toggle.mat-disabled{opacity:1}::ng-deep .mat-input-element:disabled{color:#000}.entityArray .buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}.entityArray mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.entityArray .mat-column-select{flex:0 0 75px}.entityArray .array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"], components: [{ type: StringInputComponent, selector: "string-input" }, { type: StringTextboxInputComponent, selector: "string-textbox-input" }, { type: StringAutocompleteInputComponent, selector: "string-autocomplete-input" }, { type: StringDropdownInputComponent, selector: "string-dropdown-input" }, { type: StringPasswordInputComponent, selector: "string-password-input" }, { type: BooleanCheckboxInputComponent, selector: "boolean-checkbox-input" }, { type: BooleanToggleInputComponent, selector: "boolean-toggle-input" }, { type: BooleanDropdownInputComponent, selector: "boolean-dropdown-input" }, { type: NumberInputComponent, selector: "number-input" }, { type: NumberDropdownInputComponent, selector: "number-dropdown-input" }, { type: NumberSliderInputComponent, selector: "number-slider-input" }, { type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: ["entity", "propertyKey", "getValidationErrorMessage", "hideOmitForCreate", "hideOmitForEdit", "isReadOnly"], outputs: ["inputChangeEvent"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i4$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i4$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { type: ArrayDateInputComponent, selector: "array-date-input" }, { type: ArrayDateTimeInputComponent, selector: "array-date-time-input" }, { type: ArrayDateRangeInputComponent, selector: "array-date-range-input" }, { type: ArrayStringChipsInputComponent, selector: "array-string-chips-input" }, { type: ArrayStringAutocompleteChipsComponent, selector: "array-string-autocomplete-chips" }, { type: DateInputComponent, selector: "date-input" }, { type: DateRangeInputComponent, selector: "date-range-input" }, { type: DateTimeInputComponent, selector: "date-time-input" }, { type: FileDefaultInputComponent, selector: "file-default-input" }, { type: FileImageInputComponent, selector: "file-image-input" }, { type: CustomInputComponent, selector: "custom-input" }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i6.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i4$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i4$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i4$2.MatCellDef, selector: "[matCellDef]" }, { type: i4$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i4$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i4$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { type: i6.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: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4.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]" }] });
|
|
1505
2956
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputComponent, decorators: [{
|
|
1506
2957
|
type: Component,
|
|
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"] }]
|
|
2958
|
+
args: [{ selector: 'ngx-mat-entity-input', template: "<div [ngSwitch]=\"type\" *ngIf=\"!(hideOmitForCreate && metadata.omitForCreate) && !(hideOmitForEdit && metadata.omitForUpdate)\">\n <!-------------------------------------------->\n <!-----------------Strings-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.STRING\">\n <string-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_TEXTBOX\">\n <string-textbox-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-textbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_AUTOCOMPLETE\">\n <string-autocomplete-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-autocomplete-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_DROPDOWN\">\n <string-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-dropdown-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_PASSWORD\">\n <string-password-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-password-input>\n </div>\n\n <!-------------------------------------------->\n <!-----------------Booleans------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_CHECKBOX\">\n <boolean-checkbox-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-checkbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <boolean-toggle-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-toggle-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_DROPDOWN\">\n <boolean-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-dropdown-input>\n </div>\n\n <!-------------------------------------------->\n <!------------------Numbers------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER\">\n <number-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_DROPDOWN\">\n <number-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-dropdown-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_SLIDER\">\n <number-slider-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-slider-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Object------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.OBJECT\">\n <b>{{metadataDefaultObject.displayName}}</b>\n <!-- iterates over the object properties -->\n <div class=\"row\" *ngFor=\"let row of objectPropertyRows\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [isReadOnly]=\"internalIsReadOnly\"\n class=\"col-lg-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.getWidth(objectProperty, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div class=\"entityArray\" *ngSwitchCase=\"DecoratorTypes.ARRAY\">\n <div class=\"mat-elevation-z8\" style=\"border-radius: 5px;padding: 15px;margin-bottom: 15px;margin-top: 15px;\">\n <div style=\"padding-bottom: 10px\">\n <b>{{metadataEntityArray.displayName}}</b>\n </div>\n <div *ngIf=\"metadataEntityArray.createInline && !internalIsReadOnly\">\n <div class=\"row\" *ngFor=\"let row of arrayItemInlineRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n\n <div class=\"buttons\" *ngIf=\"!internalIsReadOnly\">\n <button mat-raised-button\n [disabled]=\"metadataEntityArray.createInline && !isArrayItemValid\"\n (click)=\"addEntity()\">\n {{metadataEntityArray.addButtonLabel}}\n </button>\n <button mat-raised-button\n [disabled]=\"!selection.selected.length\"\n (click)=\"remove(selection, entityArrayValues, dataSource)\">\n {{metadataEntityArray.removeButtonLabel}}\n </button>\n </div>\n \n <mat-table [dataSource]=\"dataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\" *ngIf=\"!internalIsReadOnly\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox\n [disabled]=\"!dataSource.data.length\" (change)=\"$event ? masterToggle(selection, dataSource) : null\"\n [checked]=\"selection.hasValue() && isAllSelected(selection, dataSource)\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected(selection, dataSource)\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let module\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(module) : null\" [checked]=\"selection.isSelected(module)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadataEntityArray.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n \n <div class=\"array-error\" *ngIf=\"metadataEntityArray.required && !dataSource.data.length\">\n {{metadataEntityArray.missingErrorMessage}}\n </div>\n </div>\n </div>\n\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE\">\n <array-date-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_TIME\">\n <array-date-time-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-time-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_RANGE\">\n <array-date-range-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_CHIPS\">\n <array-string-chips-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-string-chips-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS\">\n <array-string-autocomplete-chips\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-string-autocomplete-chips>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Dates-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.DATE\">\n <date-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_RANGE\">\n <date-range-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_TIME\">\n <date-time-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-time-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Files-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.FILE_DEFAULT\">\n <file-default-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </file-default-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.FILE_IMAGE\">\n <file-image-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </file-image-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Custom------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.CUSTOM\">\n <custom-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </custom-input>\n </div>\n\n <div *ngSwitchDefault>ERROR: The type {{type}} is not known.</div>\n</div>\n\n<!--------------------------------------------------------->\n<!--------------------Add Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #addArrayItemDialog>\n <h2 mat-dialog-title>{{dialogData.createDialogData.title}}</h2>\n\n <mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"dialogData.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"dialogData.getValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(dialogData.entity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(dialogData.entity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(dialogData.entity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsDialogArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n </mat-dialog-content>\n\n <mat-dialog-actions>\n <button mat-raised-button (click)=\"addArrayItem()\" [disabled]=\"!isDialogArrayItemValid\">\n {{dialogData.createDialogData.createButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancelAddArrayItem()\" class=\"cancel-button\">\n {{dialogData.createDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n\n</ng-template>", styles: ["mat-form-field{width:100%}::ng-deep .mat-form-field.mat-form-field-disabled .mat-form-field-wrapper .mat-form-field-underline{background-image:none;height:1px;background-color:#0000006b}::ng-deep .mat-form-field.mat-form-field-disabled .mat-chip.mat-standard-chip.mat-chip-disabled{opacity:1}::ng-deep .mat-form-field.mat-form-field-disabled .mat-chip.mat-standard-chip.mat-chip-disabled button{opacity:.2}::ng-deep .mat-form-field.mat-form-field-disabled .mat-select-disabled .mat-select-value{color:#000}::ng-deep .mat-form-field.mat-form-field-disabled .mat-date-range-input-inner:disabled{color:#000}::ng-deep .mat-form-field .mat-slide-toggle.mat-disabled{opacity:1}::ng-deep .mat-input-element:disabled{color:#000}.entityArray .buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}.entityArray mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.entityArray .mat-column-select{flex:0 0 75px}.entityArray .array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}\n"] }]
|
|
1508
2959
|
}], ctorParameters: function () { return [{ type: i1.MatDialog }]; }, propDecorators: { entity: [{
|
|
1509
2960
|
type: Input
|
|
1510
2961
|
}], propertyKey: [{
|
|
@@ -1515,6 +2966,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
|
|
|
1515
2966
|
type: Input
|
|
1516
2967
|
}], hideOmitForEdit: [{
|
|
1517
2968
|
type: Input
|
|
2969
|
+
}], isReadOnly: [{
|
|
2970
|
+
type: Input
|
|
2971
|
+
}], inputChangeEvent: [{
|
|
2972
|
+
type: Output
|
|
1518
2973
|
}], addArrayItemDialog: [{
|
|
1519
2974
|
type: ViewChild,
|
|
1520
2975
|
args: ['addArrayItemDialog']
|
|
@@ -1523,7 +2978,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
|
|
|
1523
2978
|
class NgxMatEntityInputModule {
|
|
1524
2979
|
}
|
|
1525
2980
|
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: [
|
|
2981
|
+
NgxMatEntityInputModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, declarations: [StringInputComponent,
|
|
2982
|
+
StringTextboxInputComponent,
|
|
2983
|
+
StringAutocompleteInputComponent,
|
|
2984
|
+
StringDropdownInputComponent,
|
|
2985
|
+
StringPasswordInputComponent,
|
|
2986
|
+
BooleanCheckboxInputComponent,
|
|
2987
|
+
BooleanToggleInputComponent,
|
|
2988
|
+
BooleanDropdownInputComponent,
|
|
2989
|
+
NumberInputComponent,
|
|
2990
|
+
NumberDropdownInputComponent,
|
|
2991
|
+
NumberSliderInputComponent,
|
|
2992
|
+
ArrayStringChipsInputComponent,
|
|
2993
|
+
ArrayStringAutocompleteChipsComponent,
|
|
2994
|
+
DateInputComponent,
|
|
2995
|
+
DateRangeInputComponent,
|
|
2996
|
+
DateTimeInputComponent,
|
|
2997
|
+
ArrayDateInputComponent,
|
|
2998
|
+
ArrayDateTimeInputComponent,
|
|
2999
|
+
ArrayDateRangeInputComponent,
|
|
3000
|
+
FileInputComponent,
|
|
3001
|
+
FileImageInputComponent,
|
|
3002
|
+
FileDefaultInputComponent,
|
|
3003
|
+
DragDropDirective,
|
|
3004
|
+
CustomInputComponent,
|
|
3005
|
+
NgxMatEntityInputComponent], imports: [CommonModule,
|
|
1527
3006
|
MatInputModule,
|
|
1528
3007
|
FormsModule,
|
|
1529
3008
|
MatFormFieldModule,
|
|
@@ -1536,7 +3015,8 @@ NgxMatEntityInputModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0",
|
|
|
1536
3015
|
MatTableModule,
|
|
1537
3016
|
MatDialogModule,
|
|
1538
3017
|
MatButtonModule,
|
|
1539
|
-
MatDatepickerModule
|
|
3018
|
+
MatDatepickerModule,
|
|
3019
|
+
MatSliderModule], exports: [NgxMatEntityInputComponent] });
|
|
1540
3020
|
NgxMatEntityInputModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, imports: [[
|
|
1541
3021
|
CommonModule,
|
|
1542
3022
|
MatInputModule,
|
|
@@ -1551,13 +3031,38 @@ NgxMatEntityInputModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0",
|
|
|
1551
3031
|
MatTableModule,
|
|
1552
3032
|
MatDialogModule,
|
|
1553
3033
|
MatButtonModule,
|
|
1554
|
-
MatDatepickerModule
|
|
3034
|
+
MatDatepickerModule,
|
|
3035
|
+
MatSliderModule
|
|
1555
3036
|
]] });
|
|
1556
3037
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityInputModule, decorators: [{
|
|
1557
3038
|
type: NgModule,
|
|
1558
3039
|
args: [{
|
|
1559
3040
|
declarations: [
|
|
1560
|
-
|
|
3041
|
+
StringInputComponent,
|
|
3042
|
+
StringTextboxInputComponent,
|
|
3043
|
+
StringAutocompleteInputComponent,
|
|
3044
|
+
StringDropdownInputComponent,
|
|
3045
|
+
StringPasswordInputComponent,
|
|
3046
|
+
BooleanCheckboxInputComponent,
|
|
3047
|
+
BooleanToggleInputComponent,
|
|
3048
|
+
BooleanDropdownInputComponent,
|
|
3049
|
+
NumberInputComponent,
|
|
3050
|
+
NumberDropdownInputComponent,
|
|
3051
|
+
NumberSliderInputComponent,
|
|
3052
|
+
ArrayStringChipsInputComponent,
|
|
3053
|
+
ArrayStringAutocompleteChipsComponent,
|
|
3054
|
+
DateInputComponent,
|
|
3055
|
+
DateRangeInputComponent,
|
|
3056
|
+
DateTimeInputComponent,
|
|
3057
|
+
ArrayDateInputComponent,
|
|
3058
|
+
ArrayDateTimeInputComponent,
|
|
3059
|
+
ArrayDateRangeInputComponent,
|
|
3060
|
+
FileInputComponent,
|
|
3061
|
+
FileImageInputComponent,
|
|
3062
|
+
FileDefaultInputComponent,
|
|
3063
|
+
DragDropDirective,
|
|
3064
|
+
CustomInputComponent,
|
|
3065
|
+
NgxMatEntityInputComponent
|
|
1561
3066
|
],
|
|
1562
3067
|
imports: [
|
|
1563
3068
|
CommonModule,
|
|
@@ -1573,7 +3078,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
|
|
|
1573
3078
|
MatTableModule,
|
|
1574
3079
|
MatDialogModule,
|
|
1575
3080
|
MatButtonModule,
|
|
1576
|
-
MatDatepickerModule
|
|
3081
|
+
MatDatepickerModule,
|
|
3082
|
+
MatSliderModule
|
|
1577
3083
|
],
|
|
1578
3084
|
exports: [NgxMatEntityInputComponent]
|
|
1579
3085
|
}]
|
|
@@ -1616,7 +3122,7 @@ class NgxMatEntityCreateDialogComponent {
|
|
|
1616
3122
|
this.injector = injector;
|
|
1617
3123
|
this.dialog = dialog;
|
|
1618
3124
|
this.EntityUtilities = EntityUtilities;
|
|
1619
|
-
this.
|
|
3125
|
+
this.isEntityValid = false;
|
|
1620
3126
|
}
|
|
1621
3127
|
ngOnInit() {
|
|
1622
3128
|
this.data = new CreateEntityDialogDataBuilder(this.inputData).getResult();
|
|
@@ -1624,15 +3130,22 @@ class NgxMatEntityCreateDialogComponent {
|
|
|
1624
3130
|
this.entityRows = EntityUtilities.getEntityRows(this.data.entity, true);
|
|
1625
3131
|
this.entityService = this.injector.get(this.data.EntityServiceClass);
|
|
1626
3132
|
}
|
|
3133
|
+
/**
|
|
3134
|
+
* Checks if the entity is valid.
|
|
3135
|
+
*/
|
|
3136
|
+
checkIsEntityValid() {
|
|
3137
|
+
this.isEntityValid = EntityUtilities.isEntityValid(this.data.entity, 'create');
|
|
3138
|
+
}
|
|
1627
3139
|
/**
|
|
1628
3140
|
* Tries add the new entity and close the dialog afterwards.
|
|
1629
3141
|
* Also handles the confirmation if required.
|
|
1630
3142
|
*/
|
|
1631
3143
|
create() {
|
|
1632
|
-
if (!this.data.createDialogData
|
|
1633
|
-
|
|
3144
|
+
if (!this.data.createDialogData.createRequiresConfirmDialog) {
|
|
3145
|
+
this.confirmCreate();
|
|
3146
|
+
return;
|
|
1634
3147
|
}
|
|
1635
|
-
const dialogData = new ConfirmDialogDataBuilder(this.data.createDialogData
|
|
3148
|
+
const dialogData = new ConfirmDialogDataBuilder(this.data.createDialogData.confirmCreateDialogData)
|
|
1636
3149
|
.withDefault('text', ['Do you really want to create this entity?'])
|
|
1637
3150
|
.withDefault('confirmButtonLabel', 'Create')
|
|
1638
3151
|
.withDefault('title', 'Create')
|
|
@@ -1649,7 +3162,7 @@ class NgxMatEntityCreateDialogComponent {
|
|
|
1649
3162
|
});
|
|
1650
3163
|
}
|
|
1651
3164
|
confirmCreate() {
|
|
1652
|
-
this.entityService.create(this.data.entity).then(() => this.dialogRef.close());
|
|
3165
|
+
void this.entityService.create(this.data.entity).then(() => this.dialogRef.close());
|
|
1653
3166
|
}
|
|
1654
3167
|
/**
|
|
1655
3168
|
* Closes the dialog.
|
|
@@ -1659,10 +3172,10 @@ class NgxMatEntityCreateDialogComponent {
|
|
|
1659
3172
|
}
|
|
1660
3173
|
}
|
|
1661
3174
|
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 });
|
|
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]=\"!
|
|
3175
|
+
NgxMatEntityCreateDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityCreateDialogComponent, selector: "ngx-mat-entity-create-dialog", ngImport: i0, template: "<h2 mat-dialog-title>{{data.createDialogData.title}}</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\">\n <div class=\"row\" *ngFor=\"let row of entityRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(data.entity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(data.entity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(data.entity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsEntityValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"create()\" [disabled]=\"!isEntityValid\">\n {{data.createDialogData.createButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.createDialogData.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}\n"], components: [{ type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: ["entity", "propertyKey", "getValidationErrorMessage", "hideOmitForCreate", "hideOmitForEdit", "isReadOnly"], outputs: ["inputChangeEvent"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
|
|
1663
3176
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityCreateDialogComponent, decorators: [{
|
|
1664
3177
|
type: Component,
|
|
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]=\"!
|
|
3178
|
+
args: [{ selector: 'ngx-mat-entity-create-dialog', template: "<h2 mat-dialog-title>{{data.createDialogData.title}}</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\">\n <div class=\"row\" *ngFor=\"let row of entityRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(data.entity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(data.entity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(data.entity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsEntityValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </form>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"create()\" [disabled]=\"!isEntityValid\">\n {{data.createDialogData.createButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.createDialogData.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}\n"] }]
|
|
1666
3179
|
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
1667
3180
|
type: Inject,
|
|
1668
3181
|
args: [MAT_DIALOG_DATA]
|
|
@@ -1703,7 +3216,7 @@ class EditDialogDataBuilder extends BaseBuilder {
|
|
|
1703
3216
|
.withDefault('text', ['Do you really want to delete this entity?'])
|
|
1704
3217
|
.withDefault('title', 'Delete')
|
|
1705
3218
|
.getResult();
|
|
1706
|
-
return new EditDialogDataInternal(data?.title
|
|
3219
|
+
return new EditDialogDataInternal(data?.title ?? (() => 'Edit'), data?.confirmButtonLabel ?? 'Save', data?.deleteButtonLabel ?? 'Delete', data?.cancelButtonLabel ?? 'Cancel', data?.deleteRequiresConfirmDialog ?? true, data?.editRequiresConfirmDialog ?? false, confirmDeleteDialogData, confirmEditDialogData);
|
|
1707
3220
|
}
|
|
1708
3221
|
}
|
|
1709
3222
|
|
|
@@ -1711,11 +3224,12 @@ class EditDialogDataBuilder extends BaseBuilder {
|
|
|
1711
3224
|
* The internal EditEntityDialogData. Requires all default values the user can leave out.
|
|
1712
3225
|
*/
|
|
1713
3226
|
class EditEntityDialogDataInternal {
|
|
1714
|
-
constructor(entity, EntityServiceClass, editDialogData, allowDelete) {
|
|
3227
|
+
constructor(entity, EntityServiceClass, editDialogData, allowUpdate, allowDelete) {
|
|
1715
3228
|
this.entity = entity;
|
|
1716
3229
|
this.EntityServiceClass = EntityServiceClass;
|
|
1717
3230
|
this.editDialogData = editDialogData;
|
|
1718
3231
|
this.allowDelete = allowDelete;
|
|
3232
|
+
this.allowUpdate = allowUpdate;
|
|
1719
3233
|
}
|
|
1720
3234
|
}
|
|
1721
3235
|
/**
|
|
@@ -1728,7 +3242,7 @@ class EditEntityDialogDataBuilder extends BaseBuilder {
|
|
|
1728
3242
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
1729
3243
|
generateBaseData(data) {
|
|
1730
3244
|
const editDialogData = new EditDialogDataBuilder(data.editDialogData).getResult();
|
|
1731
|
-
return new EditEntityDialogDataInternal(data.entity, data.EntityServiceClass, editDialogData, data.
|
|
3245
|
+
return new EditEntityDialogDataInternal(data.entity, data.EntityServiceClass, editDialogData, data.allowUpdate ?? (() => true), data.allowDelete ?? (() => true));
|
|
1732
3246
|
}
|
|
1733
3247
|
}
|
|
1734
3248
|
|
|
@@ -1745,14 +3259,21 @@ class NgxMatEntityEditDialogComponent {
|
|
|
1745
3259
|
this.injector = injector;
|
|
1746
3260
|
this.dialog = dialog;
|
|
1747
3261
|
this.EntityUtilities = EntityUtilities;
|
|
1748
|
-
this.
|
|
3262
|
+
this.isEntityValid = true;
|
|
3263
|
+
this.isEntityDirty = (async () => false).call(this);
|
|
1749
3264
|
}
|
|
1750
3265
|
ngOnInit() {
|
|
1751
3266
|
this.data = new EditEntityDialogDataBuilder(this.inputData).getResult();
|
|
3267
|
+
this.isReadOnly = !this.data.allowUpdate(this.entityPriorChanges);
|
|
1752
3268
|
this.dialogRef.disableClose = true;
|
|
1753
3269
|
this.entityRows = EntityUtilities.getEntityRows(this.data.entity, false, true);
|
|
1754
3270
|
this.entityService = this.injector.get(this.data.EntityServiceClass);
|
|
1755
|
-
this.entityPriorChanges = cloneDeep(this.data.entity);
|
|
3271
|
+
this.entityPriorChanges = LodashUtilities.cloneDeep(this.data.entity);
|
|
3272
|
+
}
|
|
3273
|
+
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
3274
|
+
checkEntity() {
|
|
3275
|
+
this.isEntityValid = EntityUtilities.isEntityValid(this.data.entity, 'update');
|
|
3276
|
+
this.isEntityDirty = EntityUtilities.isDirty(this.data.entity, this.entityPriorChanges);
|
|
1756
3277
|
}
|
|
1757
3278
|
/**
|
|
1758
3279
|
* Tries to save the changes and close the dialog afterwards.
|
|
@@ -1760,7 +3281,8 @@ class NgxMatEntityEditDialogComponent {
|
|
|
1760
3281
|
*/
|
|
1761
3282
|
edit() {
|
|
1762
3283
|
if (!this.data.editDialogData.editRequiresConfirmDialog) {
|
|
1763
|
-
|
|
3284
|
+
this.confirmEdit();
|
|
3285
|
+
return;
|
|
1764
3286
|
}
|
|
1765
3287
|
const dialogData = new ConfirmDialogDataBuilder(this.data.editDialogData.confirmEditDialogData)
|
|
1766
3288
|
.withDefault('text', ['Do you really want to save all changes?'])
|
|
@@ -1779,7 +3301,7 @@ class NgxMatEntityEditDialogComponent {
|
|
|
1779
3301
|
});
|
|
1780
3302
|
}
|
|
1781
3303
|
confirmEdit() {
|
|
1782
|
-
this.entityService.update(this.data.entity, this.entityPriorChanges).then(() => this.dialogRef.close(1));
|
|
3304
|
+
void this.entityService.update(this.data.entity, this.entityPriorChanges).then(() => this.dialogRef.close(1));
|
|
1783
3305
|
}
|
|
1784
3306
|
/**
|
|
1785
3307
|
* Tries to delete the entity and close the dialog afterwards.
|
|
@@ -1787,7 +3309,8 @@ class NgxMatEntityEditDialogComponent {
|
|
|
1787
3309
|
*/
|
|
1788
3310
|
delete() {
|
|
1789
3311
|
if (!this.data.editDialogData.deleteRequiresConfirmDialog) {
|
|
1790
|
-
|
|
3312
|
+
this.confirmDelete();
|
|
3313
|
+
return;
|
|
1791
3314
|
}
|
|
1792
3315
|
const dialogData = new ConfirmDialogDataBuilder(this.data.editDialogData.confirmDeleteDialogData)
|
|
1793
3316
|
.withDefault('text', ['Do you really want to delete this entity?'])
|
|
@@ -1807,7 +3330,7 @@ class NgxMatEntityEditDialogComponent {
|
|
|
1807
3330
|
});
|
|
1808
3331
|
}
|
|
1809
3332
|
confirmDelete() {
|
|
1810
|
-
this.entityService.delete(this.entityPriorChanges).then(() => this.dialogRef.close(2));
|
|
3333
|
+
void this.entityService.delete(this.entityPriorChanges).then(() => this.dialogRef.close(2));
|
|
1811
3334
|
}
|
|
1812
3335
|
/**
|
|
1813
3336
|
* Reverts all changes made and closes the dialog.
|
|
@@ -1818,10 +3341,10 @@ class NgxMatEntityEditDialogComponent {
|
|
|
1818
3341
|
}
|
|
1819
3342
|
}
|
|
1820
3343
|
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 });
|
|
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]=\"!
|
|
3344
|
+
NgxMatEntityEditDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NgxMatEntityEditDialogComponent, selector: "ngx-mat-entity-edit-dialog", ngImport: i0, template: "<h2 mat-dialog-title>\n {{data.editDialogData.title(data.entity)}}\n <button *ngIf=\"data.allowDelete(data.entity)\" mat-raised-button (click)=\"delete()\" color=\"warn\" class=\"delete-button\" tabindex=\"-1\">\n {{data.editDialogData.deleteButtonLabel}}\n </button>\n</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <div class=\"row\" *ngFor=\"let row of entityRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(data.entity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(data.entity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(data.entity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkEntity()\"\n [isReadOnly]=\"isReadOnly\"\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]=\"isReadOnly || !isEntityValid || (isEntityDirty | async) === false\">\n {{data.editDialogData.confirmButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.editDialogData.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}.delete-button{float:right}\n"], components: [{ type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: ["entity", "propertyKey", "getValidationErrorMessage", "hideOmitForCreate", "hideOmitForEdit", "isReadOnly"], outputs: ["inputChangeEvent"] }], directives: [{ type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }], pipes: { "async": i6.AsyncPipe } });
|
|
1822
3345
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityEditDialogComponent, decorators: [{
|
|
1823
3346
|
type: Component,
|
|
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]=\"!
|
|
3347
|
+
args: [{ selector: 'ngx-mat-entity-edit-dialog', template: "<h2 mat-dialog-title>\n {{data.editDialogData.title(data.entity)}}\n <button *ngIf=\"data.allowDelete(data.entity)\" mat-raised-button (click)=\"delete()\" color=\"warn\" class=\"delete-button\" tabindex=\"-1\">\n {{data.editDialogData.deleteButtonLabel}}\n </button>\n</h2>\n\n<mat-dialog-content>\n <form #form=\"ngForm\" class=\"row\">\n <div class=\"row\" *ngFor=\"let row of entityRows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"data.entity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(data.entity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(data.entity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(data.entity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkEntity()\"\n [isReadOnly]=\"isReadOnly\"\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]=\"isReadOnly || !isEntityValid || (isEntityDirty | async) === false\">\n {{data.editDialogData.confirmButtonLabel}}\n </button>\n <button mat-raised-button (click)=\"cancel()\" class=\"cancel-button\">\n {{data.editDialogData.cancelButtonLabel}}\n </button>\n</mat-dialog-actions>\n", styles: ["mat-dialog-actions{display:flex;justify-content:space-between}.delete-button{float:right}\n"] }]
|
|
1825
3348
|
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
1826
3349
|
type: Inject,
|
|
1827
3350
|
args: [MAT_DIALOG_DATA]
|
|
@@ -1846,14 +3369,14 @@ class BaseDataBuilder extends BaseBuilder {
|
|
|
1846
3369
|
}
|
|
1847
3370
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
1848
3371
|
generateBaseData(data) {
|
|
1849
|
-
return new BaseDataInternal(data.title, data.displayColumns, data.EntityServiceClass, data.searchLabel
|
|
3372
|
+
return new BaseDataInternal(data.title, data.displayColumns, data.EntityServiceClass, data.searchLabel ?? 'Search', data.createButtonLabel ?? 'Create', data.searchString ?? defaultSearchFunction, data.allowCreate ?? (() => true), data.allowRead ?? (() => true), data.allowUpdate ?? (() => true), data.allowDelete ?? (() => true), data.multiSelectActions ?? [], data.multiSelectLabel ?? 'Actions', data.EntityClass, data.edit, data.create);
|
|
1850
3373
|
}
|
|
1851
3374
|
}
|
|
1852
3375
|
/**
|
|
1853
3376
|
* The internal TableData. Requires all default values the user can leave out.
|
|
1854
3377
|
*/
|
|
1855
3378
|
class BaseDataInternal {
|
|
1856
|
-
constructor(title, displayColumns, EntityServiceClass, searchLabel, createButtonLabel, searchString, allowCreate,
|
|
3379
|
+
constructor(title, displayColumns, EntityServiceClass, searchLabel, createButtonLabel, searchString, allowCreate, allowRead, allowUpdate, allowDelete, multiSelectActions, multiSelectLabel, EntityClass, edit, create) {
|
|
1857
3380
|
this.title = title;
|
|
1858
3381
|
this.displayColumns = displayColumns;
|
|
1859
3382
|
this.EntityServiceClass = EntityServiceClass;
|
|
@@ -1862,7 +3385,8 @@ class BaseDataInternal {
|
|
|
1862
3385
|
this.createButtonLabel = createButtonLabel;
|
|
1863
3386
|
this.searchString = searchString;
|
|
1864
3387
|
this.allowCreate = allowCreate;
|
|
1865
|
-
this.
|
|
3388
|
+
this.allowRead = allowRead;
|
|
3389
|
+
this.allowUpdate = allowUpdate;
|
|
1866
3390
|
this.allowDelete = allowDelete;
|
|
1867
3391
|
this.multiSelectActions = multiSelectActions;
|
|
1868
3392
|
this.multiSelectLabel = multiSelectLabel;
|
|
@@ -1890,24 +3414,26 @@ class TableDataBuilder extends BaseBuilder {
|
|
|
1890
3414
|
throw new Error(`The name "select" for a display column is reserved for the multi-select action functionality.
|
|
1891
3415
|
Please choose a different name.`);
|
|
1892
3416
|
}
|
|
1893
|
-
if ((data.baseData.
|
|
1894
|
-
|| data.baseData.
|
|
1895
|
-
|| data.baseData.
|
|
3417
|
+
if ((data.baseData.allowCreate !== (() => false)
|
|
3418
|
+
|| data.baseData.allowRead !== (() => false)
|
|
3419
|
+
|| data.baseData.allowUpdate !== (() => false)
|
|
3420
|
+
|| data.baseData.allowDelete !== (() => false))
|
|
1896
3421
|
&& !data.baseData.EntityClass) {
|
|
1897
3422
|
throw new Error(`
|
|
1898
3423
|
Missing required Input data "EntityClass".
|
|
1899
3424
|
You can only omit this value if you can neither create or update entities.`);
|
|
1900
3425
|
}
|
|
1901
|
-
if (data.baseData.allowCreate !== false && !data.baseData.create && !data.createDialogData) {
|
|
3426
|
+
if (data.baseData.allowCreate !== (() => false) && !data.baseData.create && !data.createDialogData) {
|
|
1902
3427
|
throw new Error(`Missing required Input data "createDialogData".
|
|
1903
3428
|
You can only omit this value when creation is disallowed or done with a custom create method.`);
|
|
1904
3429
|
}
|
|
1905
|
-
if ((data.baseData.
|
|
3430
|
+
if ((data.baseData.allowRead !== (() => false)
|
|
3431
|
+
|| data.baseData.allowUpdate !== (() => false)
|
|
1906
3432
|
|| data.baseData.allowDelete !== (() => false))
|
|
1907
3433
|
&& !data.baseData.edit
|
|
1908
3434
|
&& !data.editDialogData) {
|
|
1909
3435
|
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.`);
|
|
3436
|
+
You can only omit this value when viewing, editing and deleting is disallowed or done with a custom edit method.`);
|
|
1911
3437
|
}
|
|
1912
3438
|
}
|
|
1913
3439
|
}
|
|
@@ -1960,21 +3486,19 @@ class NgxMatEntityTableComponent {
|
|
|
1960
3486
|
return this.data.baseData.displayColumns.find((dp) => dp.displayName === header)?.value(entity);
|
|
1961
3487
|
};
|
|
1962
3488
|
this.dataSource.sort = this.sort;
|
|
1963
|
-
|
|
1964
|
-
this.
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
};
|
|
1970
|
-
}
|
|
3489
|
+
this.dataSource.filterPredicate = (entity, filter) => {
|
|
3490
|
+
const searchStr = this.data.baseData.searchString(entity);
|
|
3491
|
+
const formattedSearchString = searchStr.toLowerCase();
|
|
3492
|
+
const formattedFilterString = filter.toLowerCase();
|
|
3493
|
+
return formattedSearchString.includes(formattedFilterString);
|
|
3494
|
+
};
|
|
1971
3495
|
this.dataSource.filter = this.filter;
|
|
1972
3496
|
this.dataSource.paginator = this.paginator;
|
|
1973
3497
|
this.entityService.entitiesSubject.pipe(takeUntil(this.onDestroy)).subscribe((entities) => {
|
|
1974
3498
|
this.dataSource.data = entities;
|
|
1975
3499
|
this.selection.clear();
|
|
1976
3500
|
});
|
|
1977
|
-
this.entityService.read();
|
|
3501
|
+
void this.entityService.read();
|
|
1978
3502
|
}
|
|
1979
3503
|
/**
|
|
1980
3504
|
* Edits an entity. This either calls the edit-Method provided by the user or uses a default edit-dialog.
|
|
@@ -1983,39 +3507,40 @@ class NgxMatEntityTableComponent {
|
|
|
1983
3507
|
* @throws When no EntityClass was provided, as a new call is needed to initialize metadata.
|
|
1984
3508
|
*/
|
|
1985
3509
|
editEntity(entity) {
|
|
1986
|
-
if (this.data.baseData.
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
3510
|
+
if (!(this.data.baseData.allowUpdate(entity) || this.data.baseData.allowRead(entity))) {
|
|
3511
|
+
return;
|
|
3512
|
+
}
|
|
3513
|
+
if (!this.data.baseData.EntityClass) {
|
|
3514
|
+
throw new Error('No "EntityClass" specified for this table');
|
|
3515
|
+
}
|
|
3516
|
+
if (this.data.baseData.edit) {
|
|
3517
|
+
this.data.baseData.edit(new this.data.baseData.EntityClass(entity));
|
|
3518
|
+
}
|
|
3519
|
+
else {
|
|
3520
|
+
void this.editDefault(new this.data.baseData.EntityClass(entity));
|
|
1996
3521
|
}
|
|
1997
3522
|
}
|
|
1998
|
-
editDefault(entity) {
|
|
3523
|
+
async editDefault(entity) {
|
|
1999
3524
|
const inputDialogData = {
|
|
2000
3525
|
entity: entity,
|
|
2001
3526
|
EntityServiceClass: this.data.baseData.EntityServiceClass,
|
|
3527
|
+
allowUpdate: this.data.baseData.allowUpdate,
|
|
2002
3528
|
allowDelete: this.data.baseData.allowDelete,
|
|
2003
3529
|
editDialogData: this.data.editDialogData
|
|
2004
3530
|
};
|
|
2005
3531
|
const dialogData = new EditEntityDialogDataBuilder(inputDialogData).getResult();
|
|
2006
|
-
firstValueFrom(this.dialog.open(NgxMatEntityEditDialogComponent, {
|
|
3532
|
+
const res = await firstValueFrom(this.dialog.open(NgxMatEntityEditDialogComponent, {
|
|
2007
3533
|
data: dialogData,
|
|
2008
3534
|
minWidth: '60%',
|
|
2009
3535
|
autoFocus: false,
|
|
2010
3536
|
restoreFocus: false
|
|
2011
|
-
}).afterClosed())
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
});
|
|
3537
|
+
}).afterClosed());
|
|
3538
|
+
if (res === 0) {
|
|
3539
|
+
const data = this.dataSource.data;
|
|
3540
|
+
data[this.dataSource.data.findIndex((e) => e[this.entityService.idKey] === entity[this.entityService.idKey])] = entity;
|
|
3541
|
+
this.dataSource.data = data;
|
|
3542
|
+
this.selection.clear();
|
|
3543
|
+
}
|
|
2019
3544
|
}
|
|
2020
3545
|
/**
|
|
2021
3546
|
* Creates a new Entity. This either calls the create-Method provided by the user or uses a default create-dialog.
|
|
@@ -2023,7 +3548,7 @@ class NgxMatEntityTableComponent {
|
|
|
2023
3548
|
* @throws When no EntityClass was provided, as a new call is needed to initialize metadata.
|
|
2024
3549
|
*/
|
|
2025
3550
|
createEntity() {
|
|
2026
|
-
if (this.data.baseData.allowCreate) {
|
|
3551
|
+
if (this.data.baseData.allowCreate()) {
|
|
2027
3552
|
if (!this.data.baseData.EntityClass) {
|
|
2028
3553
|
throw new Error('No "EntityClass" specified for this table');
|
|
2029
3554
|
}
|
|
@@ -2056,7 +3581,8 @@ class NgxMatEntityTableComponent {
|
|
|
2056
3581
|
*/
|
|
2057
3582
|
runMultiAction(action) {
|
|
2058
3583
|
if (!action.requireConfirmDialog || !action.requireConfirmDialog(this.selection.selected)) {
|
|
2059
|
-
|
|
3584
|
+
this.confirmRunMultiAction(action);
|
|
3585
|
+
return;
|
|
2060
3586
|
}
|
|
2061
3587
|
const dialogData = new ConfirmDialogDataBuilder(action.confirmDialogData)
|
|
2062
3588
|
.withDefault('text', [`Do you really want to run this action on ${this.selection.selected.length} entries?`])
|
|
@@ -2099,7 +3625,7 @@ class NgxMatEntityTableComponent {
|
|
|
2099
3625
|
this.selection.clear();
|
|
2100
3626
|
}
|
|
2101
3627
|
else {
|
|
2102
|
-
this.dataSource.data.forEach(
|
|
3628
|
+
this.dataSource.data.forEach(row => this.selection.select(row));
|
|
2103
3629
|
}
|
|
2104
3630
|
}
|
|
2105
3631
|
/**
|
|
@@ -2128,10 +3654,10 @@ class NgxMatEntityTableComponent {
|
|
|
2128
3654
|
}
|
|
2129
3655
|
}
|
|
2130
3656
|
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 });
|
|
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)\"
|
|
3657
|
+
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.allowUpdate(entity) || data.baseData.allowRead(entity)\" (click)=\"editEntity(entity)\" *matCellDef=\"let entity\">\n {{dCol.value(entity)}}\n </mat-cell>\n </ng-container>\n\n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns\"></mat-row>\n </mat-table>\n\n <mat-paginator *ngIf=\"dataSource\" id=\"paginator\" [length]=\"dataSource.filteredData.length\" [pageIndex]=\"0\" [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\"> </mat-paginator>\n</div>\n", styles: [".title{text-align:center}button{width:100%}.mat-column-select{flex:0 0 75px}.enabled:hover{cursor:pointer}@media (max-width: 767px){.actions-button,.create-button{margin-bottom:15px}}\n"], components: [{ type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$3.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i4$3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: i4$2.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i4$2.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i4$2.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { type: i7.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }], directives: [{ type: i1$1.MatLabel, selector: "mat-label" }, { type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4$3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$2.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i4$2.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i4$2.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i4$2.MatCellDef, selector: "[matCellDef]" }, { type: i4$2.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i4$2.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i4$2.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }] });
|
|
2132
3658
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NgxMatEntityTableComponent, decorators: [{
|
|
2133
3659
|
type: Component,
|
|
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)\"
|
|
3660
|
+
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.allowUpdate(entity) || data.baseData.allowRead(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
3661
|
}], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i0.Injector }]; }, propDecorators: { tableData: [{
|
|
2136
3662
|
type: Input
|
|
2137
3663
|
}], paginator: [{
|
|
@@ -2265,16 +3791,83 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
|
|
|
2265
3791
|
class EntityArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
2266
3792
|
constructor(data) {
|
|
2267
3793
|
super(data);
|
|
2268
|
-
this.createInline = data.createInline
|
|
2269
|
-
this.displayStyle = data.displayStyle;
|
|
3794
|
+
this.createInline = data.createInline ?? true;
|
|
2270
3795
|
this.itemType = data.itemType;
|
|
3796
|
+
this.allowDuplicates = data.allowDuplicates ?? false;
|
|
3797
|
+
this.duplicatesErrorDialog = getDefaultDuplicateErrorDialogData(data);
|
|
2271
3798
|
this.EntityClass = data.EntityClass;
|
|
2272
3799
|
this.displayColumns = data.displayColumns;
|
|
2273
|
-
this.createInline = data.createInline
|
|
2274
|
-
this.missingErrorMessage = data.missingErrorMessage
|
|
2275
|
-
this.defaultWidths = data.defaultWidths
|
|
2276
|
-
this.addButtonLabel = data.addButtonLabel
|
|
2277
|
-
this.removeButtonLabel = data.removeButtonLabel
|
|
3800
|
+
this.createInline = data.createInline ?? true;
|
|
3801
|
+
this.missingErrorMessage = data.missingErrorMessage ?? 'Needs to contain at least one value';
|
|
3802
|
+
this.defaultWidths = data.defaultWidths ?? [12, 12, 12];
|
|
3803
|
+
this.addButtonLabel = data.addButtonLabel ?? 'Add';
|
|
3804
|
+
this.removeButtonLabel = data.removeButtonLabel ?? 'Remove';
|
|
3805
|
+
}
|
|
3806
|
+
}
|
|
3807
|
+
/**
|
|
3808
|
+
* The internal DateArrayDecoratorConfig. Sets default values.
|
|
3809
|
+
*/
|
|
3810
|
+
class DateArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
3811
|
+
constructor(data) {
|
|
3812
|
+
super(data);
|
|
3813
|
+
this.itemType = data.itemType;
|
|
3814
|
+
this.allowDuplicates = data.allowDuplicates ?? false;
|
|
3815
|
+
this.duplicatesErrorDialog = getDefaultDuplicateErrorDialogData(data);
|
|
3816
|
+
this.displayColumns = data.displayColumns;
|
|
3817
|
+
this.defaultWidths = data.defaultWidths ?? [12, 12, 12];
|
|
3818
|
+
this.addButtonLabel = data.addButtonLabel ?? 'Add';
|
|
3819
|
+
this.removeButtonLabel = data.removeButtonLabel ?? 'Remove';
|
|
3820
|
+
this.missingErrorMessage = data.missingErrorMessage ?? 'Needs to contain at least one value';
|
|
3821
|
+
this.min = data.min;
|
|
3822
|
+
this.max = data.max;
|
|
3823
|
+
this.filter = data.filter;
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3826
|
+
/**
|
|
3827
|
+
* The internal DateTimeArrayDecoratorConfig. Sets default values.
|
|
3828
|
+
*/
|
|
3829
|
+
class DateTimeArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
3830
|
+
constructor(data) {
|
|
3831
|
+
super(data);
|
|
3832
|
+
this.itemType = data.itemType;
|
|
3833
|
+
this.allowDuplicates = data.allowDuplicates ?? false;
|
|
3834
|
+
this.duplicatesErrorDialog = getDefaultDuplicateErrorDialogData(data);
|
|
3835
|
+
this.displayColumns = data.displayColumns;
|
|
3836
|
+
this.defaultWidths = data.defaultWidths ?? [12, 12, 12];
|
|
3837
|
+
this.addButtonLabel = data.addButtonLabel ?? 'Add';
|
|
3838
|
+
this.removeButtonLabel = data.removeButtonLabel ?? 'Remove';
|
|
3839
|
+
this.missingErrorMessage = data.missingErrorMessage ?? 'Needs to contain at least one value';
|
|
3840
|
+
this.times = data.times ?? DateUtilities.getDefaultTimes();
|
|
3841
|
+
this.timeDisplayName = data.timeDisplayName ?? 'Time';
|
|
3842
|
+
this.minDate = data.minDate;
|
|
3843
|
+
this.maxDate = data.maxDate;
|
|
3844
|
+
this.filterDate = data.filterDate;
|
|
3845
|
+
this.minTime = data.minTime;
|
|
3846
|
+
this.maxTime = data.maxTime;
|
|
3847
|
+
this.filterTime = data.filterTime;
|
|
3848
|
+
}
|
|
3849
|
+
}
|
|
3850
|
+
/**
|
|
3851
|
+
* The internal DateRangeArrayDecoratorConfig. Sets default values.
|
|
3852
|
+
*/
|
|
3853
|
+
class DateRangeArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
3854
|
+
constructor(data) {
|
|
3855
|
+
super(data);
|
|
3856
|
+
this.itemType = data.itemType;
|
|
3857
|
+
this.allowDuplicates = data.allowDuplicates ?? false;
|
|
3858
|
+
this.duplicatesErrorDialog = getDefaultDuplicateErrorDialogData(data);
|
|
3859
|
+
this.displayColumns = data.displayColumns;
|
|
3860
|
+
this.defaultWidths = data.defaultWidths ?? [12, 12, 12];
|
|
3861
|
+
this.addButtonLabel = data.addButtonLabel ?? 'Add';
|
|
3862
|
+
this.removeButtonLabel = data.removeButtonLabel ?? 'Remove';
|
|
3863
|
+
this.missingErrorMessage = data.missingErrorMessage ?? 'Needs to contain at least one value';
|
|
3864
|
+
this.placeholderStart = data.placeholderStart ?? 'Start';
|
|
3865
|
+
this.placeholderEnd = data.placeholderEnd ?? 'End';
|
|
3866
|
+
this.minStart = data.minStart;
|
|
3867
|
+
this.maxStart = data.maxStart;
|
|
3868
|
+
this.minEnd = data.minEnd;
|
|
3869
|
+
this.maxEnd = data.maxEnd;
|
|
3870
|
+
this.filter = data.filter;
|
|
2278
3871
|
}
|
|
2279
3872
|
}
|
|
2280
3873
|
/**
|
|
@@ -2283,13 +3876,14 @@ class EntityArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal
|
|
|
2283
3876
|
class StringChipsArrayDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
2284
3877
|
constructor(data) {
|
|
2285
3878
|
super(data);
|
|
2286
|
-
this.deleteIcon = data.deleteIcon
|
|
2287
|
-
this.displayStyle = data.displayStyle;
|
|
3879
|
+
this.deleteIcon = data.deleteIcon ?? 'fas fa-circle-minus';
|
|
2288
3880
|
this.itemType = data.itemType;
|
|
3881
|
+
this.allowDuplicates = data.allowDuplicates ?? false;
|
|
3882
|
+
this.duplicatesErrorDialog = getDefaultDuplicateErrorDialogData(data);
|
|
2289
3883
|
this.maxLength = data.maxLength;
|
|
2290
3884
|
this.minLength = data.minLength;
|
|
2291
3885
|
this.regex = data.regex;
|
|
2292
|
-
this.defaultWidths = data.defaultWidths
|
|
3886
|
+
this.defaultWidths = data.defaultWidths ?? [6, 12, 12];
|
|
2293
3887
|
}
|
|
2294
3888
|
}
|
|
2295
3889
|
/**
|
|
@@ -2299,15 +3893,34 @@ class AutocompleteStringChipsArrayDecoratorConfigInternal extends PropertyDecora
|
|
|
2299
3893
|
constructor(data) {
|
|
2300
3894
|
super(data);
|
|
2301
3895
|
this.autocompleteValues = data.autocompleteValues;
|
|
2302
|
-
this.deleteIcon = data.deleteIcon
|
|
2303
|
-
this.displayStyle = data.displayStyle;
|
|
3896
|
+
this.deleteIcon = data.deleteIcon ?? 'fas fa-circle-minus';
|
|
2304
3897
|
this.itemType = data.itemType;
|
|
3898
|
+
this.allowDuplicates = data.allowDuplicates ?? false;
|
|
3899
|
+
this.duplicatesErrorDialog = getDefaultDuplicateErrorDialogData(data);
|
|
2305
3900
|
this.maxLength = data.maxLength;
|
|
2306
3901
|
this.minLength = data.minLength;
|
|
2307
3902
|
this.regex = data.regex;
|
|
2308
|
-
this.defaultWidths = data.defaultWidths
|
|
3903
|
+
this.defaultWidths = data.defaultWidths ?? [6, 12, 12];
|
|
2309
3904
|
}
|
|
2310
3905
|
}
|
|
3906
|
+
/**
|
|
3907
|
+
* Gets the default dialog data for the error dialog to display when the user tries to add a duplicate value.
|
|
3908
|
+
*
|
|
3909
|
+
* @param data - The Array Decorator data.
|
|
3910
|
+
* @returns The dialog data with set default values.
|
|
3911
|
+
*/
|
|
3912
|
+
function getDefaultDuplicateErrorDialogData(data) {
|
|
3913
|
+
return {
|
|
3914
|
+
type: data.duplicatesErrorDialog?.type ?? 'info-only',
|
|
3915
|
+
// eslint-disable-next-line max-len
|
|
3916
|
+
text: data.duplicatesErrorDialog?.text ?? ['Adding duplicate entries to the array is not allowed.'],
|
|
3917
|
+
title: data.duplicatesErrorDialog?.title ?? 'Error adding duplicate item',
|
|
3918
|
+
confirmButtonLabel: data.duplicatesErrorDialog?.confirmButtonLabel,
|
|
3919
|
+
cancelButtonLabel: data.duplicatesErrorDialog?.cancelButtonLabel,
|
|
3920
|
+
requireConfirmation: data.duplicatesErrorDialog?.requireConfirmation,
|
|
3921
|
+
confirmationText: data.duplicatesErrorDialog?.confirmationText
|
|
3922
|
+
};
|
|
3923
|
+
}
|
|
2311
3924
|
|
|
2312
3925
|
/**
|
|
2313
3926
|
* Decorator for setting and getting array property metadata.
|
|
@@ -2320,6 +3933,12 @@ function array(metadata) {
|
|
|
2320
3933
|
switch (metadata.itemType) {
|
|
2321
3934
|
case DecoratorTypes.OBJECT:
|
|
2322
3935
|
return baseProperty(new EntityArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY);
|
|
3936
|
+
case DecoratorTypes.DATE:
|
|
3937
|
+
return baseProperty(new DateArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY_DATE);
|
|
3938
|
+
case DecoratorTypes.DATE_TIME:
|
|
3939
|
+
return baseProperty(new DateTimeArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY_DATE_TIME);
|
|
3940
|
+
case DecoratorTypes.DATE_RANGE:
|
|
3941
|
+
return baseProperty(new DateRangeArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY_DATE_RANGE);
|
|
2323
3942
|
case DecoratorTypes.STRING:
|
|
2324
3943
|
return baseProperty(new StringChipsArrayDecoratorConfigInternal(metadata), DecoratorTypes.ARRAY_STRING_CHIPS);
|
|
2325
3944
|
case DecoratorTypes.STRING_AUTOCOMPLETE:
|
|
@@ -2360,7 +3979,7 @@ class CheckboxBooleanDecoratorConfigInternal extends PropertyDecoratorConfigInte
|
|
|
2360
3979
|
constructor(data) {
|
|
2361
3980
|
super(data);
|
|
2362
3981
|
this.displayStyle = data.displayStyle;
|
|
2363
|
-
this.required = data.required
|
|
3982
|
+
this.required = data.required ?? false;
|
|
2364
3983
|
}
|
|
2365
3984
|
}
|
|
2366
3985
|
/**
|
|
@@ -2370,7 +3989,7 @@ class ToggleBooleanDecoratorConfigInternal extends PropertyDecoratorConfigIntern
|
|
|
2370
3989
|
constructor(data) {
|
|
2371
3990
|
super(data);
|
|
2372
3991
|
this.displayStyle = data.displayStyle;
|
|
2373
|
-
this.required = data.required
|
|
3992
|
+
this.required = data.required ?? false;
|
|
2374
3993
|
}
|
|
2375
3994
|
}
|
|
2376
3995
|
|
|
@@ -2398,6 +4017,76 @@ function boolean(metadata) {
|
|
|
2398
4017
|
class BooleanDecoratorConfig extends PropertyDecoratorConfig {
|
|
2399
4018
|
}
|
|
2400
4019
|
|
|
4020
|
+
/**
|
|
4021
|
+
* The internal DefaultDateDecoratorConfig. Sets default values.
|
|
4022
|
+
*/
|
|
4023
|
+
class DefaultDateDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
4024
|
+
constructor(data) {
|
|
4025
|
+
super(data);
|
|
4026
|
+
this.displayStyle = data.displayStyle;
|
|
4027
|
+
this.max = data.max;
|
|
4028
|
+
this.min = data.min;
|
|
4029
|
+
this.filter = data.filter;
|
|
4030
|
+
}
|
|
4031
|
+
}
|
|
4032
|
+
/**
|
|
4033
|
+
* The internal DateRangeDateDecoratorConfig. Sets default values.
|
|
4034
|
+
*/
|
|
4035
|
+
class DateRangeDateDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
4036
|
+
constructor(data) {
|
|
4037
|
+
super(data);
|
|
4038
|
+
this.displayStyle = data.displayStyle;
|
|
4039
|
+
this.minStart = data.minStart;
|
|
4040
|
+
this.maxStart = data.maxStart;
|
|
4041
|
+
this.minEnd = data.minEnd;
|
|
4042
|
+
this.maxEnd = data.maxEnd;
|
|
4043
|
+
this.filter = data.filter;
|
|
4044
|
+
this.placeholderStart = data.placeholderStart ?? 'Start';
|
|
4045
|
+
this.placeholderEnd = data.placeholderEnd ?? 'End';
|
|
4046
|
+
}
|
|
4047
|
+
}
|
|
4048
|
+
/**
|
|
4049
|
+
* The internal DateTimeDateDecoratorConfig. Sets default values.
|
|
4050
|
+
*/
|
|
4051
|
+
class DateTimeDateDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
4052
|
+
constructor(data) {
|
|
4053
|
+
super(data);
|
|
4054
|
+
this.displayStyle = data.displayStyle;
|
|
4055
|
+
this.times = data.times ?? DateUtilities.getDefaultTimes();
|
|
4056
|
+
this.timeDisplayName = data.timeDisplayName ?? 'Time';
|
|
4057
|
+
this.minDate = data.minDate;
|
|
4058
|
+
this.maxDate = data.maxDate;
|
|
4059
|
+
this.filterDate = data.filterDate;
|
|
4060
|
+
this.minTime = data.minTime;
|
|
4061
|
+
this.maxTime = data.maxTime;
|
|
4062
|
+
this.filterTime = data.filterTime;
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
|
|
4066
|
+
/**
|
|
4067
|
+
* Decorator for setting and getting date property metadata.
|
|
4068
|
+
*
|
|
4069
|
+
* @param metadata - The metadata of the date property.
|
|
4070
|
+
* @returns The method that defines the metadata.
|
|
4071
|
+
*/
|
|
4072
|
+
function date(metadata) {
|
|
4073
|
+
if (metadata.displayStyle === 'date') {
|
|
4074
|
+
return baseProperty(new DefaultDateDecoratorConfigInternal(metadata), DecoratorTypes.DATE);
|
|
4075
|
+
}
|
|
4076
|
+
else if (metadata.displayStyle === 'datetime') {
|
|
4077
|
+
return baseProperty(new DateTimeDateDecoratorConfigInternal(metadata), DecoratorTypes.DATE_TIME);
|
|
4078
|
+
}
|
|
4079
|
+
else {
|
|
4080
|
+
return baseProperty(new DateRangeDateDecoratorConfigInternal(metadata), DecoratorTypes.DATE_RANGE);
|
|
4081
|
+
}
|
|
4082
|
+
}
|
|
4083
|
+
|
|
4084
|
+
/**
|
|
4085
|
+
* Definition for the @date metadata.
|
|
4086
|
+
*/
|
|
4087
|
+
class DateDecoratorConfig extends PropertyDecoratorConfig {
|
|
4088
|
+
}
|
|
4089
|
+
|
|
2401
4090
|
/**
|
|
2402
4091
|
* The internal DefaultNumberDecoratorConfig. Sets default values.
|
|
2403
4092
|
*/
|
|
@@ -2419,6 +4108,29 @@ class DropdownNumberDecoratorConfigInternal extends PropertyDecoratorConfigInter
|
|
|
2419
4108
|
this.dropdownValues = data.dropdownValues;
|
|
2420
4109
|
}
|
|
2421
4110
|
}
|
|
4111
|
+
/**
|
|
4112
|
+
* The internal SliderNumberDecoratorConfig. Sets default values.
|
|
4113
|
+
*/
|
|
4114
|
+
class SliderNumberDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
4115
|
+
constructor(data) {
|
|
4116
|
+
super(data);
|
|
4117
|
+
this.displayStyle = data.displayStyle;
|
|
4118
|
+
this.max = data.max;
|
|
4119
|
+
this.min = data.min;
|
|
4120
|
+
this.step = data.step;
|
|
4121
|
+
this.formatThumbLabelValue = data.formatThumbLabelValue ?? defaultFormatThumbLabelValue;
|
|
4122
|
+
this.tickInterval = data.tickInterval;
|
|
4123
|
+
}
|
|
4124
|
+
}
|
|
4125
|
+
/**
|
|
4126
|
+
* The default function to format values for the number slider thumb label.
|
|
4127
|
+
*
|
|
4128
|
+
* @param value - The value of the slider.
|
|
4129
|
+
* @returns Just the value without any formatting done.
|
|
4130
|
+
*/
|
|
4131
|
+
function defaultFormatThumbLabelValue(value) {
|
|
4132
|
+
return value;
|
|
4133
|
+
}
|
|
2422
4134
|
|
|
2423
4135
|
/**
|
|
2424
4136
|
* Decorator for setting and getting number property metadata.
|
|
@@ -2427,11 +4139,13 @@ class DropdownNumberDecoratorConfigInternal extends PropertyDecoratorConfigInter
|
|
|
2427
4139
|
* @returns The method that defines the metadata.
|
|
2428
4140
|
*/
|
|
2429
4141
|
function number(metadata) {
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
4142
|
+
switch (metadata.displayStyle) {
|
|
4143
|
+
case 'dropdown':
|
|
4144
|
+
return baseProperty(new DropdownNumberDecoratorConfigInternal(metadata), DecoratorTypes.NUMBER_DROPDOWN);
|
|
4145
|
+
case 'slider':
|
|
4146
|
+
return baseProperty(new SliderNumberDecoratorConfigInternal(metadata), DecoratorTypes.NUMBER_SLIDER);
|
|
4147
|
+
default:
|
|
4148
|
+
return baseProperty(new DefaultNumberDecoratorConfigInternal(metadata), DecoratorTypes.NUMBER);
|
|
2435
4149
|
}
|
|
2436
4150
|
}
|
|
2437
4151
|
|
|
@@ -2474,6 +4188,162 @@ class ObjectDecoratorConfig extends PropertyDecoratorConfig {
|
|
|
2474
4188
|
class StringDecoratorConfig extends PropertyDecoratorConfig {
|
|
2475
4189
|
}
|
|
2476
4190
|
|
|
4191
|
+
/**
|
|
4192
|
+
* The internal DefaultFileDecoratorConfig. Sets default values.
|
|
4193
|
+
*/
|
|
4194
|
+
class DefaultFileDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
4195
|
+
constructor(data) {
|
|
4196
|
+
super(data);
|
|
4197
|
+
this.type = data.type;
|
|
4198
|
+
this.preview = false;
|
|
4199
|
+
this.multiple = data.multiple;
|
|
4200
|
+
this.deleteIcon = data.deleteIcon ?? 'fas fa-circle-minus';
|
|
4201
|
+
this.allowedMimeTypes = data.allowedMimeTypes ?? ['*'];
|
|
4202
|
+
this.maxSize = data.maxSize ?? 10;
|
|
4203
|
+
this.maxSizeTotal = data.maxSizeTotal ?? 100;
|
|
4204
|
+
this.mimeTypeErrorDialog = data.mimeTypeErrorDialog ?? getDefaultMimeTypeErrorDialogData(data);
|
|
4205
|
+
this.maxSizeErrorDialog = data.maxSizeErrorDialog ?? getDefaultMaxSizeErrorDialogData(data);
|
|
4206
|
+
this.maxSizeTotalErrorDialog = data.maxSizeTotalErrorDialog ?? getDefaultMaxSizeTotalErrorDialogData(data);
|
|
4207
|
+
this.dragAndDrop = data.dragAndDrop ?? data.multiple;
|
|
4208
|
+
}
|
|
4209
|
+
}
|
|
4210
|
+
/**
|
|
4211
|
+
* The internal ImageFileDecoratorConfig. Sets default values.
|
|
4212
|
+
*/
|
|
4213
|
+
class ImageFileDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
4214
|
+
constructor(data) {
|
|
4215
|
+
super(data);
|
|
4216
|
+
this.type = data.type;
|
|
4217
|
+
this.allowedMimeTypes = data.allowedMimeTypes ?? ['image/*'];
|
|
4218
|
+
this.multiple = data.multiple;
|
|
4219
|
+
this.preview = data.preview ?? true;
|
|
4220
|
+
this.deleteIcon = data.deleteIcon ?? 'fas fa-circle-minus';
|
|
4221
|
+
this.maxSize = data.maxSize ?? 10;
|
|
4222
|
+
this.maxSizeTotal = data.maxSizeTotal ?? 100;
|
|
4223
|
+
this.mimeTypeErrorDialog = data.mimeTypeErrorDialog ?? getDefaultMimeTypeErrorDialogData(data);
|
|
4224
|
+
this.maxSizeErrorDialog = data.maxSizeErrorDialog ?? getDefaultMaxSizeErrorDialogData(data);
|
|
4225
|
+
this.maxSizeTotalErrorDialog = data.maxSizeTotalErrorDialog ?? getDefaultMaxSizeTotalErrorDialogData(data);
|
|
4226
|
+
this.previewPlaceholderUrl = data.previewPlaceholderUrl;
|
|
4227
|
+
this.dragAndDrop = data.dragAndDrop ?? data.multiple;
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
4230
|
+
/**
|
|
4231
|
+
* Gets the default dialog data for the error dialog to display
|
|
4232
|
+
* when the user tries to add a file with a wrong type.
|
|
4233
|
+
*
|
|
4234
|
+
* @param data - The File Decorator data.
|
|
4235
|
+
* @returns The dialog data with set default values.
|
|
4236
|
+
*/
|
|
4237
|
+
function getDefaultMimeTypeErrorDialogData(data) {
|
|
4238
|
+
return {
|
|
4239
|
+
type: data.mimeTypeErrorDialog?.type ?? 'info-only',
|
|
4240
|
+
// eslint-disable-next-line max-len
|
|
4241
|
+
text: data.mimeTypeErrorDialog?.text ?? (data.multiple ? ['One of the uploaded files has the wrong type.'] : ['The uploaded file has the wrong type.']),
|
|
4242
|
+
title: data.mimeTypeErrorDialog?.title ?? (data.multiple ? 'Error adding files' : 'Error adding file'),
|
|
4243
|
+
confirmButtonLabel: data.mimeTypeErrorDialog?.confirmButtonLabel,
|
|
4244
|
+
cancelButtonLabel: data.mimeTypeErrorDialog?.cancelButtonLabel,
|
|
4245
|
+
requireConfirmation: data.mimeTypeErrorDialog?.requireConfirmation,
|
|
4246
|
+
confirmationText: data.mimeTypeErrorDialog?.confirmationText
|
|
4247
|
+
};
|
|
4248
|
+
}
|
|
4249
|
+
/**
|
|
4250
|
+
* Gets the default dialog data for the error dialog to display
|
|
4251
|
+
* when the user tries to add a single file that is bigger than the allowed maxSize.
|
|
4252
|
+
*
|
|
4253
|
+
* @param data - The File Decorator data.
|
|
4254
|
+
* @returns The dialog data with set default values.
|
|
4255
|
+
*/
|
|
4256
|
+
function getDefaultMaxSizeErrorDialogData(data) {
|
|
4257
|
+
return {
|
|
4258
|
+
type: data.mimeTypeErrorDialog?.type ?? 'info-only',
|
|
4259
|
+
// eslint-disable-next-line max-len
|
|
4260
|
+
text: data.mimeTypeErrorDialog?.text ?? (data.multiple ? ['One of the uploaded files is too big'] : ['The uploaded files is too big']),
|
|
4261
|
+
title: data.mimeTypeErrorDialog?.title ?? (data.multiple ? 'Error adding files' : 'Error adding file'),
|
|
4262
|
+
confirmButtonLabel: data.mimeTypeErrorDialog?.confirmButtonLabel,
|
|
4263
|
+
cancelButtonLabel: data.mimeTypeErrorDialog?.cancelButtonLabel,
|
|
4264
|
+
requireConfirmation: data.mimeTypeErrorDialog?.requireConfirmation,
|
|
4265
|
+
confirmationText: data.mimeTypeErrorDialog?.confirmationText
|
|
4266
|
+
};
|
|
4267
|
+
}
|
|
4268
|
+
/**
|
|
4269
|
+
* Gets the default dialog data for the error dialog to display
|
|
4270
|
+
* when the user tries to add a single file that is bigger than the allowed maxSize.
|
|
4271
|
+
*
|
|
4272
|
+
* @param data - The File Decorator data.
|
|
4273
|
+
* @returns The dialog data with set default values.
|
|
4274
|
+
*/
|
|
4275
|
+
function getDefaultMaxSizeTotalErrorDialogData(data) {
|
|
4276
|
+
return {
|
|
4277
|
+
type: data.mimeTypeErrorDialog?.type ?? 'info-only',
|
|
4278
|
+
// eslint-disable-next-line max-len
|
|
4279
|
+
text: data.mimeTypeErrorDialog?.text ?? ['The size of all files combined is too big'],
|
|
4280
|
+
title: data.mimeTypeErrorDialog?.title ?? (data.multiple ? 'Error adding files' : 'Error adding file'),
|
|
4281
|
+
confirmButtonLabel: data.mimeTypeErrorDialog?.confirmButtonLabel,
|
|
4282
|
+
cancelButtonLabel: data.mimeTypeErrorDialog?.cancelButtonLabel,
|
|
4283
|
+
requireConfirmation: data.mimeTypeErrorDialog?.requireConfirmation,
|
|
4284
|
+
confirmationText: data.mimeTypeErrorDialog?.confirmationText
|
|
4285
|
+
};
|
|
4286
|
+
}
|
|
4287
|
+
|
|
4288
|
+
/**
|
|
4289
|
+
* Decorator for setting and getting file property metadata.
|
|
4290
|
+
*
|
|
4291
|
+
* @param metadata - The metadata of the file property.
|
|
4292
|
+
* @returns The method that defines the metadata.
|
|
4293
|
+
* @throws When an unknown metadata type was provided.
|
|
4294
|
+
*/
|
|
4295
|
+
function file(metadata) {
|
|
4296
|
+
switch (metadata.type) {
|
|
4297
|
+
case 'other':
|
|
4298
|
+
return baseProperty(new DefaultFileDecoratorConfigInternal(metadata), DecoratorTypes.FILE_DEFAULT);
|
|
4299
|
+
case 'image':
|
|
4300
|
+
return baseProperty(new ImageFileDecoratorConfigInternal(metadata), DecoratorTypes.FILE_IMAGE);
|
|
4301
|
+
default:
|
|
4302
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
4303
|
+
throw new Error(`Unknown metadata type ${metadata.type}`);
|
|
4304
|
+
}
|
|
4305
|
+
}
|
|
4306
|
+
|
|
4307
|
+
/**
|
|
4308
|
+
* Definition for the @file metadata.
|
|
4309
|
+
*/
|
|
4310
|
+
class FileDecoratorConfig extends PropertyDecoratorConfig {
|
|
4311
|
+
}
|
|
4312
|
+
|
|
4313
|
+
/**
|
|
4314
|
+
* The default function to use for checking if the value is dirty.
|
|
4315
|
+
*
|
|
4316
|
+
* @param value - The current value.
|
|
4317
|
+
* @param valuePriorChanges - The value before any changes.
|
|
4318
|
+
* @returns Whether or not the provided value has been changed.
|
|
4319
|
+
*/
|
|
4320
|
+
function defaultIsEqual(value, valuePriorChanges) {
|
|
4321
|
+
return LodashUtilities.isEqual(value, valuePriorChanges);
|
|
4322
|
+
}
|
|
4323
|
+
/**
|
|
4324
|
+
* The internal config for the @custom decorator.
|
|
4325
|
+
* Sets default values.
|
|
4326
|
+
*/
|
|
4327
|
+
class CustomDecoratorConfigInternal extends PropertyDecoratorConfigInternal {
|
|
4328
|
+
constructor(data) {
|
|
4329
|
+
super(data);
|
|
4330
|
+
this.component = data.component;
|
|
4331
|
+
this.isValid = data.isValid ?? (() => true);
|
|
4332
|
+
this.isEqual = data.isEqual ?? defaultIsEqual;
|
|
4333
|
+
this.customMetadata = data.customMetadata;
|
|
4334
|
+
}
|
|
4335
|
+
}
|
|
4336
|
+
|
|
4337
|
+
/**
|
|
4338
|
+
* Decorator for setting and getting custom property metadata.
|
|
4339
|
+
*
|
|
4340
|
+
* @param metadata - The metadata of the custom property.
|
|
4341
|
+
* @returns The method that defines the metadata.
|
|
4342
|
+
*/
|
|
4343
|
+
function custom(metadata) {
|
|
4344
|
+
return baseProperty(new CustomDecoratorConfigInternal(metadata), DecoratorTypes.CUSTOM);
|
|
4345
|
+
}
|
|
4346
|
+
|
|
2477
4347
|
/**
|
|
2478
4348
|
* Public API Surface of ngx-material-entity.
|
|
2479
4349
|
*/
|
|
@@ -2482,5 +4352,5 @@ class StringDecoratorConfig extends PropertyDecoratorConfig {
|
|
|
2482
4352
|
* Generated bundle index. Do not edit.
|
|
2483
4353
|
*/
|
|
2484
4354
|
|
|
2485
|
-
export { DateUtilities, DecoratorTypes, Entity, EntityService, EntityUtilities, NgxMatEntityConfirmDialogComponent, NgxMatEntityConfirmDialogModule, NgxMatEntityCreateDialogComponent, NgxMatEntityCreateDialogModule, NgxMatEntityEditDialogComponent, NgxMatEntityEditDialogModule, NgxMatEntityInputComponent, NgxMatEntityInputModule, NgxMatEntityTableComponent, NgxMatEntityTableModule, array, boolean, getValidationErrorMessage, number, object, string };
|
|
4355
|
+
export { ArrayDecoratorConfig, DateUtilities, DecoratorTypes, Entity, EntityService, EntityUtilities, FileUtilities, NgxMatEntityBaseInputComponent, NgxMatEntityConfirmDialogComponent, NgxMatEntityConfirmDialogModule, NgxMatEntityCreateDialogComponent, NgxMatEntityCreateDialogModule, NgxMatEntityEditDialogComponent, NgxMatEntityEditDialogModule, NgxMatEntityInputComponent, NgxMatEntityInputModule, NgxMatEntityTableComponent, NgxMatEntityTableModule, array, boolean, custom, date, file, getValidationErrorMessage, number, object, string };
|
|
2486
4356
|
//# sourceMappingURL=ngx-material-entity.mjs.map
|