@stemy/ngx-dynamic-form 13.1.1 → 13.1.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.
Files changed (27) hide show
  1. package/esm2020/ngx-dynamic-form/common-types.mjs +1 -1
  2. package/esm2020/ngx-dynamic-form/components/base/dynamic-base-form-array.component.mjs +28 -12
  3. package/esm2020/ngx-dynamic-form/components/base/dynamic-base-form-control-container.component.mjs +37 -18
  4. package/esm2020/ngx-dynamic-form/components/base/dynamic-base-form-control.component.mjs +5 -4
  5. package/esm2020/ngx-dynamic-form/components/base/dynamic-base-form.component.mjs +21 -11
  6. package/esm2020/ngx-dynamic-form/components/base/dynamic-base-select.component.mjs +8 -5
  7. package/esm2020/ngx-dynamic-form/services/dynamic-form.service.mjs +69 -64
  8. package/esm2020/ngx-dynamic-form/utils/dynamic-form-array.model.mjs +114 -5
  9. package/esm2020/ngx-dynamic-form/utils/form-select-subject.mjs +10 -7
  10. package/esm2020/ngx-dynamic-form/utils/misc.mjs +4 -4
  11. package/esm2020/public_api.mjs +2 -2
  12. package/fesm2015/stemy-ngx-dynamic-form.mjs +373 -209
  13. package/fesm2015/stemy-ngx-dynamic-form.mjs.map +1 -1
  14. package/fesm2020/stemy-ngx-dynamic-form.mjs +365 -203
  15. package/fesm2020/stemy-ngx-dynamic-form.mjs.map +1 -1
  16. package/ngx-dynamic-form/common-types.d.ts +3 -33
  17. package/ngx-dynamic-form/components/base/dynamic-base-form-array.component.d.ts +18 -10
  18. package/ngx-dynamic-form/components/base/dynamic-base-form-control-container.component.d.ts +10 -12
  19. package/ngx-dynamic-form/components/base/dynamic-base-form-control.component.d.ts +3 -2
  20. package/ngx-dynamic-form/components/base/dynamic-base-form.component.d.ts +3 -1
  21. package/ngx-dynamic-form/components/base/dynamic-base-select.component.d.ts +1 -0
  22. package/ngx-dynamic-form/ngx-dynamic-form.imports.d.ts +1 -1
  23. package/ngx-dynamic-form/services/dynamic-form.service.d.ts +9 -10
  24. package/ngx-dynamic-form/utils/dynamic-form-array.model.d.ts +47 -4
  25. package/ngx-dynamic-form/utils/misc.d.ts +2 -2
  26. package/package.json +1 -1
  27. package/public_api.d.ts +2 -2
@@ -1,12 +1,12 @@
1
1
  import * as i2 from '@stemy/ngx-utils';
2
- import { ReflectUtils, ObjectUtils, StringUtils, OpenApiService, TOASTER_SERVICE, ObservableUtils, EventsService, NgxUtilsModule } from '@stemy/ngx-utils';
2
+ import { ReflectUtils, ObjectUtils, TimerUtils, StringUtils, OpenApiService, TOASTER_SERVICE, ObservableUtils, EventsService, NgxUtilsModule } from '@stemy/ngx-utils';
3
+ import { BehaviorSubject, of, isObservable, map, Subject, firstValueFrom, Subscription, debounceTime, groupBy, mergeMap } from 'rxjs';
3
4
  import * as i1 from '@ng-dynamic-forms/core';
4
- import { DynamicFormArrayModel as DynamicFormArrayModel$1, DynamicFormOption as DynamicFormOption$1, DynamicSelectModel as DynamicSelectModel$1, DynamicFormService as DynamicFormService$1, DynamicFormGroupModel, DynamicInputModel, DynamicFileUploadModel, DynamicCheckboxModel, DynamicTextAreaModel, DynamicFormComponent, DynamicTemplateDirective, DynamicFormArrayComponent, DynamicFormValueControlModel, DynamicFormControlContainerComponent, DynamicFormControlComponent, DYNAMIC_FORM_CONTROL_TYPE_ARRAY, DynamicFormGroupComponent, DYNAMIC_FORM_CONTROL_MAP_FN, DYNAMIC_VALIDATORS } from '@ng-dynamic-forms/core';
5
+ import { DynamicFormArrayGroupModel as DynamicFormArrayGroupModel$1, DynamicFormArrayModel as DynamicFormArrayModel$1, DynamicFormOption as DynamicFormOption$1, DynamicSelectModel as DynamicSelectModel$1, DynamicFormService as DynamicFormService$1, DynamicFormGroupModel, DynamicInputModel, DynamicFileUploadModel, DynamicCheckboxModel, DynamicTextAreaModel, DynamicFormComponent, DynamicTemplateDirective, DynamicFormControlContainerComponent, DYNAMIC_FORM_CONTROL_TYPE_ARRAY, DynamicFormArrayComponent, DynamicFormValueControlModel, DynamicFormControlComponent, DynamicFormGroupComponent, DYNAMIC_FORM_CONTROL_MAP_FN, DYNAMIC_VALIDATORS } from '@ng-dynamic-forms/core';
5
6
  export { DYNAMIC_FORM_CONTROL_TYPE_ARRAY, DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX, DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX_GROUP, 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, DynamicFileUploadModel, DynamicFormGroupModel, DynamicFormsCoreModule, DynamicInputModel, DynamicListDirective, DynamicRadioGroupModel, DynamicTemplateDirective, DynamicTextAreaModel } from '@ng-dynamic-forms/core';
6
- import { of, isObservable, map, Subject, Subscription, BehaviorSubject } from 'rxjs';
7
7
  import { __awaiter } from 'tslib';
8
8
  import * as i0 from '@angular/core';
9
- import { EventEmitter, Injector, Injectable, Inject, Directive, Input, Output, HostBinding, HostListener, QueryList, Component, ChangeDetectionStrategy, ContentChildren, ViewChildren, ViewChild, forwardRef, ViewContainerRef, NgModule } from '@angular/core';
9
+ import { Injector, Injectable, Inject, EventEmitter, Directive, Input, Output, HostBinding, HostListener, QueryList, Component, ChangeDetectionStrategy, ContentChildren, ViewChildren, ViewChild, ViewContainerRef, forwardRef, NgModule } from '@angular/core';
10
10
  import { FormGroup, FormArray, NgForm, FormsModule, ReactiveFormsModule, NG_VALIDATORS } from '@angular/forms';
11
11
  import { first } from 'rxjs/operators';
12
12
  import { CommonModule } from '@angular/common';
@@ -118,7 +118,7 @@ function findRefs(property) {
118
118
  return refs.map(t => t.split("/").pop());
119
119
  }
120
120
  function replaceSpecialChars(str, to = "-") {
121
- return (str || "").replace(/[&\/\\#, +()$~%.'":*?<>{}]/g, to);
121
+ return `${str}`.replace(/[&\/\\#, +()$~%.@'":*?<>{}]/g, to);
122
122
  }
123
123
  function mergeFormModels(formModels) {
124
124
  const res = [];
@@ -148,8 +148,8 @@ function collectPathAble(start, getter) {
148
148
  }
149
149
  return parts;
150
150
  }
151
- const MIN_INPUT_NUM = -99999999999999;
152
- const MAX_INPUT_NUM = 99999999999999;
151
+ const MIN_INPUT_NUM = -999999999;
152
+ const MAX_INPUT_NUM = 999999999;
153
153
 
154
154
  function validateJSON(control) {
155
155
  const value = control.value;
@@ -207,12 +207,32 @@ function validateItemsMaxValue(max) {
207
207
  };
208
208
  }
209
209
 
210
+ class DynamicFormArrayGroupModel extends DynamicFormArrayGroupModel$1 {
211
+ constructor(context, group, index = -1) {
212
+ super(context, group, index);
213
+ this.context = context;
214
+ this.isHidden = false;
215
+ }
216
+ get hidden() {
217
+ return this.isHidden;
218
+ }
219
+ set hidden(value) {
220
+ var _a;
221
+ if (this.isHidden == value)
222
+ return;
223
+ this.isHidden = value || false;
224
+ (_a = this.context) === null || _a === void 0 ? void 0 : _a.filterGroups();
225
+ }
226
+ }
210
227
  class DynamicFormArrayModel extends DynamicFormArrayModel$1 {
211
228
  constructor(config, layout) {
212
229
  super(config, layout);
230
+ this.config = config;
231
+ this.filteredGroups = new BehaviorSubject([]);
232
+ this.sortable = config.sortable || false;
213
233
  this.useTabs = config.useTabs || false;
214
- this.saveTab = ObjectUtils.isFunction(config.saveTab) ? config.saveTab : ((index, model) => {
215
- model.tabIndex = index;
234
+ this.saveTab = ObjectUtils.isFunction(config.saveTab) ? config.saveTab : ((index, model, arrayModel) => {
235
+ arrayModel.tabIndex = index;
216
236
  });
217
237
  this.restoreTab = ObjectUtils.isFunction(config.restoreTab) ? config.restoreTab : ((model) => {
218
238
  return model.tabIndex;
@@ -221,6 +241,96 @@ class DynamicFormArrayModel extends DynamicFormArrayModel$1 {
221
241
  return `${index + 1}`;
222
242
  });
223
243
  this.additional = config.additional || {};
244
+ this.tabIndex = 0;
245
+ this._sortBy = null;
246
+ this._sortDescending = false;
247
+ this._formArray = null;
248
+ }
249
+ get addItem() {
250
+ return this.config.addItem !== false;
251
+ }
252
+ get insertItem() {
253
+ return !this._sortBy && this.config.insertItem !== false;
254
+ }
255
+ get cloneItem() {
256
+ return this.config.cloneItem !== false;
257
+ }
258
+ get moveItem() {
259
+ return !this._sortBy && this.config.moveItem !== false;
260
+ }
261
+ get removeItem() {
262
+ return this.config.removeItem !== false;
263
+ }
264
+ get clearItems() {
265
+ return this.config.clearItems !== false;
266
+ }
267
+ get sortBy() {
268
+ return this._sortBy;
269
+ }
270
+ set sortBy(value) {
271
+ if (!this.sortable)
272
+ return;
273
+ value = value || null;
274
+ if (this._sortBy !== value) {
275
+ this._sortBy = value;
276
+ this._sortDescending = false;
277
+ }
278
+ else if (this._sortDescending) {
279
+ this._sortBy = null;
280
+ this._sortDescending = false;
281
+ }
282
+ else {
283
+ this._sortDescending = true;
284
+ }
285
+ this.filterGroups();
286
+ }
287
+ get sortDescending() {
288
+ return this._sortDescending;
289
+ }
290
+ get sortOrder() {
291
+ return this.sortDescending ? "desc" : "asc";
292
+ }
293
+ initialize(array) {
294
+ this._formArray = array || this._formArray;
295
+ this.filterGroups();
296
+ }
297
+ filterGroups() {
298
+ this._filterTimer = this._filterTimer || TimerUtils.createTimeout();
299
+ this._filterTimer.set(() => {
300
+ const filtered = this.groups.filter(g => !g.hidden);
301
+ if (this._sortBy && this._formArray) {
302
+ const compare = this._sortDescending
303
+ ? (a, b) => this.compareModels(b, a)
304
+ : (a, b) => this.compareModels(a, b);
305
+ filtered.sort(compare);
306
+ }
307
+ this._filteredGroups = filtered;
308
+ this.filteredGroups.next(filtered);
309
+ }, 100);
310
+ }
311
+ getFiltered(index) {
312
+ return !this._filteredGroups ? null : this._filteredGroups[index];
313
+ }
314
+ insertGroup(index) {
315
+ const group = new DynamicFormArrayGroupModel(this, this.groupFactory());
316
+ this.groups.splice(index, 0, group);
317
+ this.groups.forEach((g, index) => g.index = index);
318
+ this.filterGroups();
319
+ return group;
320
+ }
321
+ moveGroup(index, step) {
322
+ super.moveGroup(index, step);
323
+ this.filterGroups();
324
+ }
325
+ removeGroup(index) {
326
+ super.removeGroup(index);
327
+ this.filterGroups();
328
+ }
329
+ compareModels(a, b) {
330
+ var _a, _b;
331
+ const aGroup = ((_a = this._formArray.at(a.index).get(this._sortBy)) === null || _a === void 0 ? void 0 : _a.value) || null;
332
+ const bGroup = ((_b = this._formArray.at(b.index).get(this._sortBy)) === null || _b === void 0 ? void 0 : _b.value) || null;
333
+ return ObjectUtils.compare(aGroup, bGroup);
224
334
  }
225
335
  }
226
336
 
@@ -310,21 +420,24 @@ class FormSelectSubject extends FormSubject {
310
420
  handleNotifiedValue(controlModel, control, val) {
311
421
  val.then(options => {
312
422
  var _a, _b;
313
- this.next(options);
314
- if (options.length == 0)
423
+ if (options.length == 0) {
424
+ this.next(options);
315
425
  return;
426
+ }
316
427
  const currentVal = control.value;
317
428
  if (controlModel.multiple) {
318
429
  const correctVal = (currentVal || []).filter(t => options.findIndex(o => o.value == t) >= 0);
319
430
  if (correctVal.length !== (currentVal === null || currentVal === void 0 ? void 0 : currentVal.length)) {
320
431
  control.setValue(correctVal, { onlySelf: true, emitEvent: false });
321
432
  }
322
- return;
323
433
  }
324
- const option = options.find(t => t.value == currentVal);
325
- if (!option) {
326
- control.setValue((_b = (_a = options[0]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null, { onlySelf: true, emitEvent: false });
434
+ else {
435
+ const option = options.find(t => t.value == currentVal);
436
+ if (!option) {
437
+ control.setValue((_b = (_a = options[0]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null, { onlySelf: true, emitEvent: false });
438
+ }
327
439
  }
440
+ this.next(options);
328
441
  });
329
442
  }
330
443
  }
@@ -334,7 +447,6 @@ class DynamicFormService extends DynamicFormService$1 {
334
447
  super(cs, vs);
335
448
  this.openApi = openApi;
336
449
  this.injector = injector;
337
- this.onDetectChanges = new EventEmitter();
338
450
  }
339
451
  get api() {
340
452
  return this.openApi.api;
@@ -344,43 +456,24 @@ class DynamicFormService extends DynamicFormService$1 {
344
456
  }
345
457
  patchGroup(value, formModel, formGroup) {
346
458
  this.patchValueRecursive(value, formModel, formGroup);
347
- this.detectChanges();
348
459
  formGroup.patchValue(ObjectUtils.copy(value));
460
+ this.detectChanges();
349
461
  }
350
462
  patchForm(value, component) {
351
463
  this.patchValueRecursive(value, component.model, component.group);
352
- this.detectChanges(component);
353
464
  component.group.patchValue(value);
465
+ this.detectChanges(component);
354
466
  }
355
467
  serialize(formModel, formGroup) {
356
468
  return this.serializeRecursive(formModel, formGroup);
357
469
  }
358
- notifyChanges(formModel, formGroup, root) {
359
- this.notifyChangesRecursive(formModel, formGroup, root);
360
- }
361
- updateSelectOptions(formControlModel, formControl, root) {
362
- if (formControlModel instanceof DynamicSelectModel) {
363
- let options = formControlModel.options$;
364
- if (options instanceof FormSubject) {
365
- options.notify(formControlModel, formControl, root);
366
- return;
367
- }
368
- while (options instanceof Subject && options.source) {
369
- options = options.source;
370
- if (options instanceof FormSubject) {
371
- options.notify(formControlModel, formControl, root);
372
- }
373
- }
374
- }
470
+ notifyChanges(formModel, formGroup) {
471
+ this.notifyChangesRecursive(formModel, formGroup, formModel);
375
472
  }
376
473
  showErrors(form) {
377
474
  this.showErrorsForGroup(form.group);
378
475
  this.detectChanges(form);
379
476
  }
380
- detectChanges(formComponent) {
381
- super.detectChanges(formComponent);
382
- this.onDetectChanges.emit(formComponent);
383
- }
384
477
  patchValueRecursive(value, formModel, formGroup) {
385
478
  Object.keys(value).forEach(key => {
386
479
  const subModel = this.findModelById(key, formModel);
@@ -392,7 +485,7 @@ class DynamicFormService extends DynamicFormService$1 {
392
485
  value[key] = subValue.id || subValue._id || subValue;
393
486
  return;
394
487
  }
395
- if (subModel instanceof DynamicFormArrayModel$1) {
488
+ if (subModel instanceof DynamicFormArrayModel) {
396
489
  const length = Array.isArray(subValue) ? subValue.length : 0;
397
490
  const subArray = subControl;
398
491
  while (subModel.size > length) {
@@ -426,7 +519,7 @@ class DynamicFormService extends DynamicFormService$1 {
426
519
  result[subModel.id] = yield serializer(subModel, subControl);
427
520
  continue;
428
521
  }
429
- if (subModel instanceof DynamicFormArrayModel$1) {
522
+ if (subModel instanceof DynamicFormArrayModel) {
430
523
  const length = Array.isArray(subControl.value) ? subControl.value.length : 0;
431
524
  const subArray = subControl;
432
525
  const resArray = [];
@@ -458,7 +551,7 @@ class DynamicFormService extends DynamicFormService$1 {
458
551
  for (const i in formModel) {
459
552
  const subModel = formModel[i];
460
553
  const subControl = this.findControlByModel(subModel, formGroup);
461
- if (subModel instanceof DynamicFormArrayModel$1) {
554
+ if (subModel instanceof DynamicFormArrayModel) {
462
555
  const length = Array.isArray(subControl.value) ? subControl.value.length : 0;
463
556
  const subArray = subControl;
464
557
  for (let i = 0; i < length; i++) {
@@ -474,6 +567,21 @@ class DynamicFormService extends DynamicFormService$1 {
474
567
  this.updateSelectOptions(subModel, subControl, root);
475
568
  }
476
569
  }
570
+ updateSelectOptions(formControlModel, formControl, root) {
571
+ if (formControlModel instanceof DynamicSelectModel) {
572
+ let options = formControlModel.options$;
573
+ if (options instanceof FormSubject) {
574
+ options.notify(formControlModel, formControl, root);
575
+ return;
576
+ }
577
+ while (options instanceof Subject && options.source) {
578
+ options = options.source;
579
+ if (options instanceof FormSubject) {
580
+ options.notify(formControlModel, formControl, root);
581
+ }
582
+ }
583
+ }
584
+ }
477
585
  showErrorsForGroup(formGroup) {
478
586
  if (!formGroup)
479
587
  return;
@@ -543,7 +651,7 @@ class DynamicFormService extends DynamicFormService$1 {
543
651
  case "file":
544
652
  return customizeModels(property, schema, DynamicFileUploadModel, this.getFormUploadConfig(property, schema));
545
653
  }
546
- if (property.$ref) {
654
+ if (findRefs(property).length > 0) {
547
655
  return customizeModels(property, schema, DynamicFormGroupModel, this.getFormGroupConfig(property, schema, customizeModels));
548
656
  }
549
657
  return [];
@@ -555,7 +663,7 @@ class DynamicFormService extends DynamicFormService$1 {
555
663
  if (Array.isArray(parent)) {
556
664
  return this.findModelByPath(parent.find(t => t.id == next), path);
557
665
  }
558
- if (parent instanceof DynamicFormGroupModel) {
666
+ if (parent instanceof DynamicFormGroupModel || parent instanceof DynamicFormArrayGroupModel) {
559
667
  return this.findModelByPath(parent.group.find(t => t.id == next), path);
560
668
  }
561
669
  if (parent instanceof DynamicFormArrayModel) {
@@ -583,7 +691,14 @@ class DynamicFormService extends DynamicFormService$1 {
583
691
  const subSchemas = findRefs(property).map(ref => this.schemas[ref]);
584
692
  return Object.assign(this.getFormControlConfig(property, schema), {
585
693
  groupFactory: () => mergeFormModels(subSchemas.map(s => this.getFormModelForSchemaDef(s, customizeModels))),
586
- useTabs: property.useTabs || false
694
+ sortable: property.sortable || false,
695
+ useTabs: property.useTabs || false,
696
+ addItem: property.addItem !== false,
697
+ insertItem: property.insertItem !== false,
698
+ cloneItem: property.cloneItem !== false,
699
+ moveItem: property.moveItem !== false,
700
+ removeItem: property.removeItem !== false,
701
+ clearItems: property.clearItems !== false
587
702
  });
588
703
  }
589
704
  getFormGroupConfig(property, schema, customizeModels) {
@@ -617,7 +732,7 @@ class DynamicFormService extends DynamicFormService$1 {
617
732
  step: isNaN(sub.step) ? (isNaN(property.step) ? 1 : property.step) : sub.step,
618
733
  min: isNaN(sub.minimum) ? MIN_INPUT_NUM : sub.minimum,
619
734
  max: isNaN(sub.maximum) ? MAX_INPUT_NUM : sub.maximum,
620
- minLength: isNaN(sub.minLength) ? MIN_INPUT_NUM : sub.minLength,
735
+ minLength: isNaN(sub.minLength) ? 0 : sub.minLength,
621
736
  maxLength: isNaN(sub.maxLength) ? MAX_INPUT_NUM : sub.maxLength,
622
737
  placeholder: property.placeholder || ""
623
738
  });
@@ -631,34 +746,6 @@ class DynamicFormService extends DynamicFormService$1 {
631
746
  multiple: property.type == "array"
632
747
  });
633
748
  }
634
- getFormSelectConfig(property, schema) {
635
- return Object.assign(this.getFormControlConfig(property, schema), {
636
- options: this.getFormSelectOptions(property, schema),
637
- multiple: property.type == "array",
638
- groupBy: property.groupBy,
639
- inline: property.inline
640
- });
641
- }
642
- getFormCheckboxConfig(property, schema) {
643
- return Object.assign(this.getFormControlConfig(property, schema), {
644
- indeterminate: property.indeterminate === true
645
- });
646
- }
647
- cloneFormArrayGroup(index, formArray, formArrayModel) {
648
- this.insertFormArrayGroup(index, formArray, formArrayModel);
649
- this.patchGroup(formArray.at(index + 1).value, formArrayModel.groups[index].group, formArray.at(index));
650
- }
651
- fixSelectOptions(model, control, options) {
652
- return __awaiter(this, void 0, void 0, function* () {
653
- if (!options)
654
- return [];
655
- for (const option of options) {
656
- option.classes = [option.classes, model.getClasses(option, model, control, this.injector)].filter(isStringWithVal).join(" ");
657
- option.label = yield this.language.getTranslation(option.label);
658
- }
659
- return options;
660
- });
661
- }
662
749
  getFormSelectOptions(property, schema) {
663
750
  var _a;
664
751
  const $enum = ((_a = property.items) === null || _a === void 0 ? void 0 : _a.enum) || property.enum;
@@ -672,7 +759,7 @@ class DynamicFormService extends DynamicFormService$1 {
672
759
  });
673
760
  }
674
761
  if (isStringWithVal(property.optionsPath)) {
675
- return new FormSelectSubject((selectModel, control, root, indexes) => {
762
+ return new FormSelectSubject((selectModel, control, root, indexes) => __awaiter(this, void 0, void 0, function* () {
676
763
  let path = property.optionsPath;
677
764
  let target = control;
678
765
  let model = selectModel;
@@ -694,14 +781,16 @@ class DynamicFormService extends DynamicFormService$1 {
694
781
  path = path.replace(key, indexes[key]);
695
782
  });
696
783
  model = this.findModelByPath(model, path.split("."));
697
- const modelOptions = (model instanceof DynamicSelectModel ? model.options : []);
784
+ const modelOptions = model instanceof DynamicSelectModel
785
+ ? yield firstValueFrom(model.options$) :
786
+ [];
698
787
  const value = ObjectUtils.getValue(target.value, path);
699
788
  const options = (!ObjectUtils.isArray(value) ? [] : value).map(value => {
700
789
  const modelOption = modelOptions.find(t => t.value == value);
701
790
  return { value, label: (modelOption === null || modelOption === void 0 ? void 0 : modelOption.label) || value };
702
791
  });
703
792
  return this.fixSelectOptions(selectModel, control, options);
704
- });
793
+ }));
705
794
  }
706
795
  return new FormSelectSubject((selectModel, control) => __awaiter(this, void 0, void 0, function* () {
707
796
  this.api.cache[property.endpoint] = this.api.cache[property.endpoint] || this.api.list(property.endpoint, this.api.makeListParams(1, -1)).then(result => {
@@ -713,6 +802,14 @@ class DynamicFormService extends DynamicFormService$1 {
713
802
  return this.fixSelectOptions(selectModel, control, options);
714
803
  }));
715
804
  }
805
+ getFormSelectConfig(property, schema) {
806
+ return Object.assign(this.getFormControlConfig(property, schema), {
807
+ options: this.getFormSelectOptions(property, schema),
808
+ multiple: property.type == "array",
809
+ groupBy: property.groupBy,
810
+ inline: property.inline
811
+ });
812
+ }
716
813
  getFormUploadConfig(property, schema) {
717
814
  const url = this.api.url(property.url || "assets");
718
815
  const { accept, autoUpload, maxSize, minSize, removeUrl, showFileList } = property;
@@ -726,6 +823,27 @@ class DynamicFormService extends DynamicFormService$1 {
726
823
  showFileList
727
824
  });
728
825
  }
826
+ getFormCheckboxConfig(property, schema) {
827
+ return Object.assign(this.getFormControlConfig(property, schema), {
828
+ indeterminate: property.indeterminate || false
829
+ });
830
+ }
831
+ cloneFormArrayGroup(index, formArray, formArrayModel) {
832
+ this.insertFormArrayGroup(index, formArray, formArrayModel);
833
+ this.patchGroup(formArray.at(index + 1).value, formArrayModel.groups[index].group, formArray.at(index));
834
+ formArrayModel.filterGroups();
835
+ }
836
+ fixSelectOptions(model, control, options) {
837
+ return __awaiter(this, void 0, void 0, function* () {
838
+ if (!options)
839
+ return [];
840
+ for (const option of options) {
841
+ option.classes = [option.classes, model.getClasses(option, model, control, this.injector)].filter(isStringWithVal).join(" ");
842
+ option.label = yield this.language.getTranslation(option.label);
843
+ }
844
+ return options;
845
+ });
846
+ }
729
847
  getValidators(property, schema) {
730
848
  const validators = {};
731
849
  if (ObjectUtils.isArray(schema.required) && schema.required.indexOf(property.id) >= 0) {
@@ -908,6 +1026,7 @@ class DynamicBaseFormComponent extends DynamicFormComponent {
908
1026
  this.onValueChange = new EventEmitter();
909
1027
  this.onStatusChange = new EventEmitter();
910
1028
  this.onSubmit = new EventEmitter();
1029
+ this.onDetectChanges = new EventEmitter();
911
1030
  this.templates = new QueryList();
912
1031
  this.subscription = new Subscription();
913
1032
  this.groupSubscription = new Subscription();
@@ -921,9 +1040,11 @@ class DynamicBaseFormComponent extends DynamicFormComponent {
921
1040
  if (this.group) {
922
1041
  this.groupSubscription = ObservableUtils.multiSubscription(this.group.statusChanges.subscribe(() => {
923
1042
  this.onStatusChange.emit(this);
924
- }), this.group.valueChanges.subscribe(() => {
925
- this.formService.notifyChanges(this.model, this.group, this.model);
926
- }), this.change.subscribe(ev => {
1043
+ }), this.group.valueChanges.pipe(debounceTime(500)).subscribe(() => {
1044
+ this.formService.notifyChanges(this.model, this.group);
1045
+ }), this.change.pipe(groupBy(ev => ev.model))
1046
+ .pipe(mergeMap(t => t.pipe(debounceTime(500))))
1047
+ .subscribe(ev => {
927
1048
  this.onValueChange.emit(Object.assign(Object.assign({}, ev), { form: this }));
928
1049
  }));
929
1050
  }
@@ -936,6 +1057,7 @@ class DynamicBaseFormComponent extends DynamicFormComponent {
936
1057
  this.templates.reset(templates);
937
1058
  }
938
1059
  }), this.events.languageChanged.subscribe(() => {
1060
+ this.formService.notifyChanges(this.model, this.group);
939
1061
  this.formService.detectChanges(this);
940
1062
  }), this.ngForm.ngSubmit.subscribe(() => {
941
1063
  this.onSubmit.emit(this);
@@ -946,25 +1068,29 @@ class DynamicBaseFormComponent extends DynamicFormComponent {
946
1068
  this.subscription.unsubscribe();
947
1069
  this.groupSubscription.unsubscribe();
948
1070
  }
1071
+ detectChanges() {
1072
+ super.detectChanges();
1073
+ this.onDetectChanges.emit(this);
1074
+ }
949
1075
  insertFormArrayGroup(index, formArray, formArrayModel) {
950
1076
  this.formService.insertFormArrayGroup(index, formArray, formArrayModel);
951
- this.changeDetectorRef.detectChanges();
1077
+ this.detectChanges();
952
1078
  }
953
1079
  cloneFormArrayGroup(index, formArray, formArrayModel) {
954
1080
  this.formService.cloneFormArrayGroup(index, formArray, formArrayModel);
955
- this.changeDetectorRef.detectChanges();
1081
+ this.detectChanges();
956
1082
  }
957
1083
  removeFormArrayGroup(index, formArray, formArrayModel) {
958
1084
  this.formService.removeFormArrayGroup(index, formArray, formArrayModel);
959
- this.changeDetectorRef.detectChanges();
1085
+ this.detectChanges();
960
1086
  }
961
1087
  moveFormArrayGroup(index, step, formArray, formArrayModel) {
962
1088
  this.formService.moveFormArrayGroup(index, step, formArray, formArrayModel);
963
- this.changeDetectorRef.detectChanges();
1089
+ this.detectChanges();
964
1090
  }
965
1091
  clearFormArray(formArray, formArrayModel) {
966
1092
  this.formService.clearFormArray(formArray, formArrayModel);
967
- this.changeDetectorRef.detectChanges();
1093
+ this.detectChanges();
968
1094
  }
969
1095
  getClass(model) {
970
1096
  const parts = collectPathAble(model, p => p.id);
@@ -1004,7 +1130,7 @@ class DynamicBaseFormComponent extends DynamicFormComponent {
1004
1130
  }
1005
1131
  }
1006
1132
  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 });
1007
- DynamicBaseFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: DynamicBaseFormComponent, selector: "dynamic-base-form", inputs: { group: "group", model: "model", layout: "layout", labelPrefix: "labelPrefix" }, outputs: { blur: "blur", change: "change", focus: "focus", onValueChange: "onValueChange", onStatusChange: "onStatusChange", onSubmit: "onSubmit" }, queries: [{ propertyName: "contentTemplates", predicate: DynamicTemplateDirective }], viewQueries: [{ propertyName: "ngForm", first: true, predicate: NgForm, descendants: true }, { propertyName: "viewTemplates", predicate: DynamicTemplateDirective, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "", isInline: true, changeDetection: i0.ChangeDetectionStrategy.Default });
1133
+ DynamicBaseFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: DynamicBaseFormComponent, selector: "dynamic-base-form", inputs: { group: "group", model: "model", layout: "layout", labelPrefix: "labelPrefix" }, outputs: { blur: "blur", change: "change", focus: "focus", onValueChange: "onValueChange", onStatusChange: "onStatusChange", onSubmit: "onSubmit", onDetectChanges: "onDetectChanges" }, queries: [{ propertyName: "contentTemplates", predicate: DynamicTemplateDirective }], viewQueries: [{ propertyName: "ngForm", first: true, predicate: NgForm, descendants: true }, { propertyName: "viewTemplates", predicate: DynamicTemplateDirective, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "", isInline: true, changeDetection: i0.ChangeDetectionStrategy.Default });
1008
1134
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormComponent, decorators: [{
1009
1135
  type: Component,
1010
1136
  args: [{
@@ -1046,17 +1172,142 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImpor
1046
1172
  type: Output
1047
1173
  }], onSubmit: [{
1048
1174
  type: Output
1175
+ }], onDetectChanges: [{
1176
+ type: Output
1049
1177
  }], ngForm: [{
1050
1178
  type: ViewChild,
1051
1179
  args: [NgForm]
1052
1180
  }] } });
1053
1181
 
1182
+ class DynamicBaseFormControlContainerComponent extends DynamicFormControlContainerComponent {
1183
+ constructor(form, cdr, cfr, layoutService, validationService, componentService, relationService) {
1184
+ super(cdr, cfr, layoutService, validationService, componentService, relationService);
1185
+ this.form = form;
1186
+ this.cdr = cdr;
1187
+ this.context = null;
1188
+ this.blur = new EventEmitter();
1189
+ this.change = new EventEmitter();
1190
+ this.focus = new EventEmitter();
1191
+ }
1192
+ get componentType() {
1193
+ var _a;
1194
+ return (_a = this.componentService.getCustomComponentType(this.model)) !== null && _a !== void 0 ? _a : this.getComponentType(this.model);
1195
+ }
1196
+ get startTemplate() {
1197
+ return (this.model.type == DYNAMIC_FORM_CONTROL_TYPE_ARRAY)
1198
+ ? this.layoutService.getAlignedTemplate(this.model, this.templates, "ARRAY_START")
1199
+ : this.layoutService.getStartTemplate(this.model, this.templates);
1200
+ }
1201
+ get endTemplate() {
1202
+ return (this.model.type == DYNAMIC_FORM_CONTROL_TYPE_ARRAY)
1203
+ ? this.layoutService.getAlignedTemplate(this.model, this.templates, "ARRAY_END")
1204
+ : this.layoutService.getEndTemplate(this.model, this.templates);
1205
+ }
1206
+ get formService() {
1207
+ return this.form.formService;
1208
+ }
1209
+ ngOnInit() {
1210
+ super.ngOnInit();
1211
+ this.onDetectChanges = this.form.onDetectChanges.subscribe(() => {
1212
+ this.changeDetectorRef.detectChanges();
1213
+ });
1214
+ }
1215
+ ngOnDestroy() {
1216
+ super.ngOnDestroy();
1217
+ this.onDetectChanges.unsubscribe();
1218
+ }
1219
+ getLabel() {
1220
+ var _a;
1221
+ const label = collectPathAble(this.model, p => p.label);
1222
+ if (label.length == 0)
1223
+ return "";
1224
+ if ((_a = this.form) === null || _a === void 0 ? void 0 : _a.labelPrefix) {
1225
+ label.unshift(this.form.labelPrefix);
1226
+ }
1227
+ return label.join(".");
1228
+ }
1229
+ getLabelIcon() {
1230
+ if (this.context instanceof DynamicFormArrayGroupModel) {
1231
+ const arrayModel = this.context.context;
1232
+ if (arrayModel && arrayModel.sortBy == this.model.id) {
1233
+ return arrayModel.sortOrder;
1234
+ }
1235
+ }
1236
+ return null;
1237
+ }
1238
+ clickLabel() {
1239
+ if (this.context instanceof DynamicFormArrayGroupModel) {
1240
+ const arrayModel = this.context.context;
1241
+ if (arrayModel) {
1242
+ arrayModel.sortBy = this.model.id;
1243
+ }
1244
+ }
1245
+ }
1246
+ createFormControlComponent() {
1247
+ var _a;
1248
+ super.createFormControlComponent();
1249
+ const component = (_a = this.componentRef) === null || _a === void 0 ? void 0 : _a.instance;
1250
+ if (!component || !ObjectUtils.isFunction(component.initialize))
1251
+ return;
1252
+ component.initialize(this.changeDetectorRef);
1253
+ }
1254
+ getComponentType(model) {
1255
+ return null;
1256
+ }
1257
+ }
1258
+ DynamicBaseFormControlContainerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormControlContainerComponent, deps: [{ token: DynamicBaseFormComponent }, { token: i0.ChangeDetectorRef }, { token: i0.ComponentFactoryResolver }, { token: i1.DynamicFormLayoutService }, { token: i1.DynamicFormValidationService }, { token: i1.DynamicFormComponentService }, { token: i1.DynamicFormRelationService }], target: i0.ɵɵFactoryTarget.Component });
1259
+ 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: [
1260
+ { provide: DynamicFormControlContainerComponent, useExisting: DynamicBaseFormControlContainerComponent }
1261
+ ], 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 });
1262
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormControlContainerComponent, decorators: [{
1263
+ type: Component,
1264
+ args: [{
1265
+ selector: "dynamic-base-form-control",
1266
+ template: "",
1267
+ changeDetection: ChangeDetectionStrategy.OnPush,
1268
+ providers: [
1269
+ { provide: DynamicFormControlContainerComponent, useExisting: DynamicBaseFormControlContainerComponent }
1270
+ ]
1271
+ }]
1272
+ }], ctorParameters: function () { return [{ type: DynamicBaseFormComponent }, { type: i0.ChangeDetectorRef }, { type: i0.ComponentFactoryResolver }, { type: i1.DynamicFormLayoutService }, { type: i1.DynamicFormValidationService }, { type: i1.DynamicFormComponentService }, { type: i1.DynamicFormRelationService }]; }, propDecorators: { contentTemplateList: [{
1273
+ type: ContentChildren,
1274
+ args: [DynamicTemplateDirective]
1275
+ }], klass: [{
1276
+ type: HostBinding,
1277
+ args: ["class"]
1278
+ }], context: [{
1279
+ type: Input
1280
+ }], group: [{
1281
+ type: Input
1282
+ }], hostClass: [{
1283
+ type: Input
1284
+ }], inputTemplateList: [{
1285
+ type: Input,
1286
+ args: ["templates"]
1287
+ }], layout: [{
1288
+ type: Input
1289
+ }], model: [{
1290
+ type: Input
1291
+ }], blur: [{
1292
+ type: Output
1293
+ }], change: [{
1294
+ type: Output
1295
+ }], focus: [{
1296
+ type: Output
1297
+ }], componentViewContainerRef: [{
1298
+ type: ViewChild,
1299
+ args: ["componentViewContainer", {
1300
+ read: ViewContainerRef,
1301
+ static: true
1302
+ }]
1303
+ }] } });
1304
+
1054
1305
  class DynamicBaseFormArrayComponent extends DynamicFormArrayComponent {
1055
- constructor(layoutService, validationService, injector) {
1306
+ constructor(layoutService, validationService, form, injector, cdr) {
1056
1307
  super(layoutService, validationService);
1057
- this.layoutService = layoutService;
1058
- this.validationService = validationService;
1308
+ this.form = form;
1059
1309
  this.injector = injector;
1310
+ this.cdr = cdr;
1060
1311
  this.blur = new EventEmitter();
1061
1312
  this.change = new EventEmitter();
1062
1313
  this.customEvent = new EventEmitter();
@@ -1066,14 +1317,24 @@ class DynamicBaseFormArrayComponent extends DynamicFormArrayComponent {
1066
1317
  var _a;
1067
1318
  return (_a = this.model) === null || _a === void 0 ? void 0 : _a.useTabs;
1068
1319
  }
1320
+ initialize(cdr) {
1321
+ this.subscription = this.model.filteredGroups.subscribe(filteredGroups => {
1322
+ this.updateGroups(filteredGroups);
1323
+ });
1324
+ this.model.initialize(this.array);
1325
+ }
1326
+ ngOnDestroy() {
1327
+ if (this.subscription)
1328
+ this.subscription.unsubscribe();
1329
+ }
1069
1330
  saveTab(index) {
1070
- this.model.saveTab(index, this.model, this.injector);
1331
+ this.model.saveTab(index, this.model.getFiltered(index), this.model, this.injector);
1071
1332
  }
1072
1333
  restoreTab() {
1073
1334
  return this.model.restoreTab(this.model, this.injector);
1074
1335
  }
1075
- getTabLabel(index) {
1076
- return this.model.getTabLabel(index, this.model, this.array, this.injector);
1336
+ getTabLabel(index, model) {
1337
+ return this.model.getTabLabel(index, model, this.model, this.array, this.injector);
1077
1338
  }
1078
1339
  getClass(context, place, model) {
1079
1340
  var _a;
@@ -1103,9 +1364,13 @@ class DynamicBaseFormArrayComponent extends DynamicFormArrayComponent {
1103
1364
  }
1104
1365
  return null;
1105
1366
  }
1367
+ updateGroups(filteredGroups) {
1368
+ this.cdr.detectChanges();
1369
+ this.components.forEach(t => t.cdr.detectChanges());
1370
+ }
1106
1371
  }
1107
- DynamicBaseFormArrayComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormArrayComponent, deps: [{ token: i1.DynamicFormLayoutService }, { token: i1.DynamicFormValidationService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
1108
- 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 DynamicFormControlContainerComponent; }), descendants: true }], usesInheritance: true, ngImport: i0, template: "", isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1372
+ 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 });
1373
+ 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 });
1109
1374
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormArrayComponent, decorators: [{
1110
1375
  type: Component,
1111
1376
  args: [{
@@ -1113,7 +1378,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImpor
1113
1378
  template: "",
1114
1379
  changeDetection: ChangeDetectionStrategy.OnPush
1115
1380
  }]
1116
- }], ctorParameters: function () { return [{ type: i1.DynamicFormLayoutService }, { type: i1.DynamicFormValidationService }, { type: i0.Injector }]; }, propDecorators: { formLayout: [{
1381
+ }], ctorParameters: function () { return [{ type: i1.DynamicFormLayoutService }, { type: i1.DynamicFormValidationService }, { type: DynamicBaseFormComponent }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { formLayout: [{
1117
1382
  type: Input
1118
1383
  }], group: [{
1119
1384
  type: Input
@@ -1133,18 +1398,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImpor
1133
1398
  type: Output
1134
1399
  }], components: [{
1135
1400
  type: ViewChildren,
1136
- args: [forwardRef(() => DynamicFormControlContainerComponent)]
1401
+ args: [forwardRef(() => DynamicBaseFormControlContainerComponent)]
1137
1402
  }] } });
1138
1403
 
1139
1404
  class DynamicBaseFormControlComponent extends DynamicFormControlComponent {
1140
- constructor(layoutService, validationService) {
1405
+ constructor(cdr, layoutService, validationService) {
1141
1406
  super(layoutService, validationService);
1407
+ this.cdr = cdr;
1142
1408
  this.blur = new EventEmitter();
1143
1409
  this.change = new EventEmitter();
1144
1410
  this.focus = new EventEmitter();
1145
1411
  }
1146
1412
  }
1147
- DynamicBaseFormControlComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormControlComponent, deps: [{ token: i1.DynamicFormLayoutService }, { token: i1.DynamicFormValidationService }], target: i0.ɵɵFactoryTarget.Component });
1413
+ DynamicBaseFormControlComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormControlComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.DynamicFormLayoutService }, { token: i1.DynamicFormValidationService }], target: i0.ɵɵFactoryTarget.Component });
1148
1414
  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 });
1149
1415
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormControlComponent, decorators: [{
1150
1416
  type: Component,
@@ -1153,112 +1419,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImpor
1153
1419
  template: "",
1154
1420
  changeDetection: ChangeDetectionStrategy.OnPush
1155
1421
  }]
1156
- }], ctorParameters: function () { return [{ type: i1.DynamicFormLayoutService }, { type: i1.DynamicFormValidationService }]; }, propDecorators: { formLayout: [{
1157
- type: Input
1158
- }], group: [{
1159
- type: Input
1160
- }], layout: [{
1161
- type: Input
1162
- }], model: [{
1163
- type: Input
1164
- }], blur: [{
1165
- type: Output
1166
- }], change: [{
1167
- type: Output
1168
- }], focus: [{
1169
- type: Output
1170
- }] } });
1171
-
1172
- class DynamicBaseFormControlContainerComponent extends DynamicFormControlContainerComponent {
1173
- constructor(form, changeDetectorRef, componentFactoryResolver, layoutService, validationService, componentService, relationService) {
1174
- super(changeDetectorRef, componentFactoryResolver, layoutService, validationService, componentService, relationService);
1175
- this.form = form;
1176
- this.changeDetectorRef = changeDetectorRef;
1177
- this.componentFactoryResolver = componentFactoryResolver;
1178
- this.layoutService = layoutService;
1179
- this.validationService = validationService;
1180
- this.componentService = componentService;
1181
- this.relationService = relationService;
1182
- this.context = null;
1183
- this.blur = new EventEmitter();
1184
- this.change = new EventEmitter();
1185
- this.focus = new EventEmitter();
1186
- }
1187
- get componentType() {
1188
- var _a;
1189
- return (_a = this.componentService.getCustomComponentType(this.model)) !== null && _a !== void 0 ? _a : this.getComponentType(this.model);
1190
- }
1191
- get startTemplate() {
1192
- return (this.model.type == DYNAMIC_FORM_CONTROL_TYPE_ARRAY)
1193
- ? this.layoutService.getAlignedTemplate(this.model, this.templates, "ARRAY_START")
1194
- : this.layoutService.getStartTemplate(this.model, this.templates);
1195
- }
1196
- get endTemplate() {
1197
- return (this.model.type == DYNAMIC_FORM_CONTROL_TYPE_ARRAY)
1198
- ? this.layoutService.getAlignedTemplate(this.model, this.templates, "ARRAY_END")
1199
- : this.layoutService.getEndTemplate(this.model, this.templates);
1200
- }
1201
- get formService() {
1202
- return this.form.formService;
1203
- }
1204
- ngOnInit() {
1205
- this.onDetectChanges = this.formService.onDetectChanges.subscribe(form => {
1206
- if (form !== this.form)
1207
- return;
1208
- this.changeDetectorRef.detectChanges();
1209
- this.formService.updateSelectOptions(this.model, this.control, this.form.model);
1210
- });
1211
- }
1212
- ngOnDestroy() {
1213
- super.ngOnDestroy();
1214
- this.onDetectChanges.unsubscribe();
1215
- }
1216
- getLabel() {
1217
- var _a;
1218
- const label = collectPathAble(this.model, p => p.label);
1219
- if (label.length == 0)
1220
- return "";
1221
- if ((_a = this.form) === null || _a === void 0 ? void 0 : _a.labelPrefix) {
1222
- label.unshift(this.form.labelPrefix);
1223
- }
1224
- return label.join(".");
1225
- }
1226
- createFormControlComponent() {
1227
- var _a;
1228
- super.createFormControlComponent();
1229
- const component = (_a = this.componentRef) === null || _a === void 0 ? void 0 : _a.instance;
1230
- if (!component || !ObjectUtils.isFunction(component.onCreated))
1231
- return;
1232
- component.onCreated();
1233
- }
1234
- getComponentType(model) {
1235
- return null;
1236
- }
1237
- }
1238
- DynamicBaseFormControlContainerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormControlContainerComponent, deps: [{ token: DynamicBaseFormComponent }, { token: i0.ChangeDetectorRef }, { token: i0.ComponentFactoryResolver }, { token: i1.DynamicFormLayoutService }, { token: i1.DynamicFormValidationService }, { token: i1.DynamicFormComponentService }, { token: i1.DynamicFormRelationService }], target: i0.ɵɵFactoryTarget.Component });
1239
- 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" } }, 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 });
1240
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DynamicBaseFormControlContainerComponent, decorators: [{
1241
- type: Component,
1242
- args: [{
1243
- selector: "dynamic-base-form-control",
1244
- template: "",
1245
- changeDetection: ChangeDetectionStrategy.OnPush
1246
- }]
1247
- }], ctorParameters: function () { return [{ type: DynamicBaseFormComponent }, { type: i0.ChangeDetectorRef }, { type: i0.ComponentFactoryResolver }, { type: i1.DynamicFormLayoutService }, { type: i1.DynamicFormValidationService }, { type: i1.DynamicFormComponentService }, { type: i1.DynamicFormRelationService }]; }, propDecorators: { contentTemplateList: [{
1248
- type: ContentChildren,
1249
- args: [DynamicTemplateDirective]
1250
- }], klass: [{
1251
- type: HostBinding,
1252
- args: ["class"]
1253
- }], context: [{
1422
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1.DynamicFormLayoutService }, { type: i1.DynamicFormValidationService }]; }, propDecorators: { formLayout: [{
1254
1423
  type: Input
1255
1424
  }], group: [{
1256
1425
  type: Input
1257
- }], hostClass: [{
1258
- type: Input
1259
- }], inputTemplateList: [{
1260
- type: Input,
1261
- args: ["templates"]
1262
1426
  }], layout: [{
1263
1427
  type: Input
1264
1428
  }], model: [{
@@ -1269,9 +1433,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImpor
1269
1433
  type: Output
1270
1434
  }], focus: [{
1271
1435
  type: Output
1272
- }], componentViewContainerRef: [{
1273
- type: ViewChild,
1274
- args: ["componentViewContainer", { read: ViewContainerRef, static: true }]
1275
1436
  }] } });
1276
1437
 
1277
1438
  class DynamicBaseFormGroupComponent extends DynamicFormGroupComponent {
@@ -1348,18 +1509,21 @@ class DynamicBaseSelectComponent extends DynamicBaseFormControlComponent {
1348
1509
  this.groups$ = new BehaviorSubject([]);
1349
1510
  this.subscription = this.model.options$.subscribe(options => {
1350
1511
  const groupBy = this.model.inline || !this.model.multiple ? this.model.groupBy : null;
1351
- const groups = options.reduce((res, option) => {
1512
+ const grouped = options.reduce((res, option) => {
1352
1513
  const key = replaceSpecialChars(groupBy ? option.props[this.model.groupBy] || "default" : "default", "-");
1353
1514
  res[key] = res[key] || [];
1354
1515
  res[key].push(option);
1355
1516
  return res;
1356
1517
  }, {});
1357
- this.groups$.next(Object.keys(groups).map(group => {
1518
+ const groups = Object.keys(grouped).map(group => {
1358
1519
  return {
1359
1520
  group,
1360
- options: groups[group]
1521
+ options: grouped[group]
1361
1522
  };
1362
- }));
1523
+ });
1524
+ this.hasOptions = groups.length > 0;
1525
+ this.groups$.next(groups);
1526
+ this.cdr.detectChanges();
1363
1527
  });
1364
1528
  }
1365
1529
  ngOnDestroy() {
@@ -1526,5 +1690,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImpor
1526
1690
  * Generated bundle index. Do not edit.
1527
1691
  */
1528
1692
 
1529
- export { AsyncSubmitDirective, DynamicBaseFormArrayComponent, DynamicBaseFormComponent, DynamicBaseFormControlComponent, DynamicBaseFormControlContainerComponent, DynamicBaseFormGroupComponent, DynamicBaseSelectComponent, DynamicFormArrayModel, DynamicFormOption, DynamicFormService, DynamicSelectModel, FormFile, FormInput, FormModel, FormSelect, FormSelectSubject, FormSerializable, FormStatic, FormSubject, MAX_INPUT_NUM, MIN_INPUT_NUM, NgxDynamicFormModule, createFormControl, createFormInput, createFormModel, createFormSelect, createFormStatic, defaultSerializer, defineFormControl, getFormControl, getFormSerializer, mergeFormModels, replaceSpecialChars, validateItemsMaxLength, validateItemsMaxValue, validateItemsMinLength, validateItemsMinValue, validateJSON, validatePhone, validateRequiredTranslation };
1693
+ export { AsyncSubmitDirective, DynamicBaseFormArrayComponent, DynamicBaseFormComponent, DynamicBaseFormControlComponent, DynamicBaseFormControlContainerComponent, DynamicBaseFormGroupComponent, DynamicBaseSelectComponent, DynamicFormArrayGroupModel, DynamicFormArrayModel, DynamicFormOption, DynamicFormService, DynamicSelectModel, FormFile, FormInput, FormModel, FormSelect, FormSelectSubject, FormSerializable, FormStatic, FormSubject, MAX_INPUT_NUM, MIN_INPUT_NUM, NgxDynamicFormModule, createFormControl, createFormInput, createFormModel, createFormSelect, createFormStatic, defaultSerializer, defineFormControl, getFormControl, getFormSerializer, mergeFormModels, replaceSpecialChars, validateItemsMaxLength, validateItemsMaxValue, validateItemsMinLength, validateItemsMinValue, validateJSON, validatePhone, validateRequiredTranslation };
1530
1694
  //# sourceMappingURL=stemy-ngx-dynamic-form.mjs.map