@stemy/ngx-dynamic-form 19.1.13 → 19.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/fesm2022/stemy-ngx-dynamic-form-ui-nebular.mjs +4 -4
  2. package/fesm2022/stemy-ngx-dynamic-form-ui-nebular.mjs.map +1 -1
  3. package/fesm2022/stemy-ngx-dynamic-form.mjs +859 -1662
  4. package/fesm2022/stemy-ngx-dynamic-form.mjs.map +1 -1
  5. package/ngx-dynamic-form/common-types.d.ts +109 -26
  6. package/ngx-dynamic-form/components/dynamic-form/dynamic-form.component.d.ts +21 -0
  7. package/ngx-dynamic-form/components/dynamic-form-array/dynamic-form-array.component.d.ts +9 -0
  8. package/ngx-dynamic-form/components/dynamic-form-chips/dynamic-form-chips.component.d.ts +7 -0
  9. package/ngx-dynamic-form/components/dynamic-form-field/dynamic-form-field.component.d.ts +6 -0
  10. package/ngx-dynamic-form/components/dynamic-form-fieldset/dynamic-form-fieldset.component.d.ts +7 -0
  11. package/ngx-dynamic-form/components/dynamic-form-group/dynamic-form-group.component.d.ts +6 -0
  12. package/ngx-dynamic-form/components/dynamic-form-upload/dynamic-form-upload.component.d.ts +7 -0
  13. package/ngx-dynamic-form/directives/async-submit.directive.d.ts +17 -23
  14. package/ngx-dynamic-form/ngx-dynamic-form.imports.d.ts +5 -9
  15. package/ngx-dynamic-form/ngx-dynamic-form.module.d.ts +13 -11
  16. package/ngx-dynamic-form/services/dynamic-form-builder.service.d.ts +27 -0
  17. package/ngx-dynamic-form/services/dynamic-form.service.d.ts +28 -46
  18. package/ngx-dynamic-form/utils/customizer.d.ts +5 -12
  19. package/ngx-dynamic-form/utils/decorators.d.ts +10 -0
  20. package/ngx-dynamic-form/utils/misc.d.ts +2 -4
  21. package/ngx-dynamic-form/utils/validation.d.ts +13 -0
  22. package/package.json +21 -16
  23. package/public_api.d.ts +13 -18
  24. package/ui-nebular/index.d.ts +1 -5
  25. package/common-types.d.ts +0 -37
  26. package/components/base/dynamic-base-form-array.component.d.ts +0 -38
  27. package/components/base/dynamic-base-form-control-container.component.d.ts +0 -39
  28. package/components/base/dynamic-base-form-control.component.d.ts +0 -26
  29. package/components/base/dynamic-base-form-group.component.d.ts +0 -25
  30. package/components/base/dynamic-base-form.component.d.ts +0 -46
  31. package/components/base/dynamic-base-select.component.d.ts +0 -15
  32. package/directives/async-submit.directive.d.ts +0 -31
  33. package/esm2020/ngx-dynamic-form/common-types.mjs +0 -2
  34. package/esm2020/ngx-dynamic-form/components/base/dynamic-base-form-array.component.mjs +0 -104
  35. package/esm2020/ngx-dynamic-form/components/base/dynamic-base-form-control-container.component.mjs +0 -127
  36. package/esm2020/ngx-dynamic-form/components/base/dynamic-base-form-control.component.mjs +0 -57
  37. package/esm2020/ngx-dynamic-form/components/base/dynamic-base-form-group.component.mjs +0 -75
  38. package/esm2020/ngx-dynamic-form/components/base/dynamic-base-form.component.mjs +0 -182
  39. package/esm2020/ngx-dynamic-form/components/base/dynamic-base-select.component.mjs +0 -66
  40. package/esm2020/ngx-dynamic-form/directives/async-submit.directive.mjs +0 -116
  41. package/esm2020/ngx-dynamic-form/ngx-dynamic-form.imports.mjs +0 -26
  42. package/esm2020/ngx-dynamic-form/ngx-dynamic-form.module.mjs +0 -116
  43. package/esm2020/ngx-dynamic-form/services/dynamic-form.service.mjs +0 -615
  44. package/esm2020/ngx-dynamic-form/utils/creators.mjs +0 -67
  45. package/esm2020/ngx-dynamic-form/utils/customizer.mjs +0 -28
  46. package/esm2020/ngx-dynamic-form/utils/dynamic-editor.model.mjs +0 -14
  47. package/esm2020/ngx-dynamic-form/utils/dynamic-form-array.model.mjs +0 -128
  48. package/esm2020/ngx-dynamic-form/utils/dynamic-form-group.model.mjs +0 -26
  49. package/esm2020/ngx-dynamic-form/utils/dynamic-select.model.mjs +0 -59
  50. package/esm2020/ngx-dynamic-form/utils/form-select-subject.mjs +0 -26
  51. package/esm2020/ngx-dynamic-form/utils/form-subject.mjs +0 -29
  52. package/esm2020/ngx-dynamic-form/utils/misc.mjs +0 -47
  53. package/esm2020/ngx-dynamic-form/utils/validation-errors.mjs +0 -22
  54. package/esm2020/ngx-dynamic-form/utils/validators.mjs +0 -56
  55. package/esm2020/public_api.mjs +0 -21
  56. package/esm2020/stemy-ngx-dynamic-form.mjs +0 -5
  57. package/fesm2015/stemy-ngx-dynamic-form.mjs +0 -1927
  58. package/fesm2015/stemy-ngx-dynamic-form.mjs.map +0 -1
  59. package/fesm2020/stemy-ngx-dynamic-form.mjs +0 -1893
  60. package/fesm2020/stemy-ngx-dynamic-form.mjs.map +0 -1
  61. package/fesm2022/stemy-ngx-dynamic-form-src-ngx-dynamic-form-nebular.mjs +0 -50
  62. package/fesm2022/stemy-ngx-dynamic-form-src-ngx-dynamic-form-nebular.mjs.map +0 -1
  63. package/imports.d.ts +0 -12
  64. package/ngx-dynamic-form/components/base/dynamic-base-form-array.component.d.ts +0 -38
  65. package/ngx-dynamic-form/components/base/dynamic-base-form-control-container.component.d.ts +0 -39
  66. package/ngx-dynamic-form/components/base/dynamic-base-form-control.component.d.ts +0 -26
  67. package/ngx-dynamic-form/components/base/dynamic-base-form-group.component.d.ts +0 -25
  68. package/ngx-dynamic-form/components/base/dynamic-base-form.component.d.ts +0 -46
  69. package/ngx-dynamic-form/components/base/dynamic-base-select.component.d.ts +0 -15
  70. package/ngx-dynamic-form/services/dynamic-form-layout.service.d.ts +0 -7
  71. package/ngx-dynamic-form/utils/creators.d.ts +0 -18
  72. package/ngx-dynamic-form/utils/dynamic-editor.model.d.ts +0 -11
  73. package/ngx-dynamic-form/utils/dynamic-form-array.model.d.ts +0 -69
  74. package/ngx-dynamic-form/utils/dynamic-form-group.model.d.ts +0 -14
  75. package/ngx-dynamic-form/utils/dynamic-select.model.d.ts +0 -39
  76. package/ngx-dynamic-form/utils/form-select-subject.d.ts +0 -6
  77. package/ngx-dynamic-form/utils/form-subject.d.ts +0 -10
  78. package/ngx-dynamic-form/utils/validators.d.ts +0 -8
  79. package/ngx-dynamic-form.imports.d.ts +0 -12
  80. package/ngx-dynamic-form.module.d.ts +0 -21
  81. package/services/dynamic-form.service.d.ts +0 -61
  82. package/src/ngx-dynamic-form/nebular/imports.d.ts +0 -4
  83. package/src/ngx-dynamic-form/nebular/index.d.ts +0 -5
  84. package/src/ngx-dynamic-form/nebular/ngx-dynamic-form.nebular.module.d.ts +0 -9
  85. package/src/ngx-dynamic-form/nebular/public_api.d.ts +0 -1
  86. package/stemy-ngx-dynamic-form.d.ts +0 -5
  87. package/ui-nebular/public_api.d.ts +0 -1
  88. package/utils/creators.d.ts +0 -18
  89. package/utils/customizer.d.ts +0 -14
  90. package/utils/dynamic-editor.model.d.ts +0 -11
  91. package/utils/dynamic-form-array.model.d.ts +0 -69
  92. package/utils/dynamic-form-group.model.d.ts +0 -14
  93. package/utils/dynamic-select.model.d.ts +0 -39
  94. package/utils/form-select-subject.d.ts +0 -6
  95. package/utils/form-subject.d.ts +0 -10
  96. package/utils/misc.d.ts +0 -11
  97. package/utils/validation-errors.d.ts +0 -11
  98. package/utils/validators.d.ts +0 -8
@@ -1,1893 +0,0 @@
1
- import * as i1 from '@ng-dynamic-forms/core';
2
- import { DynamicInputControlModel, DYNAMIC_FORM_CONTROL_TYPE_EDITOR, serializable, DynamicFormArrayGroupModel as DynamicFormArrayGroupModel$1, DynamicFormArrayModel as DynamicFormArrayModel$1, DynamicFormGroupModel as DynamicFormGroupModel$1, DynamicFormOption as DynamicFormOption$1, DynamicSelectModel as DynamicSelectModel$1, DynamicCheckboxModel, DynamicDatePickerModel, DynamicInputModel, DynamicTextAreaModel, DynamicFileUploadModel, DynamicFormService as DynamicFormService$1, DynamicFormValueControlModel, DynamicFormComponent, DynamicTemplateDirective, DynamicFormControlContainerComponent, DYNAMIC_FORM_CONTROL_TYPE_ARRAY, DynamicFormArrayComponent, DynamicFormControlComponent, DynamicFormGroupComponent, DYNAMIC_FORM_CONTROL_MAP_FN, DYNAMIC_VALIDATORS } from '@ng-dynamic-forms/core';
3
- export { DYNAMIC_FORM_CONTROL_TYPE_ARRAY, DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX, DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX_GROUP, DYNAMIC_FORM_CONTROL_TYPE_DATEPICKER, DYNAMIC_FORM_CONTROL_TYPE_EDITOR, DYNAMIC_FORM_CONTROL_TYPE_FILE_UPLOAD, DYNAMIC_FORM_CONTROL_TYPE_GROUP, DYNAMIC_FORM_CONTROL_TYPE_INPUT, DYNAMIC_FORM_CONTROL_TYPE_RADIO_GROUP, DYNAMIC_FORM_CONTROL_TYPE_SELECT, DYNAMIC_FORM_CONTROL_TYPE_TEXTAREA, DynamicCheckboxGroupModel, DynamicCheckboxModel, DynamicDatePickerModel, DynamicFileUploadModel, DynamicFormControlComponent, DynamicFormControlModel, DynamicFormsCoreModule, DynamicInputModel, DynamicListDirective, DynamicRadioGroupModel, DynamicTemplateDirective, DynamicTextAreaModel } from '@ng-dynamic-forms/core';
4
- import * as i2 from '@stemy/ngx-utils';
5
- import { ObjectUtils, TimerUtils, cachedFactory, StringUtils, OpenApiService, TOASTER_SERVICE, ObservableUtils, EventsService, NgxUtilsModule } from '@stemy/ngx-utils';
6
- import { __decorate } from 'tslib';
7
- import { BehaviorSubject, of, isObservable, Subject, firstValueFrom, Subscription } from 'rxjs';
8
- import { map, debounceTime, groupBy, mergeMap, first } from 'rxjs/operators';
9
- import * as i0 from '@angular/core';
10
- import { Injector, Injectable, Inject, EventEmitter, Directive, Input, Output, HostBinding, HostListener, QueryList, Component, ChangeDetectionStrategy, ContentChildren, ViewChildren, ViewContainerRef, ViewChild, forwardRef, NgModule } from '@angular/core';
11
- import { FormGroup, FormArray, FormsModule, ReactiveFormsModule, NG_VALIDATORS } from '@angular/forms';
12
- import { CommonModule } from '@angular/common';
13
-
14
- class DynamicEditorModel extends DynamicInputControlModel {
15
- constructor(config, layout) {
16
- super(config, layout);
17
- this.type = DYNAMIC_FORM_CONTROL_TYPE_EDITOR;
18
- this.inputType = config.inputType || "javascript";
19
- this.convertObject = config.convertObject !== false;
20
- }
21
- }
22
- __decorate([
23
- serializable()
24
- ], DynamicEditorModel.prototype, "type", void 0);
25
-
26
- class DynamicFormArrayGroupModel extends DynamicFormArrayGroupModel$1 {
27
- constructor(context, group, index = -1) {
28
- super(context, group, index);
29
- this.context = context;
30
- this.isHidden = false;
31
- }
32
- get hidden() {
33
- return this.isHidden;
34
- }
35
- set hidden(value) {
36
- if (this.isHidden == value)
37
- return;
38
- this.isHidden = value || false;
39
- this.context?.filterGroups();
40
- }
41
- }
42
- class DynamicFormArrayModel extends DynamicFormArrayModel$1 {
43
- constructor(config, layout) {
44
- super(config, layout);
45
- this.config = config;
46
- this.filteredGroups = new BehaviorSubject([]);
47
- this.sortable = config.sortable || false;
48
- this.useTabs = config.useTabs || false;
49
- this.saveTab = ObjectUtils.isFunction(config.saveTab) ? config.saveTab : ((index, model, arrayModel) => {
50
- arrayModel.tabIndex = index;
51
- });
52
- this.restoreTab = ObjectUtils.isFunction(config.restoreTab) ? config.restoreTab : ((model) => {
53
- return model.tabIndex;
54
- });
55
- this.getTabLabel = ObjectUtils.isFunction(config.getTabLabel) ? config.getTabLabel : ((index) => {
56
- return `${index + 1}`;
57
- });
58
- this.additional = config.additional || {};
59
- this.tabIndex = 0;
60
- this._sortBy = null;
61
- this._sortDescending = false;
62
- this._formArray = null;
63
- }
64
- get addItem() {
65
- return this.config.addItem !== false;
66
- }
67
- get insertItem() {
68
- return !this._sortBy && this.config.insertItem !== false;
69
- }
70
- get cloneItem() {
71
- return this.config.cloneItem !== false;
72
- }
73
- get moveItem() {
74
- return !this._sortBy && this.config.moveItem !== false;
75
- }
76
- get removeItem() {
77
- return this.config.removeItem !== false;
78
- }
79
- get clearItems() {
80
- return this.config.clearItems !== false;
81
- }
82
- get sortBy() {
83
- return this._sortBy;
84
- }
85
- set sortBy(value) {
86
- if (!this.sortable)
87
- return;
88
- value = value || null;
89
- if (this._sortBy !== value) {
90
- this._sortBy = value;
91
- this._sortDescending = false;
92
- }
93
- else if (this._sortDescending) {
94
- this._sortBy = null;
95
- this._sortDescending = false;
96
- }
97
- else {
98
- this._sortDescending = true;
99
- }
100
- this.filterGroups();
101
- }
102
- get sortDescending() {
103
- return this._sortDescending;
104
- }
105
- get sortOrder() {
106
- return this.sortDescending ? "desc" : "asc";
107
- }
108
- initialize(array) {
109
- this._formArray = array || this._formArray;
110
- this.filterGroups();
111
- }
112
- filterGroups() {
113
- this._filterTimer = this._filterTimer || TimerUtils.createTimeout();
114
- this._filterTimer.set(() => {
115
- const filtered = this.groups.filter(g => !g.hidden);
116
- if (this._sortBy && this._formArray) {
117
- const compare = this._sortDescending
118
- ? (a, b) => this.compareModels(b, a)
119
- : (a, b) => this.compareModels(a, b);
120
- filtered.sort(compare);
121
- }
122
- this._filteredGroups = filtered;
123
- this.filteredGroups.next(filtered);
124
- }, 100);
125
- }
126
- getFiltered(index) {
127
- return !this._filteredGroups ? null : this._filteredGroups[index];
128
- }
129
- insertGroup(index) {
130
- const group = new DynamicFormArrayGroupModel(this, this.groupFactory());
131
- this.groups.splice(index, 0, group);
132
- this.groups.forEach((g, index) => g.index = index);
133
- this.filterGroups();
134
- return group;
135
- }
136
- moveGroup(index, step) {
137
- super.moveGroup(index, step);
138
- this.filterGroups();
139
- }
140
- removeGroup(index) {
141
- super.removeGroup(index);
142
- this.filterGroups();
143
- }
144
- compareModels(a, b) {
145
- const aGroup = this._formArray.at(a.index).get(this._sortBy)?.value || null;
146
- const bGroup = this._formArray.at(b.index).get(this._sortBy)?.value || null;
147
- return ObjectUtils.compare(aGroup, bGroup);
148
- }
149
- }
150
-
151
- class DynamicFormGroupModel extends DynamicFormGroupModel$1 {
152
- constructor(config, layout) {
153
- super(config, layout);
154
- const controls = [...config.group];
155
- const groups = [];
156
- const sets = config.fieldSets || [];
157
- for (const fs of sets) {
158
- const fields = [];
159
- for (const f of fs.fields) {
160
- const ix = controls.findIndex(c => c.id === f);
161
- if (ix < 0)
162
- continue;
163
- fields.push(controls.splice(ix, 1)[0]);
164
- }
165
- if (fields.length === 0)
166
- continue;
167
- groups.push({ id: fs.id, legend: fs.legend, fields });
168
- }
169
- if (controls.length > 0) {
170
- groups.unshift({ id: "root-controls", legend: config.legend, fields: controls });
171
- }
172
- this.groups = groups;
173
- }
174
- }
175
-
176
- const ignoredKeys = ["disabled", "label", "value", "classes"];
177
- class DynamicFormOption extends DynamicFormOption$1 {
178
- constructor(config) {
179
- super(config);
180
- this.classes = config.classes || "";
181
- this.props = Object.keys(config).reduce((res, k) => {
182
- if (ignoredKeys.indexOf(k) >= 0)
183
- return res;
184
- res[k] = config[k];
185
- return res;
186
- }, {});
187
- }
188
- }
189
- class DynamicSelectModel extends DynamicSelectModel$1 {
190
- constructor(config, layout) {
191
- super(config, layout);
192
- this.groupBy = config.groupBy || null;
193
- this.inline = config.inline || false;
194
- this.getClasses = ObjectUtils.isFunction(config.getClasses) ? config.getClasses : (() => "");
195
- this.allowEmpty = config.allowEmpty || false;
196
- this.mOptions = this.mOptions || [];
197
- }
198
- updateOptions() {
199
- this.options$ = of(this.mOptions);
200
- }
201
- set options(options) {
202
- if (Array.isArray(options)) {
203
- this.mOptions = options.map(optionConfig => new DynamicFormOption(optionConfig));
204
- this.updateOptions();
205
- }
206
- else if (isObservable(options)) {
207
- this.options$ = options.pipe(map(optionsConfig => {
208
- this.mOptions = optionsConfig.map(optionConfig => new DynamicFormOption(optionConfig));
209
- return this.mOptions;
210
- }));
211
- }
212
- else {
213
- this.updateOptions();
214
- }
215
- }
216
- get options() {
217
- return this.mOptions;
218
- }
219
- insert(index, optionConfig) {
220
- const option = new DynamicFormOption(optionConfig);
221
- this.mOptions.splice(index, 0, option);
222
- this.updateOptions();
223
- return option;
224
- }
225
- remove(...indices) {
226
- indices.forEach(index => this.mOptions.splice(index, 1));
227
- this.updateOptions();
228
- }
229
- }
230
-
231
- function createFormConfig(id, config) {
232
- const res = (config || { id });
233
- res.id = id;
234
- res.label = ObjectUtils.isNullOrUndefined(config.label) ? id : config.label;
235
- res.disabled = config.disabled || false;
236
- res.hidden = config.hidden || false;
237
- return res;
238
- }
239
- function createFormCheckbox(id, config, layout) {
240
- const res = createFormConfig(id, config);
241
- res.indeterminate = config.indeterminate || false;
242
- return new DynamicCheckboxModel(res, layout);
243
- }
244
- function createFormDate(id, config, layout) {
245
- const res = createFormConfig(id, config);
246
- res.autoFocus = config.autoFocus || false;
247
- res.focusedDate = config.focusedDate || new Date();
248
- res.inline = config.inline || false;
249
- return new DynamicDatePickerModel(res, layout);
250
- }
251
- function createFormEditor(id, config, layout) {
252
- const res = createFormConfig(id, config);
253
- return new DynamicEditorModel(res, layout);
254
- }
255
- function createFormArray(id, config, layout) {
256
- const res = createFormConfig(id, config);
257
- return new DynamicFormArrayModel(res, layout);
258
- }
259
- function createFormGroup(id, config, layout) {
260
- const res = createFormConfig(id, config);
261
- res.name = config.name || "";
262
- return new DynamicFormGroupModel(res, layout);
263
- }
264
- function createFormInput(id, config, type = "text", layout) {
265
- const res = createFormConfig(id, config);
266
- res.inputType = config.inputType || type;
267
- res.placeholder = config.placeholder || (config.inputType == "mask" ? "_" : "");
268
- res.step = config.step || 1;
269
- res.mask = config.mask || null;
270
- return new DynamicInputModel(res, layout);
271
- }
272
- function createFormSelect(id, config, layout) {
273
- const res = createFormConfig(id, config);
274
- res.options = config.options || [];
275
- return new DynamicSelectModel(res, layout);
276
- }
277
- function createFormTextarea(id, config, layout) {
278
- const res = createFormConfig(id, config);
279
- res.cols = config.cols || 10;
280
- res.rows = config.rows || 3;
281
- res.wrap = config.wrap || "soft";
282
- return new DynamicTextAreaModel(res, layout);
283
- }
284
- function createFormFile(id, config, layout) {
285
- const res = createFormConfig(id, config);
286
- res.accept = config.accept || ["jpg", "jpeg", "png"];
287
- res.multiple = config.multiple || false;
288
- res.url = ObjectUtils.isString(config.url) ? config.url : "assets";
289
- return new DynamicFileUploadModel(res, layout);
290
- }
291
-
292
- function getFormComponent(...providers) {
293
- const factory = cachedFactory(providers);
294
- return (model, injector) => {
295
- const customizers = factory(injector);
296
- for (const customizer of customizers) {
297
- const component = customizer.acceptModel(model) ? customizer.getFormComponent(model) : null;
298
- if (component) {
299
- return component;
300
- }
301
- }
302
- return null;
303
- };
304
- }
305
- function customizeFormModel(...providers) {
306
- const factory = cachedFactory(providers);
307
- return async (property, schema, model, config, injector) => {
308
- const customizers = factory(injector);
309
- for (const customizer of customizers) {
310
- const accept = customizer.acceptModel(model);
311
- if (accept) {
312
- return customizer.customizeModel(model, config, property, schema);
313
- }
314
- }
315
- return model;
316
- };
317
- }
318
-
319
- function isStringWithVal(val) {
320
- return typeof val == "string" && val.length > 0;
321
- }
322
- function findRefs(property) {
323
- const refs = Array.isArray(property.allOf)
324
- ? property.allOf.map(o => o.$ref).filter(isStringWithVal)
325
- : [property.items?.$ref, property.$ref].filter(isStringWithVal);
326
- return refs.map(t => t.split("/").pop());
327
- }
328
- function replaceSpecialChars(str, to = "-") {
329
- return `${str}`.replace(/[&\/\\#, +()$~%.@'":*?<>{}]/g, to);
330
- }
331
- function mergeFormModels(formModels) {
332
- const res = [];
333
- for (const formModel of formModels) {
334
- for (const subModel of formModel) {
335
- const index = res.findIndex(t => t.id == subModel.id);
336
- if (index >= 0) {
337
- res[index] = subModel;
338
- continue;
339
- }
340
- res.push(subModel);
341
- }
342
- }
343
- return res;
344
- }
345
- function collectPathAble(start, getter) {
346
- if (!start || !getter(start))
347
- return [];
348
- const parts = [];
349
- let currentPath = start;
350
- while (currentPath) {
351
- const val = getter(currentPath);
352
- if (val) {
353
- parts.unshift(val);
354
- }
355
- currentPath = currentPath.parent;
356
- }
357
- return parts;
358
- }
359
- function getDynamicPath(start) {
360
- return collectPathAble(start, t => t.id).join(".");
361
- }
362
- const MIN_INPUT_NUM = -999999999;
363
- const MAX_INPUT_NUM = 999999999;
364
- const EDITOR_FORMATS = ["php", "json", "html", "css", "scss"];
365
-
366
- function validateJSON(control) {
367
- const value = control.value;
368
- if (!value)
369
- return null;
370
- try {
371
- JSON.parse(value);
372
- return null;
373
- }
374
- catch (e) {
375
- return { json: true };
376
- }
377
- }
378
- function validateRequiredTranslation(control) {
379
- const value = control.value;
380
- if (!value || value.length == 0)
381
- return { requiredTranslation: true };
382
- return value.findIndex(t => (t.lang == "de" || t.lang == "en") && !t.translation) < 0
383
- ? null
384
- : { requiredTranslation: true };
385
- }
386
- function validatePhone(control) {
387
- const value = control.value;
388
- if (!value)
389
- return Promise.resolve(null);
390
- const phoneRegexp = /^(?:\d){10,12}$/;
391
- return phoneRegexp.test(value) ? null : { phone: true };
392
- }
393
- function validateItemsMinLength(minLength) {
394
- return (control) => {
395
- const value = control.value;
396
- return (Array.isArray(value) && value.every(v => typeof v == "string" && v.length >= minLength))
397
- ? null : { itemsMinLength: minLength };
398
- };
399
- }
400
- function validateItemsMaxLength(maxLength) {
401
- return (control) => {
402
- const value = control.value;
403
- return (Array.isArray(value) && value.every(v => typeof v == "string" && v.length <= maxLength))
404
- ? null : { itemsMaxLength: maxLength };
405
- };
406
- }
407
- function validateItemsMinValue(min) {
408
- return (control) => {
409
- const value = control.value;
410
- return (Array.isArray(value) && value.every(v => typeof v == "number" && v >= min))
411
- ? null : { itemsMinValue: min };
412
- };
413
- }
414
- function validateItemsMaxValue(max) {
415
- return (control) => {
416
- const value = control.value;
417
- return (Array.isArray(value) && value.every(v => typeof v == "number" && v <= max))
418
- ? null : { itemsMaxValue: max };
419
- };
420
- }
421
-
422
- const indexLabels = ["$ix", "$pix"];
423
- class FormSubject extends Subject {
424
- constructor(notifyCallback) {
425
- super();
426
- this.notifyCallback = notifyCallback;
427
- }
428
- handleNotifiedValue(controlModel, control, val) {
429
- val.then(v => this.next(v));
430
- }
431
- notify(controlModel, control, root) {
432
- const indexes = {};
433
- let path = controlModel;
434
- let ix = 0;
435
- while (path) {
436
- if (!isNaN(path.index)) {
437
- const key = indexLabels[ix++] || `$pix${ix}`;
438
- indexes[key] = path.index;
439
- }
440
- path = path.parent;
441
- }
442
- let value = this.notifyCallback(controlModel, control, root, indexes);
443
- if (!(value instanceof Promise)) {
444
- value = Promise.resolve(value);
445
- }
446
- this.handleNotifiedValue(controlModel, control, value);
447
- }
448
- }
449
-
450
- class FormSelectSubject extends FormSubject {
451
- handleNotifiedValue(controlModel, control, val) {
452
- val.then(options => {
453
- if (options.length == 0) {
454
- this.next(options);
455
- return;
456
- }
457
- const currentVal = control.value;
458
- if (controlModel.multiple) {
459
- const correctVal = (currentVal || []).filter(t => options.findIndex(o => o.value == t) >= 0);
460
- if (correctVal.length !== currentVal?.length) {
461
- control.setValue(correctVal, { onlySelf: true, emitEvent: false });
462
- }
463
- }
464
- else {
465
- const option = options.find(t => t.value == currentVal);
466
- if (!option) {
467
- control.setValue(controlModel.allowEmpty ? null : options[0]?.value ?? null, { onlySelf: true, emitEvent: false });
468
- }
469
- }
470
- this.next(options);
471
- });
472
- }
473
- }
474
-
475
- function getFormValidationErrors(controls, parentPath = "") {
476
- const errors = [];
477
- Object.entries(controls).forEach(([name, control], ix) => {
478
- const path = !parentPath ? name : `${parentPath}.${name}`;
479
- if (control instanceof FormGroup) {
480
- getFormValidationErrors(control.controls, path).forEach(error => errors.push(error));
481
- return;
482
- }
483
- if (control instanceof FormArray) {
484
- control.controls.forEach((control, ix) => {
485
- getFormValidationErrors(control.controls, `${path}.${ix}`).forEach(error => errors.push(error));
486
- });
487
- return;
488
- }
489
- Object.entries(control.errors || {}).forEach(([errorKey, errorValue]) => {
490
- errors.push({ control, path, errorKey, errorValue });
491
- });
492
- });
493
- return errors;
494
- }
495
-
496
- class DynamicFormService extends DynamicFormService$1 {
497
- constructor(cs, vs, openApi, injector) {
498
- super(cs, vs);
499
- this.openApi = openApi;
500
- this.injector = injector;
501
- }
502
- get api() {
503
- return this.openApi.api;
504
- }
505
- get language() {
506
- return this.api.language;
507
- }
508
- patchGroup(value, formModel, formGroup) {
509
- value = ObjectUtils.copy(value);
510
- this.patchValueRecursive(value, formModel, formGroup);
511
- formGroup.patchValue(value);
512
- this.detectChanges();
513
- }
514
- patchForm(value, component) {
515
- value = ObjectUtils.copy(value);
516
- this.patchValueRecursive(value, component.model, component.group);
517
- component.group.patchValue(value);
518
- this.detectChanges(component);
519
- }
520
- serialize(formModel, formGroup) {
521
- return this.serializeRecursive(formModel, formGroup);
522
- }
523
- notifyChanges(formModel, formGroup) {
524
- this.notifyChangesRecursive(formModel, formGroup, formModel);
525
- }
526
- showErrors(form) {
527
- this.showErrorsForGroup(form.group);
528
- this.detectChanges(form);
529
- }
530
- getErrors(form) {
531
- this.showErrors(form);
532
- return new Promise(resolve => {
533
- setTimeout(() => {
534
- resolve(getFormValidationErrors(form.group.controls, ""));
535
- }, 500);
536
- });
537
- }
538
- patchValueRecursive(value, formModel, formGroup) {
539
- if (!value)
540
- return;
541
- formModel?.forEach(subModel => {
542
- const key = subModel.id;
543
- const subValue = value[key];
544
- const subControl = this.findControlByModel(subModel, formGroup);
545
- if (subModel instanceof DynamicSelectModel && ObjectUtils.isObject(subValue)) {
546
- value[key] = subValue.id || subValue._id || subValue;
547
- return;
548
- }
549
- if (subModel instanceof DynamicDatePickerModel) {
550
- value[key] = this.convertToDate(subValue);
551
- return;
552
- }
553
- if (subModel instanceof DynamicFormArrayModel) {
554
- const length = Array.isArray(subValue) ? subValue.length : 0;
555
- const subArray = subControl;
556
- while (subModel.size > length) {
557
- this.removeFormArrayGroup(0, subArray, subModel);
558
- }
559
- while (subModel.size < length) {
560
- this.insertFormArrayGroup(subModel.size, subArray, subModel);
561
- }
562
- for (let i = 0; i < length; i++) {
563
- const itemModel = subModel.get(i);
564
- this.patchValueRecursive(subValue[i], itemModel.group, subArray.at(i));
565
- }
566
- return;
567
- }
568
- if (subModel instanceof DynamicFormGroupModel) {
569
- this.patchValueRecursive(subValue, subModel.group, subControl);
570
- }
571
- });
572
- }
573
- async serializeRecursive(formModel, formGroup) {
574
- const result = {};
575
- if (!formModel || !formGroup || !formGroup.value)
576
- return result;
577
- for (const i in formModel) {
578
- const subModel = formModel[i];
579
- const subControl = this.findControlByModel(subModel, formGroup);
580
- const serializer = subModel.additional?.serializer;
581
- if (ObjectUtils.isFunction(serializer)) {
582
- result[subModel.id] = await serializer(subModel, subControl);
583
- continue;
584
- }
585
- if (subModel.hidden && !subModel.additional?.serialize)
586
- continue;
587
- if (subModel instanceof DynamicFormArrayModel) {
588
- const length = Array.isArray(subControl.value) ? subControl.value.length : 0;
589
- const subArray = subControl;
590
- const resArray = [];
591
- for (let i = 0; i < length; i++) {
592
- const itemModel = subModel.get(i);
593
- resArray.push(await this.serializeRecursive(itemModel.group, subArray.at(i)));
594
- }
595
- result[subModel.id] = resArray;
596
- continue;
597
- }
598
- if (subModel instanceof DynamicInputModel && !ObjectUtils.isNullOrUndefined(subControl.value)) {
599
- result[subModel.id] = subModel.inputType == "number"
600
- ? parseFloat((`${subControl.value}` || "0").replace(/,/gi, ".")) ?? null
601
- : subControl.value;
602
- continue;
603
- }
604
- if (subModel instanceof DynamicFormGroupModel) {
605
- result[subModel.id] = await this.serializeRecursive(subModel.group, subControl);
606
- continue;
607
- }
608
- result[subModel.id] = subControl.value;
609
- }
610
- return result;
611
- }
612
- notifyChangesRecursive(formModel, formGroup, root) {
613
- if (!formModel || !formGroup)
614
- return;
615
- for (const i in formModel) {
616
- const subModel = formModel[i];
617
- const subControl = this.findControlByModel(subModel, formGroup);
618
- if (subModel instanceof DynamicFormArrayModel) {
619
- const length = Array.isArray(subControl.value) ? subControl.value.length : 0;
620
- const subArray = subControl;
621
- for (let i = 0; i < length; i++) {
622
- const itemModel = subModel.get(i);
623
- this.notifyChangesRecursive(itemModel.group, subArray.at(i), root);
624
- }
625
- continue;
626
- }
627
- if (subModel instanceof DynamicFormGroupModel) {
628
- this.notifyChangesRecursive(subModel.group, subControl, root);
629
- continue;
630
- }
631
- this.updateSelectOptions(subModel, subControl, root);
632
- }
633
- }
634
- updateSelectOptions(formControlModel, formControl, root) {
635
- if (formControlModel instanceof DynamicSelectModel) {
636
- let options = formControlModel.options$;
637
- if (options instanceof FormSubject) {
638
- options.notify(formControlModel, formControl, root);
639
- return;
640
- }
641
- while (options instanceof Subject && options.source) {
642
- options = options.source;
643
- if (options instanceof FormSubject) {
644
- options.notify(formControlModel, formControl, root);
645
- }
646
- }
647
- }
648
- }
649
- showErrorsForGroup(formGroup) {
650
- if (!formGroup)
651
- return;
652
- formGroup.markAsTouched({ onlySelf: true });
653
- const controls = Object.keys(formGroup.controls).map(id => formGroup.controls[id]);
654
- this.showErrorsForControls(controls);
655
- }
656
- showErrorsForControls(controls) {
657
- controls.forEach(control => {
658
- if (control instanceof FormGroup) {
659
- this.showErrorsForGroup(control);
660
- return;
661
- }
662
- control.markAsTouched({ onlySelf: true });
663
- if (control instanceof FormArray) {
664
- this.showErrorsForControls(control.controls);
665
- }
666
- });
667
- }
668
- convertToDate(value) {
669
- if (ObjectUtils.isNullOrUndefined(value))
670
- return null;
671
- const date = ObjectUtils.isDate(value)
672
- ? value
673
- : new Date(value);
674
- return isNaN(date) ? new Date() : date;
675
- }
676
- async getFormModelForSchema(name, customizeModel) {
677
- return (await this.getFormGroupModelForSchema(name, customizeModel)).group;
678
- }
679
- async getFormGroupModelForSchema(name, customizeModel) {
680
- this.api.cache = {};
681
- this.schemas = await this.openApi.getSchemas();
682
- const fieldSets = [];
683
- const customizeModels = async (property, schema, modelType, config) => {
684
- const model = new modelType(config);
685
- if (model instanceof DynamicFormValueControlModel) {
686
- model.value = (model instanceof DynamicDatePickerModel)
687
- ? this.convertToDate(property.default) : property.default;
688
- }
689
- if (!ObjectUtils.isFunction(customizeModel))
690
- return [model];
691
- let res = customizeModel(property, schema, model, config, this.injector);
692
- if (!res)
693
- return [model];
694
- if (res instanceof Promise) {
695
- res = await res;
696
- }
697
- return Array.isArray(res) ? res : [res];
698
- };
699
- const schema = this.schemas[name];
700
- const controls = await this.getFormModelForSchemaDef(schema, fieldSets, customizeModels);
701
- const idFields = [
702
- createFormInput("id", { hidden: true }),
703
- createFormInput("_id", { hidden: true })
704
- ].filter(t => !controls.some(c => c.id == t.id));
705
- const config = {
706
- id: "root",
707
- group: [
708
- // -- Hidden id fields --
709
- ...idFields,
710
- // -- Main form controls --
711
- ...controls
712
- ],
713
- fieldSets
714
- };
715
- const root = await customizeModels({
716
- id: "root",
717
- type: "object",
718
- properties: schema.properties
719
- }, schema, DynamicFormGroupModel, config);
720
- // Check if the customized root wrapper returned an array
721
- if (Array.isArray(root)) {
722
- controls.length = 0;
723
- for (const model of root) {
724
- if (model instanceof DynamicFormGroupModel && model.id === "root") {
725
- return model;
726
- }
727
- else {
728
- controls.push(model);
729
- }
730
- }
731
- }
732
- return new DynamicFormGroupModel({
733
- ...config,
734
- group: controls
735
- });
736
- }
737
- async getFormModelForSchemaDef(schema, fieldSets, customizeModels) {
738
- if (!schema)
739
- return [];
740
- const keys = Object.keys(schema.properties || {});
741
- const controls = [];
742
- for (const p of keys) {
743
- const property = schema.properties[p];
744
- const fsName = property.hidden ? null : String(property.fieldSet || "");
745
- if (fsName) {
746
- const fs = fieldSets.find(t => t.id === fsName);
747
- if (fs) {
748
- fs.fields.push(p);
749
- }
750
- else {
751
- fieldSets.push({ id: fsName, legend: `legend.${fsName}`, fields: [p] });
752
- }
753
- }
754
- const models = await this.getFormControlModels(property, schema, customizeModels);
755
- controls.push(...models);
756
- }
757
- return controls.filter(t => null !== t);
758
- }
759
- checkIsEditorProperty(property) {
760
- if (!property.format)
761
- return false;
762
- return EDITOR_FORMATS.indexOf(property.format) >= 0 || property.format.endsWith("script");
763
- }
764
- async getFormControlModels(property, schema, customizeModels) {
765
- const $enum = property.items?.enum || property.enum;
766
- if (Array.isArray($enum) || isStringWithVal(property.optionsPath) || isStringWithVal(property.endpoint)) {
767
- return customizeModels(property, schema, DynamicSelectModel, this.getFormSelectConfig(property, schema));
768
- }
769
- switch (property.type) {
770
- case "string":
771
- case "number":
772
- case "integer":
773
- case "textarea":
774
- if (this.checkIsEditorProperty(property)) {
775
- return customizeModels(property, schema, DynamicEditorModel, this.getFormEditorConfig(property, schema));
776
- }
777
- if (property.format == "textarea") {
778
- return customizeModels(property, schema, DynamicTextAreaModel, this.getFormTextareaConfig(property, schema));
779
- }
780
- if (property.format == "date") {
781
- return customizeModels(property, schema, DynamicDatePickerModel, this.getFormDatepickerConfig(property, schema));
782
- }
783
- return customizeModels(property, schema, DynamicInputModel, this.getFormInputConfig(property, schema));
784
- case "object":
785
- return customizeModels(property, schema, DynamicEditorModel, this.getFormEditorConfig(property, schema));
786
- case "boolean":
787
- return customizeModels(property, schema, DynamicCheckboxModel, this.getFormCheckboxConfig(property, schema));
788
- case "array":
789
- if (findRefs(property).length > 0) {
790
- return customizeModels(property, schema, DynamicFormArrayModel, await this.getFormArrayConfig(property, schema, customizeModels));
791
- }
792
- else {
793
- return customizeModels(property, schema, DynamicInputModel, this.getFormInputConfig(property, schema));
794
- }
795
- case "file":
796
- return customizeModels(property, schema, DynamicFileUploadModel, this.getFormUploadConfig(property, schema));
797
- }
798
- if (findRefs(property).length > 0) {
799
- return customizeModels(property, schema, DynamicFormGroupModel, await this.getFormGroupConfig(property, schema, customizeModels));
800
- }
801
- return [];
802
- }
803
- findModelByPath(parent, path) {
804
- if (path.length == 0)
805
- return parent;
806
- const next = path.shift();
807
- if (Array.isArray(parent)) {
808
- return this.findModelByPath(parent.find(t => t.id == next), path);
809
- }
810
- if (parent instanceof DynamicFormGroupModel || parent instanceof DynamicFormArrayGroupModel) {
811
- return this.findModelByPath(parent.group.find(t => t.id == next), path);
812
- }
813
- if (parent instanceof DynamicFormArrayModel) {
814
- return this.findModelByPath(parent.groups.find(t => t.index == next), path);
815
- }
816
- return parent;
817
- }
818
- getFormControlConfig(property, schema) {
819
- const validators = this.getValidators(property, schema);
820
- const errorMessages = Object.keys(validators).reduce((res, key) => {
821
- res[key] = `error.${key}`;
822
- return res;
823
- }, {});
824
- return {
825
- id: property.id,
826
- label: ObjectUtils.isString(property.label) ? property.label : property.id,
827
- hidden: property.hidden,
828
- disabled: property.disabled,
829
- validators,
830
- errorMessages,
831
- additional: Object.assign({}, property)
832
- };
833
- }
834
- async getFormArrayConfig(property, schema, customizeModels) {
835
- const fieldSets = [];
836
- const subSchemas = findRefs(property).map(ref => this.schemas[ref]);
837
- const subModels = await Promise.all(subSchemas.map(s => this.getFormModelForSchemaDef(s, fieldSets, customizeModels)));
838
- return Object.assign(this.getFormControlConfig(property, schema), {
839
- groupFactory: () => mergeFormModels(ObjectUtils.copy(subModels)),
840
- initialCount: property.initialCount || 0,
841
- sortable: property.sortable || false,
842
- useTabs: property.useTabs || false,
843
- addItem: property.addItem !== false,
844
- insertItem: property.insertItem !== false,
845
- cloneItem: property.cloneItem !== false,
846
- moveItem: property.moveItem !== false,
847
- removeItem: property.removeItem !== false,
848
- clearItems: property.clearItems !== false
849
- });
850
- }
851
- async getFormGroupConfig(property, schema, customizeModels) {
852
- const fieldSets = [];
853
- const subSchemas = findRefs(property).map(ref => this.schemas[ref]);
854
- const subModels = await Promise.all(subSchemas.map(s => this.getFormModelForSchemaDef(s, fieldSets, customizeModels)));
855
- return Object.assign(this.getFormControlConfig(property, schema), {
856
- fieldSets,
857
- group: mergeFormModels(subModels)
858
- });
859
- }
860
- getFormInputConfig(property, schema) {
861
- let inputType = StringUtils.has(property.id, "password", "Password") ? "password" : (property.format || property.items?.type || property.type);
862
- switch (inputType) {
863
- case "string":
864
- inputType = "text";
865
- break;
866
- case "boolean":
867
- inputType = "checkbox";
868
- break;
869
- case "textarea":
870
- inputType = "textarea";
871
- break;
872
- case "integer":
873
- inputType = "number";
874
- break;
875
- }
876
- const sub = property.type == "array" ? property.items || property : property;
877
- return Object.assign(this.getFormControlConfig(property, schema), {
878
- inputType,
879
- autoComplete: property.autoComplete || "off",
880
- multiple: property.type == "array",
881
- accept: ObjectUtils.isString(property.accept) ? property.accept : null,
882
- mask: ObjectUtils.isString(property.mask) ? property.mask : null,
883
- pattern: ObjectUtils.isString(property.pattern) ? property.pattern : null,
884
- step: isNaN(sub.step) ? (isNaN(property.step) ? 1 : property.step) : sub.step,
885
- min: isNaN(sub.minimum) ? MIN_INPUT_NUM : sub.minimum,
886
- max: isNaN(sub.maximum) ? MAX_INPUT_NUM : sub.maximum,
887
- minLength: isNaN(sub.minLength) ? 0 : sub.minLength,
888
- maxLength: isNaN(sub.maxLength) ? MAX_INPUT_NUM : sub.maxLength,
889
- placeholder: property.placeholder || ""
890
- });
891
- }
892
- getFormEditorConfig(property, schema) {
893
- const sub = property.type == "array" ? property.items || property : property;
894
- return Object.assign(this.getFormControlConfig(property, schema), {
895
- inputType: property.format || "json",
896
- convertObject: property.type !== "string",
897
- autoComplete: property.autoComplete || "off",
898
- multiple: property.type == "array",
899
- accept: ObjectUtils.isString(property.accept) ? property.accept : null,
900
- mask: ObjectUtils.isString(property.mask) ? property.mask : null,
901
- pattern: ObjectUtils.isString(property.pattern) ? property.pattern : null,
902
- step: isNaN(sub.step) ? (isNaN(property.step) ? 1 : property.step) : sub.step,
903
- minLength: isNaN(sub.minLength) ? 0 : sub.minLength,
904
- maxLength: isNaN(sub.maxLength) ? MAX_INPUT_NUM : sub.maxLength,
905
- placeholder: property.placeholder || ""
906
- });
907
- }
908
- getFormTextareaConfig(property, schema) {
909
- return Object.assign(this.getFormControlConfig(property, schema), {
910
- cols: property.cols || null,
911
- rows: property.rows || 10,
912
- wrap: property.wrap || false,
913
- autoComplete: property.autoComplete || "off",
914
- multiple: property.type == "array",
915
- minLength: isNaN(property.minLength) ? 0 : property.minLength,
916
- maxLength: isNaN(property.maxLength) ? MAX_INPUT_NUM : property.maxLength,
917
- placeholder: property.placeholder || ""
918
- });
919
- }
920
- getFormDatepickerConfig(property, schema) {
921
- return Object.assign(this.getFormControlConfig(property, schema), {
922
- format: property.dateFormat || "dd.MM.yyyy",
923
- min: this.convertToDate(property.min),
924
- max: this.convertToDate(property.max),
925
- });
926
- }
927
- getFormSelectOptions(property, schema) {
928
- const $enum = property.items?.enum || property.enum;
929
- if (Array.isArray($enum)) {
930
- return new FormSelectSubject((selectModel, formControl) => {
931
- const options = $enum.map(value => {
932
- const label = property.translatable ? `${property.id}.${value}` : `${value}`;
933
- return { value, label };
934
- });
935
- return this.fixSelectOptions(selectModel, formControl, options);
936
- });
937
- }
938
- if (isStringWithVal(property.optionsPath)) {
939
- return new FormSelectSubject(async (selectModel, control, root, indexes) => {
940
- let path = property.optionsPath;
941
- let target = control;
942
- let model = selectModel;
943
- if (path.startsWith("$root")) {
944
- path = path.substring(5);
945
- while (target.parent) {
946
- target = target.parent;
947
- }
948
- model = root;
949
- }
950
- while (path.startsWith(".")) {
951
- path = path.substring(1);
952
- if (target.parent) {
953
- target = target.parent;
954
- }
955
- model = model.parent || root;
956
- }
957
- Object.keys(indexes).forEach(key => {
958
- path = path.replace(key, indexes[key]);
959
- });
960
- model = this.findModelByPath(model, path.split("."));
961
- const modelOptions = model instanceof DynamicSelectModel
962
- ? await firstValueFrom(model.options$) :
963
- [];
964
- const value = ObjectUtils.getValue(target.value, path);
965
- const options = (!ObjectUtils.isArray(value) ? [] : value).map(value => {
966
- const modelOption = modelOptions.find(t => t.value == value);
967
- return { value, label: modelOption?.label || value };
968
- });
969
- return this.fixSelectOptions(selectModel, control, options);
970
- });
971
- }
972
- return new FormSelectSubject(async (selectModel, control) => {
973
- const entries = Object.entries(control.root?.value || {});
974
- const endpoint = entries.reduce((res, [key, value]) => {
975
- return res.replace(new RegExp(`$${key}`, "gi"), `${value}`);
976
- }, `${property.endpoint}`);
977
- this.api.cache[endpoint] = this.api.cache[endpoint] || this.api.list(endpoint, this.api.makeListParams(1, -1)).then(result => {
978
- const items = ObjectUtils.isArray(result)
979
- ? result
980
- : (ObjectUtils.isArray(result.items) ? result.items : []);
981
- return items.map(i => {
982
- const item = ObjectUtils.isObject(i) ? i : { id: i };
983
- return {
984
- ...item,
985
- value: item.id || item._id,
986
- label: item[property.labelField] || item.label || item.id || item._id
987
- };
988
- });
989
- });
990
- const options = (await this.api.cache[endpoint]).map(t => Object.assign({}, t));
991
- return this.fixSelectOptions(selectModel, control, options);
992
- });
993
- }
994
- getFormSelectConfig(property, schema) {
995
- return Object.assign(this.getFormControlConfig(property, schema), {
996
- options: this.getFormSelectOptions(property, schema),
997
- multiple: property.type == "array",
998
- groupBy: property.groupBy,
999
- inline: property.inline,
1000
- allowEmpty: property.allowEmpty,
1001
- });
1002
- }
1003
- getFormUploadConfig(property, schema) {
1004
- const url = this.api.url(property.url || "assets");
1005
- const { accept, autoUpload, maxSize, minSize, removeUrl, showFileList } = property;
1006
- return Object.assign(this.getFormControlConfig(property, schema), {
1007
- url,
1008
- accept,
1009
- autoUpload,
1010
- maxSize,
1011
- minSize,
1012
- removeUrl,
1013
- showFileList
1014
- });
1015
- }
1016
- getFormCheckboxConfig(property, schema) {
1017
- return Object.assign(this.getFormControlConfig(property, schema), {
1018
- indeterminate: property.indeterminate || false
1019
- });
1020
- }
1021
- cloneFormArrayGroup(index, formArray, formArrayModel) {
1022
- this.insertFormArrayGroup(index, formArray, formArrayModel);
1023
- this.patchGroup(formArray.at(index + 1).value, formArrayModel.groups[index].group, formArray.at(index));
1024
- formArrayModel.filterGroups();
1025
- }
1026
- async fixSelectOptions(model, control, options) {
1027
- if (!options)
1028
- return [];
1029
- for (const option of options) {
1030
- option.classes = [option.classes, model.getClasses(option, model, control, this.injector)].filter(isStringWithVal).join(" ");
1031
- option.label = await this.language.getTranslation(option.label);
1032
- }
1033
- return options;
1034
- }
1035
- getValidators(property, schema) {
1036
- const validators = {};
1037
- if (ObjectUtils.isArray(schema.required) && schema.required.indexOf(property.id) >= 0) {
1038
- validators.required = null;
1039
- }
1040
- this.addPropertyValidators(validators, property);
1041
- this.addItemsValidators(validators, property.items);
1042
- return validators;
1043
- }
1044
- addPropertyValidators(validators, property) {
1045
- if (!property)
1046
- return;
1047
- if (!isNaN(property.minLength)) {
1048
- validators.minLength = property.minLength;
1049
- }
1050
- if (!isNaN(property.maxLength)) {
1051
- validators.maxLength = property.maxLength;
1052
- }
1053
- if (!isNaN(property.minimum)) {
1054
- validators.min = property.minimum;
1055
- }
1056
- if (!isNaN(property.maximum)) {
1057
- validators.max = property.maximum;
1058
- }
1059
- switch (property.format) {
1060
- case "email":
1061
- validators.email = null;
1062
- break;
1063
- }
1064
- }
1065
- addItemsValidators(validators, items) {
1066
- if (!items)
1067
- return;
1068
- if (!isNaN(items.minLength)) {
1069
- validators.itemsMinLength = items.minLength;
1070
- }
1071
- if (!isNaN(items.maxLength)) {
1072
- validators.itemsMaxLength = items.maxLength;
1073
- }
1074
- if (!isNaN(items.minimum)) {
1075
- validators.itemsMinValue = items.minimum;
1076
- }
1077
- if (!isNaN(items.maximum)) {
1078
- validators.itemsMaxValue = items.maximum;
1079
- }
1080
- }
1081
- }
1082
- DynamicFormService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicFormService, deps: [{ token: i1.DynamicFormComponentService }, { token: i1.DynamicFormValidationService }, { token: OpenApiService }, { token: Injector }], target: i0.ɵɵFactoryTarget.Injectable });
1083
- DynamicFormService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicFormService });
1084
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicFormService, decorators: [{
1085
- type: Injectable
1086
- }], ctorParameters: function () { return [{ type: i1.DynamicFormComponentService }, { type: i1.DynamicFormValidationService }, { type: i2.OpenApiService, decorators: [{
1087
- type: Inject,
1088
- args: [OpenApiService]
1089
- }] }, { type: i0.Injector, decorators: [{
1090
- type: Inject,
1091
- args: [Injector]
1092
- }] }]; } });
1093
-
1094
- class AsyncSubmitDirective {
1095
- constructor(toaster, cdr, elem, renderer) {
1096
- this.toaster = toaster;
1097
- this.cdr = cdr;
1098
- this.elem = elem;
1099
- this.renderer = renderer;
1100
- this.onSuccess = new EventEmitter();
1101
- this.onError = new EventEmitter();
1102
- if (elem.nativeElement.tagName !== "BUTTON")
1103
- return;
1104
- renderer.setAttribute(elem.nativeElement, "type", "button");
1105
- }
1106
- get isDisabled() {
1107
- return this.disabled;
1108
- }
1109
- set isDisabled(value) {
1110
- this.disabled = value;
1111
- if (value) {
1112
- this.renderer.setAttribute(this.elem.nativeElement, "disabled", "disabled");
1113
- return;
1114
- }
1115
- this.renderer.removeAttribute(this.elem.nativeElement, "disabled");
1116
- }
1117
- get isLoading() {
1118
- return this.loading;
1119
- }
1120
- ngOnInit() {
1121
- if (!this.form)
1122
- return;
1123
- this.isDisabled = this.form.status !== "VALID";
1124
- this.cdr.detectChanges();
1125
- this.onStatusChange = this.form.onStatusChange.subscribe(() => {
1126
- this.isDisabled = this.form.status !== "VALID";
1127
- this.cdr.detectChanges();
1128
- if (!this.callback || this.form.status == "PENDING")
1129
- return;
1130
- if (!this.disabled) {
1131
- this.callback();
1132
- }
1133
- this.callback = null;
1134
- });
1135
- this.onSubmit = this.form.onSubmit.pipe(debounceTime(200)).subscribe(() => this.callMethod());
1136
- }
1137
- ngOnDestroy() {
1138
- if (this.onStatusChange)
1139
- this.onStatusChange.unsubscribe();
1140
- if (this.onSubmit)
1141
- this.onSubmit.unsubscribe();
1142
- }
1143
- click() {
1144
- this.callback = () => this.callMethod();
1145
- if (this.form.status === "INVALID") {
1146
- console.log(getFormValidationErrors(this.form.group.controls));
1147
- }
1148
- if (this.form.status !== "VALID" && this.form.status !== "INVALID")
1149
- return;
1150
- this.callback();
1151
- this.callback = null;
1152
- }
1153
- callMethod() {
1154
- if (this.loading)
1155
- return;
1156
- this.loading = true;
1157
- this.method(this.form, this.context).then(result => {
1158
- this.loading = false;
1159
- if (result) {
1160
- this.onSuccess.emit(result);
1161
- this.toaster.success(result.message, result.context);
1162
- }
1163
- }, reason => {
1164
- if (!reason || !reason.message)
1165
- throw new Error("Reason must implement IAsyncMessage interface");
1166
- this.loading = false;
1167
- this.onError.emit(reason);
1168
- this.toaster.error(reason.message, reason.context);
1169
- });
1170
- }
1171
- }
1172
- AsyncSubmitDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: AsyncSubmitDirective, deps: [{ token: TOASTER_SERVICE }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
1173
- AsyncSubmitDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.8", type: AsyncSubmitDirective, selector: "[async-submit]", inputs: { method: ["async-submit", "method"], form: "form", context: "context" }, outputs: { onSuccess: "onSuccess", onError: "onError" }, host: { listeners: { "click": "click()" }, properties: { "class.disabled": "this.isDisabled", "class.loading": "this.isLoading" } }, exportAs: ["async-submit"], ngImport: i0 });
1174
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: AsyncSubmitDirective, decorators: [{
1175
- type: Directive,
1176
- args: [{
1177
- selector: "[async-submit]",
1178
- exportAs: "async-submit"
1179
- }]
1180
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1181
- type: Inject,
1182
- args: [TOASTER_SERVICE]
1183
- }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { method: [{
1184
- type: Input,
1185
- args: ["async-submit"]
1186
- }], form: [{
1187
- type: Input
1188
- }], context: [{
1189
- type: Input
1190
- }], onSuccess: [{
1191
- type: Output
1192
- }], onError: [{
1193
- type: Output
1194
- }], isDisabled: [{
1195
- type: HostBinding,
1196
- args: ["class.disabled"]
1197
- }], isLoading: [{
1198
- type: HostBinding,
1199
- args: ["class.loading"]
1200
- }], click: [{
1201
- type: HostListener,
1202
- args: ["click"]
1203
- }] } });
1204
-
1205
- class DynamicBaseFormComponent extends DynamicFormComponent {
1206
- constructor(formService, events, changeDetectorRef, componentService) {
1207
- super(changeDetectorRef, componentService);
1208
- this.formService = formService;
1209
- this.events = events;
1210
- this.blur = new EventEmitter();
1211
- this.change = new EventEmitter();
1212
- this.focus = new EventEmitter();
1213
- this.onValueChange = new EventEmitter();
1214
- this.onStatusChange = new EventEmitter();
1215
- this.onSubmit = new EventEmitter();
1216
- this.onDetectChanges = new EventEmitter();
1217
- this.templates = new QueryList();
1218
- this.subscription = new Subscription();
1219
- this.groupSubscription = new Subscription();
1220
- this.labelPrefix = "label";
1221
- this.getComponentType = () => null;
1222
- }
1223
- get status() {
1224
- return !this.group ? null : this.group.status;
1225
- }
1226
- submit() {
1227
- this.onSubmit.emit(this);
1228
- }
1229
- ngOnChanges(changes) {
1230
- this.groupSubscription.unsubscribe();
1231
- if (this.group) {
1232
- this.groupSubscription = ObservableUtils.multiSubscription(this.group.statusChanges.subscribe(() => {
1233
- this.onStatusChange.emit(this);
1234
- }), this.group.valueChanges.pipe(debounceTime(500)).subscribe(() => {
1235
- this.formService.notifyChanges(this.model, this.group);
1236
- }), this.change.pipe(groupBy(ev => ev.model))
1237
- .pipe(mergeMap(t => t.pipe(debounceTime(500))))
1238
- .subscribe(ev => {
1239
- this.onValueChange.emit({ ...ev, form: this });
1240
- }));
1241
- }
1242
- if (changes.groupModel) {
1243
- this.model = this.groupModel?.group;
1244
- }
1245
- if (changes.model) {
1246
- this.groupModel = new DynamicFormGroupModel({ id: "root", group: this.model });
1247
- }
1248
- }
1249
- ngAfterViewInit() {
1250
- this.subscription = ObservableUtils.multiSubscription(ObservableUtils.subscribe({
1251
- subjects: [this.contentTemplates.changes, this.viewTemplates.changes],
1252
- cb: () => {
1253
- const templates = this.contentTemplates.toArray().concat(this.viewTemplates.toArray());
1254
- this.templates.reset(templates);
1255
- }
1256
- }), this.events.languageChanged.subscribe(() => {
1257
- this.formService.notifyChanges(this.model, this.group);
1258
- this.formService.detectChanges(this);
1259
- }));
1260
- }
1261
- ngOnDestroy() {
1262
- super.ngOnDestroy();
1263
- this.subscription.unsubscribe();
1264
- this.groupSubscription.unsubscribe();
1265
- }
1266
- detectChanges() {
1267
- super.detectChanges();
1268
- this.onDetectChanges.emit(this);
1269
- }
1270
- insertFormArrayGroup(index, formArray, formArrayModel) {
1271
- this.formService.insertFormArrayGroup(index, formArray, formArrayModel);
1272
- this.detectChanges();
1273
- }
1274
- cloneFormArrayGroup(index, formArray, formArrayModel) {
1275
- this.formService.cloneFormArrayGroup(index, formArray, formArrayModel);
1276
- this.detectChanges();
1277
- }
1278
- removeFormArrayGroup(index, formArray, formArrayModel) {
1279
- this.formService.removeFormArrayGroup(index, formArray, formArrayModel);
1280
- this.detectChanges();
1281
- }
1282
- moveFormArrayGroup(index, step, formArray, formArrayModel) {
1283
- this.formService.moveFormArrayGroup(index, step, formArray, formArrayModel);
1284
- this.detectChanges();
1285
- }
1286
- clearFormArray(formArray, formArrayModel) {
1287
- this.formService.clearFormArray(formArray, formArrayModel);
1288
- this.detectChanges();
1289
- }
1290
- getClass(model) {
1291
- const parts = collectPathAble(model, p => p.id);
1292
- if (parts.length == 0)
1293
- return "";
1294
- if (model instanceof DynamicFormGroupModel) {
1295
- return `form-group-${parts.join("-")}`;
1296
- }
1297
- return `form-control-${parts.join("-")}`;
1298
- }
1299
- validate(showErrors = true) {
1300
- if (!this.group)
1301
- return Promise.resolve();
1302
- return new Promise((resolve, reject) => {
1303
- this.group.statusChanges.pipe(first(status => status == "VALID" || status == "INVALID")).subscribe(status => {
1304
- if (showErrors) {
1305
- this.formService.showErrors(this);
1306
- }
1307
- if (status == "VALID") {
1308
- resolve(null);
1309
- return;
1310
- }
1311
- reject(null);
1312
- });
1313
- this.group.updateValueAndValidity();
1314
- });
1315
- }
1316
- async serialize(validate) {
1317
- if (!this.group)
1318
- return null;
1319
- if (validate) {
1320
- await this.validate();
1321
- }
1322
- return await this.formService.serialize(this.model, this.group);
1323
- }
1324
- }
1325
- DynamicBaseFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormComponent, deps: [{ token: DynamicFormService }, { token: EventsService }, { token: i0.ChangeDetectorRef }, { token: i1.DynamicFormComponentService }], target: i0.ɵɵFactoryTarget.Component });
1326
- DynamicBaseFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: DynamicBaseFormComponent, selector: "dynamic-base-form", inputs: { group: "group", groupModel: "groupModel", model: "model", layout: "layout", labelPrefix: "labelPrefix", getComponentType: "getComponentType" }, outputs: { blur: "blur", change: "change", focus: "focus", onValueChange: "onValueChange", onStatusChange: "onStatusChange", onSubmit: "onSubmit", onDetectChanges: "onDetectChanges" }, queries: [{ propertyName: "contentTemplates", predicate: DynamicTemplateDirective }], viewQueries: [{ propertyName: "viewTemplates", predicate: DynamicTemplateDirective, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "", isInline: true, changeDetection: i0.ChangeDetectionStrategy.Default });
1327
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormComponent, decorators: [{
1328
- type: Component,
1329
- args: [{
1330
- selector: "dynamic-base-form",
1331
- template: "",
1332
- changeDetection: ChangeDetectionStrategy.Default
1333
- }]
1334
- }], ctorParameters: function () { return [{ type: DynamicFormService, decorators: [{
1335
- type: Inject,
1336
- args: [DynamicFormService]
1337
- }] }, { type: i2.EventsService, decorators: [{
1338
- type: Inject,
1339
- args: [EventsService]
1340
- }] }, { type: i0.ChangeDetectorRef }, { type: i1.DynamicFormComponentService }]; }, propDecorators: { group: [{
1341
- type: Input
1342
- }], groupModel: [{
1343
- type: Input
1344
- }], model: [{
1345
- type: Input
1346
- }], layout: [{
1347
- type: Input
1348
- }], labelPrefix: [{
1349
- type: Input
1350
- }], getComponentType: [{
1351
- type: Input
1352
- }], blur: [{
1353
- type: Output
1354
- }], change: [{
1355
- type: Output
1356
- }], focus: [{
1357
- type: Output
1358
- }], contentTemplates: [{
1359
- type: ContentChildren,
1360
- args: [DynamicTemplateDirective]
1361
- }], viewTemplates: [{
1362
- type: ViewChildren,
1363
- args: [DynamicTemplateDirective]
1364
- }], onValueChange: [{
1365
- type: Output
1366
- }], onStatusChange: [{
1367
- type: Output
1368
- }], onSubmit: [{
1369
- type: Output
1370
- }], onDetectChanges: [{
1371
- type: Output
1372
- }] } });
1373
-
1374
- class DynamicBaseFormControlContainerComponent extends DynamicFormControlContainerComponent {
1375
- constructor(form, cdr, injector, cfr, layoutService, validationService, componentService, relationService) {
1376
- super(cdr, cfr, layoutService, validationService, componentService, relationService);
1377
- this.form = form;
1378
- this.cdr = cdr;
1379
- this.injector = injector;
1380
- this.context = null;
1381
- this.blur = new EventEmitter();
1382
- this.change = new EventEmitter();
1383
- this.focus = new EventEmitter();
1384
- }
1385
- get componentType() {
1386
- return this.form.getComponentType?.(this.model, this.injector)
1387
- ?? this.componentService.getCustomComponentType(this.model);
1388
- }
1389
- get startTemplate() {
1390
- return (this.model.type == DYNAMIC_FORM_CONTROL_TYPE_ARRAY)
1391
- ? this.layoutService.getAlignedTemplate(this.model, this.templates, "ARRAY_START")
1392
- : this.layoutService.getStartTemplate(this.model, this.templates);
1393
- }
1394
- get endTemplate() {
1395
- return (this.model.type == DYNAMIC_FORM_CONTROL_TYPE_ARRAY)
1396
- ? this.layoutService.getAlignedTemplate(this.model, this.templates, "ARRAY_END")
1397
- : this.layoutService.getEndTemplate(this.model, this.templates);
1398
- }
1399
- get formService() {
1400
- return this.form.formService;
1401
- }
1402
- ngOnInit() {
1403
- super.ngOnInit();
1404
- this.onDetectChanges = this.form.onDetectChanges.subscribe(() => {
1405
- this.changeDetectorRef.detectChanges();
1406
- });
1407
- }
1408
- ngOnDestroy() {
1409
- super.ngOnDestroy();
1410
- this.onDetectChanges.unsubscribe();
1411
- }
1412
- getLabel() {
1413
- const label = collectPathAble(this.model, p => p.label);
1414
- if (label.length == 0)
1415
- return "";
1416
- if (this.form?.labelPrefix) {
1417
- label.unshift(this.form.labelPrefix);
1418
- }
1419
- return label.join(".");
1420
- }
1421
- getLabelIcon() {
1422
- if (this.context instanceof DynamicFormArrayGroupModel) {
1423
- const arrayModel = this.context.context;
1424
- if (arrayModel && arrayModel.sortBy == this.model.id) {
1425
- return arrayModel.sortOrder;
1426
- }
1427
- }
1428
- return null;
1429
- }
1430
- clickLabel() {
1431
- if (this.context instanceof DynamicFormArrayGroupModel) {
1432
- const arrayModel = this.context.context;
1433
- if (arrayModel) {
1434
- arrayModel.sortBy = this.model.id;
1435
- }
1436
- }
1437
- }
1438
- createFormControlComponent() {
1439
- super.createFormControlComponent();
1440
- const component = this.componentRef?.instance;
1441
- if (!component || !ObjectUtils.isFunction(component.initialize))
1442
- return;
1443
- component.initialize(this.changeDetectorRef);
1444
- }
1445
- }
1446
- DynamicBaseFormControlContainerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormControlContainerComponent, deps: [{ token: DynamicBaseFormComponent }, { token: i0.ChangeDetectorRef }, { token: i0.Injector }, { token: i0.ComponentFactoryResolver }, { token: i1.DynamicFormLayoutService }, { token: i1.DynamicFormValidationService }, { token: i1.DynamicFormComponentService }, { token: i1.DynamicFormRelationService }], target: i0.ɵɵFactoryTarget.Component });
1447
- DynamicBaseFormControlContainerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: DynamicBaseFormControlContainerComponent, selector: "dynamic-base-form-control", inputs: { context: "context", group: "group", hostClass: "hostClass", inputTemplateList: ["templates", "inputTemplateList"], layout: "layout", model: "model" }, outputs: { blur: "blur", change: "change", focus: "focus" }, host: { properties: { "class": "this.klass" } }, providers: [
1448
- { provide: DynamicFormControlContainerComponent, useExisting: DynamicBaseFormControlContainerComponent }
1449
- ], queries: [{ propertyName: "contentTemplateList", predicate: DynamicTemplateDirective }], viewQueries: [{ propertyName: "componentViewContainerRef", first: true, predicate: ["componentViewContainer"], descendants: true, read: ViewContainerRef, static: true }], usesInheritance: true, ngImport: i0, template: "", isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1450
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormControlContainerComponent, decorators: [{
1451
- type: Component,
1452
- args: [{
1453
- selector: "dynamic-base-form-control",
1454
- template: "",
1455
- changeDetection: ChangeDetectionStrategy.OnPush,
1456
- providers: [
1457
- { provide: DynamicFormControlContainerComponent, useExisting: DynamicBaseFormControlContainerComponent }
1458
- ]
1459
- }]
1460
- }], ctorParameters: function () { return [{ type: DynamicBaseFormComponent }, { type: i0.ChangeDetectorRef }, { type: i0.Injector }, { type: i0.ComponentFactoryResolver }, { type: i1.DynamicFormLayoutService }, { type: i1.DynamicFormValidationService }, { type: i1.DynamicFormComponentService }, { type: i1.DynamicFormRelationService }]; }, propDecorators: { contentTemplateList: [{
1461
- type: ContentChildren,
1462
- args: [DynamicTemplateDirective]
1463
- }], klass: [{
1464
- type: HostBinding,
1465
- args: ["class"]
1466
- }], context: [{
1467
- type: Input
1468
- }], group: [{
1469
- type: Input
1470
- }], hostClass: [{
1471
- type: Input
1472
- }], inputTemplateList: [{
1473
- type: Input,
1474
- args: ["templates"]
1475
- }], layout: [{
1476
- type: Input
1477
- }], model: [{
1478
- type: Input
1479
- }], blur: [{
1480
- type: Output
1481
- }], change: [{
1482
- type: Output
1483
- }], focus: [{
1484
- type: Output
1485
- }], componentViewContainerRef: [{
1486
- type: ViewChild,
1487
- args: ["componentViewContainer", {
1488
- read: ViewContainerRef,
1489
- static: true
1490
- }]
1491
- }] } });
1492
-
1493
- class DynamicBaseFormArrayComponent extends DynamicFormArrayComponent {
1494
- constructor(layoutService, validationService, form, injector, cdr) {
1495
- super(layoutService, validationService);
1496
- this.form = form;
1497
- this.injector = injector;
1498
- this.cdr = cdr;
1499
- this.blur = new EventEmitter();
1500
- this.change = new EventEmitter();
1501
- this.customEvent = new EventEmitter();
1502
- this.focus = new EventEmitter();
1503
- }
1504
- get useTabs() {
1505
- return this.model?.useTabs;
1506
- }
1507
- initialize(cdr) {
1508
- this.subscription = this.model.filteredGroups.subscribe(filteredGroups => {
1509
- this.updateGroups(filteredGroups);
1510
- });
1511
- this.model.initialize(this.array);
1512
- }
1513
- ngOnDestroy() {
1514
- if (this.subscription)
1515
- this.subscription.unsubscribe();
1516
- }
1517
- saveTab(index) {
1518
- this.model.saveTab(index, this.model.getFiltered(index), this.model, this.injector);
1519
- }
1520
- restoreTab() {
1521
- return this.model.restoreTab(this.model, this.injector);
1522
- }
1523
- getTabLabel(index, model) {
1524
- return this.model.getTabLabel(index, model, this.model, this.array, this.injector);
1525
- }
1526
- getClass(context, place, model) {
1527
- return [
1528
- context == "element" ? this.getModelClass(model) : null,
1529
- context == "element" ? this.getAdditionalClass(model) : null,
1530
- super.getClass(context, place, model),
1531
- model instanceof DynamicFormValueControlModel ? model.additional?.classes : null
1532
- ].filter(cls => !!cls).join(" ");
1533
- }
1534
- getModelClass(model) {
1535
- const parts = collectPathAble(model, p => p.id);
1536
- if (parts.length == 0)
1537
- return "";
1538
- if (model instanceof DynamicFormGroupModel$1) {
1539
- return `form-group-${parts.join("-")}`;
1540
- }
1541
- return `form-control-${parts.join("-")}`;
1542
- }
1543
- getAdditionalClass(model) {
1544
- if (model instanceof DynamicFormArrayModel) {
1545
- return model.additional?.classes;
1546
- }
1547
- if (model instanceof DynamicFormValueControlModel) {
1548
- return model.additional?.classes;
1549
- }
1550
- return null;
1551
- }
1552
- updateGroups(filteredGroups) {
1553
- this.cdr.detectChanges();
1554
- this.components.forEach(t => t.cdr.detectChanges());
1555
- }
1556
- }
1557
- DynamicBaseFormArrayComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormArrayComponent, deps: [{ token: i1.DynamicFormLayoutService }, { token: i1.DynamicFormValidationService }, { token: DynamicBaseFormComponent }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1558
- DynamicBaseFormArrayComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: DynamicBaseFormArrayComponent, selector: "dynamic-base-form-array", inputs: { formLayout: "formLayout", group: "group", layout: "layout", model: "model", templates: "templates" }, outputs: { blur: "blur", change: "change", customEvent: "customEvent", focus: "focus" }, viewQueries: [{ propertyName: "components", predicate: i0.forwardRef(function () { return DynamicBaseFormControlContainerComponent; }), descendants: true }], usesInheritance: true, ngImport: i0, template: "", isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1559
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormArrayComponent, decorators: [{
1560
- type: Component,
1561
- args: [{
1562
- selector: "dynamic-base-form-array",
1563
- template: "",
1564
- changeDetection: ChangeDetectionStrategy.OnPush
1565
- }]
1566
- }], ctorParameters: function () { return [{ type: i1.DynamicFormLayoutService }, { type: i1.DynamicFormValidationService }, { type: DynamicBaseFormComponent }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { formLayout: [{
1567
- type: Input
1568
- }], group: [{
1569
- type: Input
1570
- }], layout: [{
1571
- type: Input
1572
- }], model: [{
1573
- type: Input
1574
- }], templates: [{
1575
- type: Input
1576
- }], blur: [{
1577
- type: Output
1578
- }], change: [{
1579
- type: Output
1580
- }], customEvent: [{
1581
- type: Output
1582
- }], focus: [{
1583
- type: Output
1584
- }], components: [{
1585
- type: ViewChildren,
1586
- args: [forwardRef(() => DynamicBaseFormControlContainerComponent)]
1587
- }] } });
1588
-
1589
- class DynamicBaseFormControlComponent extends DynamicFormControlComponent {
1590
- constructor(layoutService, validationService, form, injector, cdr) {
1591
- super(layoutService, validationService);
1592
- this.form = form;
1593
- this.injector = injector;
1594
- this.cdr = cdr;
1595
- this.blur = new EventEmitter();
1596
- this.change = new EventEmitter();
1597
- this.focus = new EventEmitter();
1598
- }
1599
- ngAfterViewInit() {
1600
- this.subscription = this.control.valueChanges.pipe(debounceTime(500)).subscribe(value => {
1601
- this.onValueChanged(value);
1602
- });
1603
- }
1604
- ngOnDestroy() {
1605
- if (!this.subscription)
1606
- return;
1607
- this.subscription.unsubscribe();
1608
- }
1609
- submit() {
1610
- this.form.submit();
1611
- }
1612
- onValueChanged(value) {
1613
- }
1614
- }
1615
- DynamicBaseFormControlComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormControlComponent, deps: [{ token: i1.DynamicFormLayoutService }, { token: i1.DynamicFormValidationService }, { token: DynamicBaseFormComponent }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1616
- DynamicBaseFormControlComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: DynamicBaseFormControlComponent, selector: "dynamic-base-form-control", inputs: { formLayout: "formLayout", group: "group", layout: "layout", model: "model" }, outputs: { blur: "blur", change: "change", focus: "focus" }, usesInheritance: true, ngImport: i0, template: "", isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1617
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormControlComponent, decorators: [{
1618
- type: Component,
1619
- args: [{
1620
- selector: "dynamic-base-form-control",
1621
- template: "",
1622
- changeDetection: ChangeDetectionStrategy.OnPush
1623
- }]
1624
- }], ctorParameters: function () { return [{ type: i1.DynamicFormLayoutService }, { type: i1.DynamicFormValidationService }, { type: DynamicBaseFormComponent }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { formLayout: [{
1625
- type: Input
1626
- }], group: [{
1627
- type: Input
1628
- }], layout: [{
1629
- type: Input
1630
- }], model: [{
1631
- type: Input
1632
- }], blur: [{
1633
- type: Output
1634
- }], change: [{
1635
- type: Output
1636
- }], focus: [{
1637
- type: Output
1638
- }] } });
1639
-
1640
- class DynamicBaseFormGroupComponent extends DynamicFormGroupComponent {
1641
- constructor(layoutService, validationService) {
1642
- super(layoutService, validationService);
1643
- this.layoutService = layoutService;
1644
- this.validationService = validationService;
1645
- this.blur = new EventEmitter();
1646
- this.change = new EventEmitter();
1647
- this.customEvent = new EventEmitter();
1648
- this.focus = new EventEmitter();
1649
- }
1650
- getClass(context, place, model) {
1651
- return [
1652
- context == "element" ? this.getModelClass(model) : null,
1653
- context == "element" ? this.getAdditionalClass(model) : null,
1654
- super.getClass(context, place, model)
1655
- ].filter(cls => !!cls).join(" ");
1656
- }
1657
- getModelClass(model) {
1658
- const parts = collectPathAble(model, p => p.id);
1659
- if (parts.length == 0)
1660
- return "";
1661
- if (model instanceof DynamicFormGroupModel) {
1662
- return `form-group-${parts.join("-")}`;
1663
- }
1664
- return `form-control-${parts.join("-")}`;
1665
- }
1666
- getAdditionalClass(model) {
1667
- if (model instanceof DynamicFormArrayModel) {
1668
- return model.additional?.classes;
1669
- }
1670
- if (model instanceof DynamicFormValueControlModel) {
1671
- return model.additional?.classes;
1672
- }
1673
- return null;
1674
- }
1675
- }
1676
- DynamicBaseFormGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormGroupComponent, deps: [{ token: i1.DynamicFormLayoutService }, { token: i1.DynamicFormValidationService }], target: i0.ɵɵFactoryTarget.Component });
1677
- DynamicBaseFormGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: DynamicBaseFormGroupComponent, selector: "dynamic-base-form-group", inputs: { formLayout: "formLayout", group: "group", layout: "layout", model: "model", templates: "templates" }, outputs: { blur: "blur", change: "change", customEvent: "customEvent", focus: "focus" }, viewQueries: [{ propertyName: "components", predicate: i0.forwardRef(function () { return DynamicFormControlContainerComponent; }), descendants: true }], usesInheritance: true, ngImport: i0, template: "", isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1678
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormGroupComponent, decorators: [{
1679
- type: Component,
1680
- args: [{
1681
- selector: "dynamic-base-form-group",
1682
- template: "",
1683
- changeDetection: ChangeDetectionStrategy.OnPush
1684
- }]
1685
- }], ctorParameters: function () { return [{ type: i1.DynamicFormLayoutService }, { type: i1.DynamicFormValidationService }]; }, propDecorators: { formLayout: [{
1686
- type: Input
1687
- }], group: [{
1688
- type: Input
1689
- }], layout: [{
1690
- type: Input
1691
- }], model: [{
1692
- type: Input
1693
- }], templates: [{
1694
- type: Input
1695
- }], blur: [{
1696
- type: Output
1697
- }], change: [{
1698
- type: Output
1699
- }], customEvent: [{
1700
- type: Output
1701
- }], focus: [{
1702
- type: Output
1703
- }], components: [{
1704
- type: ViewChildren,
1705
- args: [forwardRef(() => DynamicFormControlContainerComponent)]
1706
- }] } });
1707
-
1708
- class DynamicBaseSelectComponent extends DynamicBaseFormControlComponent {
1709
- ngOnInit() {
1710
- this.groups$ = new BehaviorSubject([]);
1711
- this.subscription = this.model.options$.subscribe(options => {
1712
- const groupBy = this.model.inline || !this.model.multiple ? this.model.groupBy : null;
1713
- const grouped = options.reduce((res, option) => {
1714
- const key = replaceSpecialChars(groupBy ? option.props[this.model.groupBy] || "default" : "default", "-");
1715
- res[key] = res[key] || [];
1716
- res[key].push(option);
1717
- return res;
1718
- }, {});
1719
- const groups = Object.keys(grouped).map(group => {
1720
- return {
1721
- group,
1722
- options: grouped[group]
1723
- };
1724
- });
1725
- this.hasOptions = groups.length > 0;
1726
- this.groups$.next(groups);
1727
- this.cdr.detectChanges();
1728
- });
1729
- }
1730
- ngOnDestroy() {
1731
- if (this.subscription)
1732
- this.subscription.unsubscribe();
1733
- }
1734
- isSelected(option) {
1735
- if (this.model.multiple) {
1736
- return this.control.value?.indexOf(option.value) >= 0;
1737
- }
1738
- return this.control.value == option.value;
1739
- }
1740
- selectToggle(option, state) {
1741
- if (this.model.multiple) {
1742
- const value = Array.from(this.control.value || []);
1743
- const index = value.indexOf(option.value);
1744
- if (index >= 0) {
1745
- value.splice(index, 1);
1746
- }
1747
- if (state) {
1748
- value.push(option.value);
1749
- }
1750
- this.control.setValue(value);
1751
- this.onChange(value);
1752
- return;
1753
- }
1754
- this.control.setValue(option.value);
1755
- this.onChange(option.value);
1756
- }
1757
- }
1758
- DynamicBaseSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1759
- DynamicBaseSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: DynamicBaseSelectComponent, selector: "dynamic-base-select", usesInheritance: true, ngImport: i0, template: "", isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1760
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseSelectComponent, decorators: [{
1761
- type: Component,
1762
- args: [{
1763
- selector: "dynamic-base-select",
1764
- template: "",
1765
- changeDetection: ChangeDetectionStrategy.OnPush
1766
- }]
1767
- }] });
1768
-
1769
- // --- Components ---
1770
- const components = [
1771
- DynamicBaseFormComponent,
1772
- DynamicBaseFormArrayComponent,
1773
- DynamicBaseFormControlComponent,
1774
- DynamicBaseFormControlContainerComponent,
1775
- DynamicBaseFormGroupComponent,
1776
- DynamicBaseSelectComponent
1777
- ];
1778
- // --- Directives ---
1779
- const directives = [
1780
- AsyncSubmitDirective,
1781
- ];
1782
- // --- Pipes ---
1783
- const pipes = [];
1784
- function defaultFormControlProvider() {
1785
- return () => null;
1786
- }
1787
-
1788
- class NgxDynamicFormModule {
1789
- static forRoot(config) {
1790
- return {
1791
- ngModule: NgxDynamicFormModule,
1792
- providers: [
1793
- DynamicFormService,
1794
- {
1795
- provide: DynamicFormService$1,
1796
- useExisting: DynamicFormService
1797
- },
1798
- {
1799
- provide: DYNAMIC_FORM_CONTROL_MAP_FN,
1800
- useFactory: (config?.controlProvider || defaultFormControlProvider),
1801
- deps: [Injector]
1802
- }
1803
- ]
1804
- };
1805
- }
1806
- }
1807
- NgxDynamicFormModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: NgxDynamicFormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1808
- NgxDynamicFormModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: NgxDynamicFormModule, declarations: [DynamicBaseFormComponent, DynamicBaseFormArrayComponent, DynamicBaseFormControlComponent, DynamicBaseFormControlContainerComponent, DynamicBaseFormGroupComponent, DynamicBaseSelectComponent, AsyncSubmitDirective], imports: [CommonModule,
1809
- FormsModule,
1810
- ReactiveFormsModule,
1811
- NgxUtilsModule], exports: [DynamicBaseFormComponent, DynamicBaseFormArrayComponent, DynamicBaseFormControlComponent, DynamicBaseFormControlContainerComponent, DynamicBaseFormGroupComponent, DynamicBaseSelectComponent, AsyncSubmitDirective, FormsModule,
1812
- ReactiveFormsModule,
1813
- NgxUtilsModule] });
1814
- NgxDynamicFormModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: NgxDynamicFormModule, providers: [
1815
- ...pipes,
1816
- { provide: NG_VALIDATORS, useValue: validateJSON, multi: true },
1817
- { provide: NG_VALIDATORS, useValue: validateRequiredTranslation, multi: true },
1818
- { provide: NG_VALIDATORS, useValue: validateItemsMinLength, multi: true },
1819
- { provide: NG_VALIDATORS, useValue: validateItemsMaxLength, multi: true },
1820
- { provide: NG_VALIDATORS, useValue: validateItemsMinValue, multi: true },
1821
- { provide: NG_VALIDATORS, useValue: validateItemsMaxValue, multi: true },
1822
- {
1823
- provide: DYNAMIC_VALIDATORS,
1824
- useValue: new Map([
1825
- ["json", validateJSON],
1826
- ["requiredTranslation", validateRequiredTranslation],
1827
- ["phone", validatePhone],
1828
- ["itemsMinLength", validateItemsMinLength],
1829
- ["itemsMaxLength", validateItemsMaxLength],
1830
- ["itemsMinValue", validateItemsMinValue],
1831
- ["itemsMaxValue", validateItemsMaxValue],
1832
- ])
1833
- }
1834
- ], imports: [[
1835
- CommonModule,
1836
- FormsModule,
1837
- ReactiveFormsModule,
1838
- NgxUtilsModule
1839
- ], FormsModule,
1840
- ReactiveFormsModule,
1841
- NgxUtilsModule] });
1842
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: NgxDynamicFormModule, decorators: [{
1843
- type: NgModule,
1844
- args: [{
1845
- declarations: [
1846
- ...components,
1847
- ...directives,
1848
- ...pipes
1849
- ],
1850
- imports: [
1851
- CommonModule,
1852
- FormsModule,
1853
- ReactiveFormsModule,
1854
- NgxUtilsModule
1855
- ],
1856
- exports: [
1857
- ...components,
1858
- ...directives,
1859
- ...pipes,
1860
- FormsModule,
1861
- ReactiveFormsModule,
1862
- NgxUtilsModule
1863
- ],
1864
- providers: [
1865
- ...pipes,
1866
- { provide: NG_VALIDATORS, useValue: validateJSON, multi: true },
1867
- { provide: NG_VALIDATORS, useValue: validateRequiredTranslation, multi: true },
1868
- { provide: NG_VALIDATORS, useValue: validateItemsMinLength, multi: true },
1869
- { provide: NG_VALIDATORS, useValue: validateItemsMaxLength, multi: true },
1870
- { provide: NG_VALIDATORS, useValue: validateItemsMinValue, multi: true },
1871
- { provide: NG_VALIDATORS, useValue: validateItemsMaxValue, multi: true },
1872
- {
1873
- provide: DYNAMIC_VALIDATORS,
1874
- useValue: new Map([
1875
- ["json", validateJSON],
1876
- ["requiredTranslation", validateRequiredTranslation],
1877
- ["phone", validatePhone],
1878
- ["itemsMinLength", validateItemsMinLength],
1879
- ["itemsMaxLength", validateItemsMaxLength],
1880
- ["itemsMinValue", validateItemsMinValue],
1881
- ["itemsMaxValue", validateItemsMaxValue],
1882
- ])
1883
- }
1884
- ]
1885
- }]
1886
- }] });
1887
-
1888
- /**
1889
- * Generated bundle index. Do not edit.
1890
- */
1891
-
1892
- export { AsyncSubmitDirective, DynamicBaseFormArrayComponent, DynamicBaseFormComponent, DynamicBaseFormControlComponent, DynamicBaseFormControlContainerComponent, DynamicBaseFormGroupComponent, DynamicBaseSelectComponent, DynamicEditorModel, DynamicFormArrayGroupModel, DynamicFormArrayModel, DynamicFormGroupModel, DynamicFormOption, DynamicFormService, DynamicSelectModel, EDITOR_FORMATS, FormSelectSubject, FormSubject, MAX_INPUT_NUM, MIN_INPUT_NUM, NgxDynamicFormModule, collectPathAble, createFormArray, createFormCheckbox, createFormDate, createFormEditor, createFormFile, createFormGroup, createFormInput, createFormSelect, createFormTextarea, customizeFormModel, getDynamicPath, getFormComponent, mergeFormModels, replaceSpecialChars, validateItemsMaxLength, validateItemsMaxValue, validateItemsMinLength, validateItemsMinValue, validateJSON, validatePhone, validateRequiredTranslation };
1893
- //# sourceMappingURL=stemy-ngx-dynamic-form.mjs.map