@tft/crispr-forms 13.0.17 → 13.0.20

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.
@@ -1160,10 +1160,6 @@ class ImageUploadFieldComponent extends ImageUploadFieldMixin {
1160
1160
  minCompressionThresholdMb: .6,
1161
1161
  useWebWorker: true,
1162
1162
  };
1163
- /**
1164
- * The url mapped from initial input value, consumers can us mapInputValueToUrl in config to transform their input value into a src url for the image element
1165
- */
1166
- // inputValueUrl: string | undefined;
1167
1163
  this.inputImageFileSubject = new Subject();
1168
1164
  this.inputImageFile$ = this.inputImageFileSubject.asObservable().pipe(shareReplay(1));
1169
1165
  this.compressedFile$ = this.inputImageFile$.pipe(switchMap(async (file) => {
@@ -1225,7 +1221,6 @@ class ImageUploadFieldComponent extends ImageUploadFieldMixin {
1225
1221
  }
1226
1222
  ngOnInit() {
1227
1223
  super.ngOnInit();
1228
- // this.inputValueUrl = this.value && this.config.mapInputValueToUrl?.(this.value) || this.value;
1229
1224
  this.imageSrcUrl$ = combineLatest([
1230
1225
  this.compressedImageUrlString$.pipe(startWith(null)),
1231
1226
  this.control.valueChanges.pipe(startWith(this.value), map((controlValue) => {
@@ -1357,6 +1352,26 @@ function allowedFileExtValidator(allowedFileExtensions, onlyAllowFiles = true) {
1357
1352
  }
1358
1353
  return { allowedExtension: { allowedFileExtensions, actualExtension } };
1359
1354
  };
1355
+ }
1356
+ function allowedFileType(matchExp) {
1357
+ return (formControl) => {
1358
+ const value = formControl.value;
1359
+ if (!(value instanceof File))
1360
+ return null;
1361
+ const type = value.type;
1362
+ const matches = type.match(matchExp);
1363
+ if (!type || !matches?.length) {
1364
+ return {
1365
+ allowedFileType: {
1366
+ actualType: type,
1367
+ allowedTypeExp: matchExp
1368
+ }
1369
+ };
1370
+ }
1371
+ else {
1372
+ return null;
1373
+ }
1374
+ };
1360
1375
  }
1361
1376
 
1362
1377
  // TODO: Should we import UI library?
@@ -1538,6 +1553,7 @@ var index$2 = /*#__PURE__*/Object.freeze({
1538
1553
  ImageUploadFieldModule: ImageUploadFieldModule,
1539
1554
  maxFileSizeValidator: maxFileSizeValidator,
1540
1555
  allowedFileExtValidator: allowedFileExtValidator,
1556
+ allowedFileType: allowedFileType,
1541
1557
  FileDropzoneDirective: FileDropzoneDirective,
1542
1558
  FileUploadFieldComponent: FileUploadFieldComponent,
1543
1559
  FileUploadFieldModule: FileUploadFieldModule,
@@ -1565,7 +1581,7 @@ const FIELD_COMPONENTS = {
1565
1581
  unitConversion: Promise.resolve().then(function () { return index$2; }).then(({ UnitConversionFieldComponent }) => UnitConversionFieldComponent)
1566
1582
  };
1567
1583
  function isControlComponent(component) {
1568
- return isControlConfig(component.config) && 'value' in component; // || component.config.controlType === ControlType.BUTTON;
1584
+ return component && isControlConfig(component.config) && 'value' in component; // || component.config.controlType === ControlType.BUTTON;
1569
1585
  }
1570
1586
  function isControlOrButtonComponent(component) {
1571
1587
  return isControlComponent(component) || component.config.controlType === ControlType.BUTTON;
@@ -1579,6 +1595,7 @@ class CrisprFieldDirective {
1579
1595
  }
1580
1596
  set value(value) {
1581
1597
  this._value = value;
1598
+ // This is needed to keep the group list from resetting control values to the initial input value
1582
1599
  this.updateComponentValue(value);
1583
1600
  }
1584
1601
  ;
@@ -1612,9 +1629,9 @@ class CrisprFieldDirective {
1612
1629
  });
1613
1630
  }
1614
1631
  updateComponentValue(value) {
1615
- if (this.component && isControlComponent(this.component)) {
1632
+ if (isControlComponent(this.component)) {
1616
1633
  this.component.value = value;
1617
- // SubGroups won't populate without this
1634
+ // SubGroups won't populate without this detectChanges
1618
1635
  this.cdr.detectChanges();
1619
1636
  }
1620
1637
  }
@@ -1725,6 +1742,11 @@ class FormGroupListComponent extends FormGroupListMixin {
1725
1742
  super();
1726
1743
  this.cdr = cdr;
1727
1744
  this.defaultConfig = defaultConfig;
1745
+ /**
1746
+ * By setting this to true when adding/removing items from array,
1747
+ * we can block original values from overwriting form values
1748
+ * */
1749
+ this.blockValue = false;
1728
1750
  }
1729
1751
  ngOnInit() {
1730
1752
  super.ngOnInit();
@@ -1749,6 +1771,14 @@ class FormGroupListComponent extends FormGroupListMixin {
1749
1771
  });
1750
1772
  }
1751
1773
  }
1774
+ clickDelete(index) {
1775
+ this.blockValue = true;
1776
+ this.deleteGroup(index);
1777
+ }
1778
+ clickAdd() {
1779
+ this.blockValue = true;
1780
+ this.addGroup();
1781
+ }
1752
1782
  addGroup(value = null) {
1753
1783
  this.control.push(createControlForType(this.config.itemConfig, value));
1754
1784
  // needed to ensure new array items render
@@ -1761,10 +1791,10 @@ class FormGroupListComponent extends FormGroupListMixin {
1761
1791
  }
1762
1792
  }
1763
1793
  FormGroupListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FormGroupListComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1764
- FormGroupListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: FormGroupListComponent, selector: "crispr-form-group-list", usesInheritance: true, ngImport: i0, template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\"\n [formGroup]=\"group\">\n\n <div [formArrayName]=\"config.controlName\">\n <!-- Don't add trackBy function, it confuses the state of the array -->\n <div *ngFor=\"let control of control?.controls; let i = index\">\n <!-- TODO: use content projection to allow custom item label component -->\n <div class=\"item-header\">\n <span class=\"mat-h2\"> {{ config.itemLabelBuilder ? config.itemLabelBuilder(i) : 'Item ' + (i + 1) }} </span>\n <button\n mat-icon-button\n type=\"button\"\n *ngIf=\"i + 1 > config.minListLength\">\n <mat-icon (click)=\"deleteGroup(i)\">delete</mat-icon>\n </button>\n </div>\n <div\n [formGroupName]=\"i\">\n <ng-container\n *ngFor=\"let field of config.itemConfig.fields;\"\n crisprField\n [config]=\"field\"\n [value]=\"control.value | initialControlValue : field\"\n [group]=\"control\">\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"group-footer\">\n <button\n type=\"button\"\n class=\"add\"\n mat-raised-button\n [color]=\"config.addButtonColor\"\n (click)=\"addGroup()\">\n {{config.addItemLabel || config.addButtonLabel}}\n </button>\n </div>\n\n</crispr-field-container>\n", styles: [".item-header{display:flex;justify-content:space-between}.group-footer{display:flex;justify-content:flex-end}.group-footer button.add{margin-bottom:16px}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i1.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i4$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "value"] }], pipes: { "initialControlValue": InitialControlValuePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
1794
+ FormGroupListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: FormGroupListComponent, selector: "crispr-form-group-list", usesInheritance: true, ngImport: i0, template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\"\n [formGroup]=\"group\">\n\n <div [formArrayName]=\"config.controlName\">\n <!-- Don't add trackBy function, it confuses the state of the array -->\n <div *ngFor=\"let con of control?.controls; let i = index;\">\n <!-- TODO: use content projection to allow custom item label component -->\n <div class=\"item-header\">\n <span class=\"mat-h2\"> {{ config.itemLabelBuilder ? config.itemLabelBuilder(i) : 'Item ' + (i + 1) }} </span>\n <button\n mat-icon-button\n type=\"button\"\n *ngIf=\"i + 1 > config.minListLength\">\n <mat-icon (click)=\"clickDelete(i)\">delete</mat-icon>\n </button>\n </div>\n <div\n [formGroup]=\"con\">\n <!-- TODO: if chiplists didn't need to have labels mixed in with their values we could use [value]=\"control.value\" below -->\n <ng-container\n *ngFor=\"let field of config.itemConfig.fields;\"\n crisprField\n [value]=\"blockValue ? null : value && value[i] | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"con\">\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"group-footer\">\n <button\n type=\"button\"\n class=\"add\"\n mat-raised-button\n [color]=\"config.addButtonColor\"\n (click)=\"clickAdd()\">\n {{config.addItemLabel || config.addButtonLabel}}\n </button>\n </div>\n\n</crispr-field-container>\n", styles: [".item-header{display:flex;justify-content:space-between}.group-footer{display:flex;justify-content:flex-end}.group-footer button.add{margin-bottom:16px}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i1.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i4$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "value"] }], pipes: { "initialControlValue": InitialControlValuePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
1765
1795
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FormGroupListComponent, decorators: [{
1766
1796
  type: Component,
1767
- args: [{ selector: 'crispr-form-group-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\"\n [formGroup]=\"group\">\n\n <div [formArrayName]=\"config.controlName\">\n <!-- Don't add trackBy function, it confuses the state of the array -->\n <div *ngFor=\"let control of control?.controls; let i = index\">\n <!-- TODO: use content projection to allow custom item label component -->\n <div class=\"item-header\">\n <span class=\"mat-h2\"> {{ config.itemLabelBuilder ? config.itemLabelBuilder(i) : 'Item ' + (i + 1) }} </span>\n <button\n mat-icon-button\n type=\"button\"\n *ngIf=\"i + 1 > config.minListLength\">\n <mat-icon (click)=\"deleteGroup(i)\">delete</mat-icon>\n </button>\n </div>\n <div\n [formGroupName]=\"i\">\n <ng-container\n *ngFor=\"let field of config.itemConfig.fields;\"\n crisprField\n [config]=\"field\"\n [value]=\"control.value | initialControlValue : field\"\n [group]=\"control\">\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"group-footer\">\n <button\n type=\"button\"\n class=\"add\"\n mat-raised-button\n [color]=\"config.addButtonColor\"\n (click)=\"addGroup()\">\n {{config.addItemLabel || config.addButtonLabel}}\n </button>\n </div>\n\n</crispr-field-container>\n", styles: [".item-header{display:flex;justify-content:space-between}.group-footer{display:flex;justify-content:flex-end}.group-footer button.add{margin-bottom:16px}\n"] }]
1797
+ args: [{ selector: 'crispr-form-group-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\"\n [formGroup]=\"group\">\n\n <div [formArrayName]=\"config.controlName\">\n <!-- Don't add trackBy function, it confuses the state of the array -->\n <div *ngFor=\"let con of control?.controls; let i = index;\">\n <!-- TODO: use content projection to allow custom item label component -->\n <div class=\"item-header\">\n <span class=\"mat-h2\"> {{ config.itemLabelBuilder ? config.itemLabelBuilder(i) : 'Item ' + (i + 1) }} </span>\n <button\n mat-icon-button\n type=\"button\"\n *ngIf=\"i + 1 > config.minListLength\">\n <mat-icon (click)=\"clickDelete(i)\">delete</mat-icon>\n </button>\n </div>\n <div\n [formGroup]=\"con\">\n <!-- TODO: if chiplists didn't need to have labels mixed in with their values we could use [value]=\"control.value\" below -->\n <ng-container\n *ngFor=\"let field of config.itemConfig.fields;\"\n crisprField\n [value]=\"blockValue ? null : value && value[i] | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"con\">\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"group-footer\">\n <button\n type=\"button\"\n class=\"add\"\n mat-raised-button\n [color]=\"config.addButtonColor\"\n (click)=\"clickAdd()\">\n {{config.addItemLabel || config.addButtonLabel}}\n </button>\n </div>\n\n</crispr-field-container>\n", styles: [".item-header{display:flex;justify-content:space-between}.group-footer{display:flex;justify-content:flex-end}.group-footer button.add{margin-bottom:16px}\n"] }]
1768
1798
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; } });
1769
1799
 
1770
1800
  class CrisprPipesModule {
@@ -1845,10 +1875,10 @@ class SubGroupComponent extends FormGroupMixin {
1845
1875
  }
1846
1876
  }
1847
1877
  SubGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SubGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1848
- SubGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: SubGroupComponent, selector: "crispr-sub-group", usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <ng-container\n *ngFor=\"let fieldConfig of config.fields;\"\n crisprField\n [value]=\"value | initialControlValue : fieldConfig\"\n [config]=\"fieldConfig\"\n [group]=\"control\">\n </ng-container>\n</crispr-field-container>\n\n", styles: [""], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "value"] }], pipes: { "initialControlValue": InitialControlValuePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
1878
+ SubGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: SubGroupComponent, selector: "crispr-sub-group", usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <ng-container\n *ngFor=\"let fieldConfig of config.fields;\"\n crisprField\n [value]=\"value | initialControlValue : fieldConfig\"\n [config]=\"fieldConfig\"\n [group]=\"control\">\n </ng-container>\n</crispr-field-container>\n\n", styles: [""], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "value"] }], pipes: { "initialControlValue": InitialControlValuePipe }, preserveWhitespaces: true });
1849
1879
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SubGroupComponent, decorators: [{
1850
1880
  type: Component,
1851
- args: [{ selector: 'crispr-sub-group', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <ng-container\n *ngFor=\"let fieldConfig of config.fields;\"\n crisprField\n [value]=\"value | initialControlValue : fieldConfig\"\n [config]=\"fieldConfig\"\n [group]=\"control\">\n </ng-container>\n</crispr-field-container>\n\n", styles: [""] }]
1881
+ args: [{ selector: 'crispr-sub-group', template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <ng-container\n *ngFor=\"let fieldConfig of config.fields;\"\n crisprField\n [value]=\"value | initialControlValue : fieldConfig\"\n [config]=\"fieldConfig\"\n [group]=\"control\">\n </ng-container>\n</crispr-field-container>\n\n", styles: [""] }]
1852
1882
  }] });
1853
1883
 
1854
1884
  class SubGroupModule {
@@ -1949,5 +1979,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImpor
1949
1979
  * Generated bundle index. Do not edit.
1950
1980
  */
1951
1981
 
1952
- export { AbstractAutocompleteComponent, AutocompleteChiplistFieldComponent, AutocompleteFieldComponent, ButtonComponent, CheckboxFieldComponent, ControlType, CrisprFieldComponent, CrisprFormComponent, CrisprFormsModule, DEFAULT_EMPTY_OPTIONS_MESSAGE, DatepickerFieldComponent, DividerComponent, FieldContainerComponent, FieldContainerModule, FileDropzoneDirective, FileUploadFieldComponent, FileUploadFieldModule, HeadingComponent, HeadingModule, ImageUploadFieldComponent, ImageUploadFieldModule, InputFieldComponent, MaterialModule, OptionComponent, RadioFieldComponent, SelectFieldComponent, SliderFieldComponent, TextareaFieldComponent, UnitConversionFieldComponent, allowedFileExtValidator, buildFormGroupFromConfig, callOptionsIfFunction, checkControlForValues, checkControlsForValues, computeValueFromFields, createControlForType, crisprControlMixin, filterOptionsByLabel, isControlConfig, maxFileSizeValidator, observablifyOptions };
1982
+ export { AbstractAutocompleteComponent, AutocompleteChiplistFieldComponent, AutocompleteFieldComponent, ButtonComponent, CheckboxFieldComponent, ControlType, CrisprFieldComponent, CrisprFormComponent, CrisprFormsModule, DEFAULT_EMPTY_OPTIONS_MESSAGE, DatepickerFieldComponent, DividerComponent, FieldContainerComponent, FieldContainerModule, FileDropzoneDirective, FileUploadFieldComponent, FileUploadFieldModule, HeadingComponent, HeadingModule, ImageUploadFieldComponent, ImageUploadFieldModule, InputFieldComponent, MaterialModule, OptionComponent, RadioFieldComponent, SelectFieldComponent, SliderFieldComponent, TextareaFieldComponent, UnitConversionFieldComponent, allowedFileExtValidator, allowedFileType, buildFormGroupFromConfig, callOptionsIfFunction, checkControlForValues, checkControlsForValues, computeValueFromFields, createControlForType, crisprControlMixin, filterOptionsByLabel, isControlConfig, maxFileSizeValidator, observablifyOptions };
1953
1983
  //# sourceMappingURL=tft-crispr-forms.mjs.map