UNPKG

@igo2/common

Version:
819 lines (803 loc) 56 kB
import * as i0 from '@angular/core'; import { EventEmitter, ViewChild, Output, Input, ChangeDetectionStrategy, Component, NgModule, Injectable, ChangeDetectorRef, Inject } from '@angular/core'; import { NgClass, NgFor, NgIf, AsyncPipe } from '@angular/common'; import * as i3 from '@angular/forms'; import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { t } from 'typy'; import { __decorate, __metadata } from 'tslib'; import { MatOptionModule } from '@angular/material/core'; import * as i1 from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field'; import * as i4 from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon'; import * as i2 from '@angular/material/select'; import { MatSelectModule } from '@angular/material/select'; import * as i1$1 from '@igo2/core/language'; import { IgoLanguageModule } from '@igo2/core/language'; import { BehaviorSubject } from 'rxjs'; import * as i5 from '@ngx-translate/core'; import * as i5$1 from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button'; import * as i2$1 from '@angular/material/input'; import { MatInputModule } from '@angular/material/input'; import { DynamicOutletComponent } from '@igo2/common/dynamic-component'; import * as i2$2 from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogTitle, MatDialogActions, MatDialogModule } from '@angular/material/dialog'; import { CustomHtmlComponent } from '@igo2/common/custom-html'; function formControlIsRequired(control) { if (control.validator) { const validator = control.validator({}); if (validator && validator.required) { return true; } } if (control.controls) { const requiredControl = Object.keys(control.controls).find((key) => { return formControlIsRequired(control.controls[key]); }); return requiredControl !== undefined; } return false; } function getDefaultErrorMessages() { return { required: 'igo.common.form.errors.required', email: 'igo.common.form.errors.email' }; } function getControlErrorMessage(control, messages) { const errors = control.errors || {}; const errorKeys = Object.keys(errors); const errorMessages = errorKeys .map((key) => messages[key]) .filter((message) => message !== undefined); return errorMessages.length > 0 ? errorMessages[0] : ''; } function getAllFormFields(form) { return form.groups.reduce((acc, group) => { return acc.concat(group.fields); }, [].concat(form.fields)); } function getFormFieldByName(form, name) { const fields = getAllFormFields(form); return fields.find((field) => { return field.name === name; }); } /** * A configurable form */ class FormComponent { /** * Form */ form; /** * Input data */ formData; /** * Form autocomplete */ autocomplete = 'off'; /** * Event emitted when the form is submitted */ submitForm = new EventEmitter(); buttons; get hasButtons() { return this.buttons.nativeElement.children.length !== 0; } /** * Is the entity or the template change, recreate the form or repopulate it. * @internal */ ngOnChanges(changes) { const formData = changes.formData; if (formData.firstChange && formData.currentValue == null) { return; } if (formData && formData.currentValue !== formData.previousValue) { if (formData.currentValue === undefined) { this.clear(); } else { this.setData(formData.currentValue); } } } /** * Transform the form data to a feature and emit an event * @param event Form submit event * @internal */ onSubmit() { this.submitForm.emit(this.getData()); } getData() { const data = {}; getAllFormFields(this.form).forEach((field) => { this.updateDataWithFormField(data, field); }); return data; } setData(data) { this.form.fields.forEach((field) => { field.control.setValue(t(data, field.name).safeObject); }); this.form.groups.forEach((group) => { group.fields.forEach((field) => { field.control.setValue(t(data, field.name).safeObject); }); }); } updateDataWithFormField(data, field) { const control = field.control; if (!control.disabled) { data[field.name] = control.value; } } /** * Clear form */ clear() { this.form.control.reset(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: FormComponent, isStandalone: true, selector: "igo-form", inputs: { form: "form", formData: "formData", autocomplete: "autocomplete" }, outputs: { submitForm: "submitForm" }, viewQueries: [{ propertyName: "buttons", first: true, predicate: ["buttons"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<form\n [autocomplete]=\"autocomplete\"\n [formGroup]=\"form.control\"\n (ngSubmit)=\"onSubmit()\"\n>\n <div\n class=\"igo-form-body\"\n [ngClass]=\"{ 'igo-form-body-with-buttons': hasButtons }\"\n >\n <div class=\"igo-form-content\">\n <ng-content></ng-content>\n </div>\n <div #buttons class=\"igo-form-buttons\">\n <ng-content select=\"[formButtons]\"></ng-content>\n </div>\n </div>\n</form>\n", styles: [":host{display:block}form{width:100%;height:100%}.igo-form-body,.igo-form-content{height:100%}.igo-form-body-with-buttons .igo-form-content{height:calc(100% - 56px)}.igo-form-content{display:flex}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormComponent, decorators: [{ type: Component, args: [{ selector: 'igo-form', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, ReactiveFormsModule, NgClass], template: "<form\n [autocomplete]=\"autocomplete\"\n [formGroup]=\"form.control\"\n (ngSubmit)=\"onSubmit()\"\n>\n <div\n class=\"igo-form-body\"\n [ngClass]=\"{ 'igo-form-body-with-buttons': hasButtons }\"\n >\n <div class=\"igo-form-content\">\n <ng-content></ng-content>\n </div>\n <div #buttons class=\"igo-form-buttons\">\n <ng-content select=\"[formButtons]\"></ng-content>\n </div>\n </div>\n</form>\n", styles: [":host{display:block}form{width:100%;height:100%}.igo-form-body,.igo-form-content{height:100%}.igo-form-body-with-buttons .igo-form-content{height:calc(100% - 56px)}.igo-form-content{display:flex}\n"] }] }], propDecorators: { form: [{ type: Input }], formData: [{ type: Input }], autocomplete: [{ type: Input }], submitForm: [{ type: Output }], buttons: [{ type: ViewChild, args: ['buttons', { static: true }] }] } }); /** * @deprecated import the FormComponent directly */ class IgoFormFormModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoFormFormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.15", ngImport: i0, type: IgoFormFormModule, imports: [FormComponent], exports: [FormComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoFormFormModule, imports: [FormComponent] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoFormFormModule, decorators: [{ type: NgModule, args: [{ imports: [FormComponent], exports: [FormComponent] }] }] }); /** * Service where all available form fields are registered. */ class FormFieldService { static fields = {}; static register(type, component) { FormFieldService.fields[type] = component; } /** * Return field component by type * @param type Field type * @returns Field component */ getFieldByType(type) { return FormFieldService.fields[type]; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormFieldService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormFieldService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormFieldService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); function IgoFormFieldComponent(type) { return (compType) => { FormFieldService.register(type, compType); }; } /** * This component renders a select field */ let FormFieldSelectComponent = class FormFieldSelectComponent { disabled$ = new BehaviorSubject(false); /** * Select input choices */ set choices(value) { this.choices$.next(value); } get choices() { return this.choices$.value; } choices$ = new BehaviorSubject([]); /** * If the select allow multiple selections */ multiple = false; /** * The field's form control */ formControl; /** * Field placeholder */ placeholder; /** * Field placeholder */ errors; /** * Wheter a disable switch should be available */ disableSwitch = false; /** * Whether the field is required */ get required() { return formControlIsRequired(this.formControl); } ngOnInit() { this.disabled$.next(this.formControl.disabled); } /** * Get error message */ getErrorMessage() { return getControlErrorMessage(this.formControl, this.errors); } onDisableSwitchClick() { this.toggleDisabled(); } toggleDisabled() { const disabled = !this.disabled$.value; if (disabled === true) { this.formControl.disable(); } else { this.formControl.enable(); } this.disabled$.next(disabled); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormFieldSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: FormFieldSelectComponent, isStandalone: true, selector: "igo-form-field-select", inputs: { choices: "choices", multiple: "multiple", formControl: "formControl", placeholder: "placeholder", errors: "errors", disableSwitch: "disableSwitch" }, ngImport: i0, template: "<mat-form-field>\n <mat-select\n [multiple]=\"multiple\"\n [required]=\"required\"\n [placeholder]=\"placeholder | translate\"\n [formControl]=\"formControl\"\n >\n <mat-option *ngFor=\"let choice of choices$ | async\" [value]=\"choice.value\">\n {{ choice.title }}\n </mat-option>\n </mat-select>\n <mat-icon\n *ngIf=\"disableSwitch === true\"\n class=\"igo-form-disable-switch\"\n (click)=\"onDisableSwitchClick()\"\n matPrefix\n >{{\n (disabled$ | async) === true ? 'check_box_outline_blank' : 'check_box'\n }}\n </mat-icon>\n <mat-error *ngIf=\"formControl.errors\">{{\n getErrorMessage() | translate\n }}</mat-error>\n</mat-form-field>\n", dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }; FormFieldSelectComponent = __decorate([ IgoFormFieldComponent('select') ], FormFieldSelectComponent); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormFieldSelectComponent, decorators: [{ type: Component, args: [{ selector: 'igo-form-field-select', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ MatFormFieldModule, MatSelectModule, FormsModule, ReactiveFormsModule, NgFor, MatOptionModule, NgIf, MatIconModule, AsyncPipe, IgoLanguageModule ], template: "<mat-form-field>\n <mat-select\n [multiple]=\"multiple\"\n [required]=\"required\"\n [placeholder]=\"placeholder | translate\"\n [formControl]=\"formControl\"\n >\n <mat-option *ngFor=\"let choice of choices$ | async\" [value]=\"choice.value\">\n {{ choice.title }}\n </mat-option>\n </mat-select>\n <mat-icon\n *ngIf=\"disableSwitch === true\"\n class=\"igo-form-disable-switch\"\n (click)=\"onDisableSwitchClick()\"\n matPrefix\n >{{\n (disabled$ | async) === true ? 'check_box_outline_blank' : 'check_box'\n }}\n </mat-icon>\n <mat-error *ngIf=\"formControl.errors\">{{\n getErrorMessage() | translate\n }}</mat-error>\n</mat-form-field>\n" }] }], propDecorators: { choices: [{ type: Input }], multiple: [{ type: Input }], formControl: [{ type: Input }], placeholder: [{ type: Input }], errors: [{ type: Input }], disableSwitch: [{ type: Input }] } }); /** * This component renders a text field */ let FormFieldTextComponent = class FormFieldTextComponent { cdRef; disabled$ = new BehaviorSubject(false); hide = true; lastTimeoutRequest; /** * The field's form control */ formControl; /** * Field placeholder */ placeholder; /** * if the input is a password */ isPassword; /** * Field placeholder */ errors; /** * Wheter a disable switch should be available */ disableSwitch = false; /** * Whether the field is required */ get required() { return formControlIsRequired(this.formControl); } constructor(cdRef) { this.cdRef = cdRef; } ngOnInit() { this.disabled$.next(this.formControl.disabled); } /** * Get error message */ getErrorMessage() { return getControlErrorMessage(this.formControl, this.errors); } onDisableSwitchClick() { this.toggleDisabled(); } toggleDisabled() { const disabled = !this.disabled$.value; if (disabled === true) { this.formControl.disable(); } else { this.formControl.enable(); } this.disabled$.next(disabled); } togglePassword() { this.hide = !this.hide; this.delayedHide(); } delayedHide(delayMS = 10000) { if (this.isPassword && !this.hide) { if (this.lastTimeoutRequest) { clearTimeout(this.lastTimeoutRequest); } this.lastTimeoutRequest = setTimeout(() => { this.hide = true; this.cdRef.detectChanges(); }, delayMS); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormFieldTextComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: FormFieldTextComponent, isStandalone: true, selector: "igo-form-field-text", inputs: { formControl: "formControl", placeholder: "placeholder", isPassword: "isPassword", errors: "errors", disableSwitch: "disableSwitch" }, ngImport: i0, template: "<mat-form-field>\n <input\n matInput\n (blur)=\"delayedHide(0)\"\n [type]=\"isPassword ? (hide ? 'password' : 'text') : 'text'\"\n [required]=\"isPassword ? 'true' : required\"\n [placeholder]=\"placeholder | translate\"\n [formControl]=\"formControl\"\n (change)=\"delayedHide()\"\n />\n <mat-icon\n *ngIf=\"disableSwitch === true\"\n class=\"igo-form-disable-switch\"\n (click)=\"onDisableSwitchClick()\"\n matPrefix\n >{{\n (disabled$ | async) === true ? 'check_box_outline_blank' : 'check_box'\n }}\n </mat-icon>\n\n <button\n type=\"button\"\n *ngIf=\"isPassword\"\n matSuffix\n mat-icon-button\n (click)=\"togglePassword()\"\n >\n <mat-icon color=\"primary\">{{\n hide ? 'visibility_off' : 'visibility'\n }}</mat-icon>\n </button>\n\n <mat-error *ngIf=\"formControl.errors\">{{\n getErrorMessage() | translate\n }}</mat-error>\n</mat-form-field>\n", dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i5$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }; FormFieldTextComponent = __decorate([ IgoFormFieldComponent('text'), __metadata("design:paramtypes", [ChangeDetectorRef]) ], FormFieldTextComponent); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormFieldTextComponent, decorators: [{ type: Component, args: [{ selector: 'igo-form-field-text', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule, NgIf, MatIconModule, MatButtonModule, AsyncPipe, IgoLanguageModule ], template: "<mat-form-field>\n <input\n matInput\n (blur)=\"delayedHide(0)\"\n [type]=\"isPassword ? (hide ? 'password' : 'text') : 'text'\"\n [required]=\"isPassword ? 'true' : required\"\n [placeholder]=\"placeholder | translate\"\n [formControl]=\"formControl\"\n (change)=\"delayedHide()\"\n />\n <mat-icon\n *ngIf=\"disableSwitch === true\"\n class=\"igo-form-disable-switch\"\n (click)=\"onDisableSwitchClick()\"\n matPrefix\n >{{\n (disabled$ | async) === true ? 'check_box_outline_blank' : 'check_box'\n }}\n </mat-icon>\n\n <button\n type=\"button\"\n *ngIf=\"isPassword\"\n matSuffix\n mat-icon-button\n (click)=\"togglePassword()\"\n >\n <mat-icon color=\"primary\">{{\n hide ? 'visibility_off' : 'visibility'\n }}</mat-icon>\n </button>\n\n <mat-error *ngIf=\"formControl.errors\">{{\n getErrorMessage() | translate\n }}</mat-error>\n</mat-form-field>\n" }] }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { formControl: [{ type: Input }], placeholder: [{ type: Input }], isPassword: [{ type: Input }], errors: [{ type: Input }], disableSwitch: [{ type: Input }] } }); /** * This component renders a textarea field */ let FormFieldTextareaComponent = class FormFieldTextareaComponent { disabled$ = new BehaviorSubject(false); /** * The field's form control */ formControl; /** * Field placeholder */ placeholder; /** * Field placeholder */ errors; /** * Wheter a disable switch should be available */ disableSwitch = false; /** * Whether the field is required */ get required() { return formControlIsRequired(this.formControl); } ngOnInit() { this.disabled$.next(this.formControl.disabled); } /** * Get error message */ getErrorMessage() { return getControlErrorMessage(this.formControl, this.errors); } onDisableSwitchClick() { this.toggleDisabled(); } toggleDisabled() { const disabled = !this.disabled$.value; if (disabled === true) { this.formControl.disable(); } else { this.formControl.enable(); } this.disabled$.next(disabled); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormFieldTextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: FormFieldTextareaComponent, isStandalone: true, selector: "igo-form-field-textarea", inputs: { formControl: "formControl", placeholder: "placeholder", errors: "errors", disableSwitch: "disableSwitch" }, ngImport: i0, template: "<mat-form-field>\n <textarea\n matInput\n [required]=\"required\"\n [placeholder]=\"placeholder | translate\"\n [formControl]=\"formControl\"\n >\n </textarea>\n <mat-icon\n *ngIf=\"disableSwitch === true\"\n class=\"igo-form-disable-switch\"\n (click)=\"onDisableSwitchClick()\"\n matPrefix\n >{{\n (disabled$ | async) === true ? 'check_box_outline_blank' : 'check_box'\n }}\n </mat-icon>\n <mat-error *ngIf=\"formControl.errors\">{{\n getErrorMessage() | translate\n }}</mat-error>\n</mat-form-field>\n", dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }; FormFieldTextareaComponent = __decorate([ IgoFormFieldComponent('textarea') ], FormFieldTextareaComponent); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormFieldTextareaComponent, decorators: [{ type: Component, args: [{ selector: 'igo-form-field-textarea', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule, NgIf, MatIconModule, AsyncPipe, IgoLanguageModule ], template: "<mat-form-field>\n <textarea\n matInput\n [required]=\"required\"\n [placeholder]=\"placeholder | translate\"\n [formControl]=\"formControl\"\n >\n </textarea>\n <mat-icon\n *ngIf=\"disableSwitch === true\"\n class=\"igo-form-disable-switch\"\n (click)=\"onDisableSwitchClick()\"\n matPrefix\n >{{\n (disabled$ | async) === true ? 'check_box_outline_blank' : 'check_box'\n }}\n </mat-icon>\n <mat-error *ngIf=\"formControl.errors\">{{\n getErrorMessage() | translate\n }}</mat-error>\n</mat-form-field>\n" }] }], propDecorators: { formControl: [{ type: Input }], placeholder: [{ type: Input }], errors: [{ type: Input }], disableSwitch: [{ type: Input }] } }); class FormService { formBuilder; constructor(formBuilder) { this.formBuilder = formBuilder; } form(fields, groups) { const control = this.formBuilder.group({}); fields.forEach((field) => { control.addControl(field.name, field.control); }); groups.forEach((group) => { control.addControl(group.name, group.control); }); return { fields, groups, control }; } group(config, fields) { const options = config.options || {}; const control = this.formBuilder.group({}); fields.forEach((field) => { control.addControl(field.name, field.control); }); if (options.validator) { const validators = this.getValidators(options.validator); // convert string to actual validator control.setValidators(validators); } return Object.assign({}, config, { fields, control }); } field(config) { const options = config.options || {}; const state = { value: options.initialValue ?? '', disabled: options.disabled }; const control = this.formBuilder.control(state); if (options.validator) { const validators = this.getValidators(options.validator); // convert string to actual validator control.setValidators(validators); } return Object.assign({ type: 'text' }, config, { control }); } extendFieldConfig(config, partial) { const options = Object.assign({}, config.options || {}, partial.options || {}); const inputs = Object.assign({}, config.inputs || {}, partial.inputs || {}); const subscribers = Object.assign({}, config.subscribers || {}, partial.subscribers || {}); return Object.assign({}, config, { options, inputs, subscribers }); } getValidators(validatorOption) { if (Array.isArray(validatorOption)) { return validatorOption.map((validatorStr) => { return this.getValidator(validatorStr); }); } return this.getValidator(validatorOption); } getValidator(validatorStr) { if (typeof validatorStr !== 'string') { return validatorStr; } // regex pattern to extract arguments from string for e.g applying on "minLength(8)" would extract 8 const re = /^([a-zA-Z]{3,15})\((.{0,20})\)$/; const match = validatorStr.match(re); if (!match) { return Validators[validatorStr]; } const name = match[1]; const args = match[2]; return Validators[name](args); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormService, deps: [{ token: i3.UntypedFormBuilder }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i3.UntypedFormBuilder }] }); /** * This component renders the proper form input based on * the field configuration it receives. */ class FormFieldComponent { formFieldService; /** * Field configuration */ field; /** * Field inputs cache */ fieldInputs = undefined; /** * Field subscribers cache */ fieldSubscribers = undefined; get fieldOptions() { return this.field.options || {}; } constructor(formFieldService) { this.formFieldService = formFieldService; } getFieldComponent() { return this.formFieldService.getFieldByType(this.field.type || 'text'); } getFieldInputs() { if (this.fieldInputs !== undefined) { return this.fieldInputs; } const errors = this.fieldOptions.errors || {}; this.fieldInputs = Object.assign({ placeholder: this.field.title, disableSwitch: this.fieldOptions.disableSwitch || false }, Object.assign({}, this.field.inputs || {}), { formControl: this.field.control, errors: Object.assign({}, getDefaultErrorMessages(), errors) }); return this.fieldInputs; } getFieldSubscribers() { if (this.fieldSubscribers !== undefined) { return this.fieldSubscribers; } this.fieldSubscribers = Object.assign({}, this.field.subscribers || {}); return this.fieldSubscribers; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormFieldComponent, deps: [{ token: FormFieldService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: FormFieldComponent, isStandalone: true, selector: "igo-form-field", inputs: { field: "field" }, ngImport: i0, template: "<ng-container *ngIf=\"field !== undefined\">\n <igo-dynamic-outlet\n [component]=\"getFieldComponent()\"\n [inputs]=\"getFieldInputs()\"\n [subscribers]=\"getFieldSubscribers()\"\n >\n </igo-dynamic-outlet>\n</ng-container>\n", styles: ["::ng-deep mat-form-field{width:100%}::ng-deep .igo-form-disable-switch{margin-right:8px}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DynamicOutletComponent, selector: "igo-dynamic-outlet", inputs: ["component", "inputs", "subscribers"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormFieldComponent, decorators: [{ type: Component, args: [{ selector: 'igo-form-field', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgIf, DynamicOutletComponent], template: "<ng-container *ngIf=\"field !== undefined\">\n <igo-dynamic-outlet\n [component]=\"getFieldComponent()\"\n [inputs]=\"getFieldInputs()\"\n [subscribers]=\"getFieldSubscribers()\"\n >\n </igo-dynamic-outlet>\n</ng-container>\n", styles: ["::ng-deep mat-form-field{width:100%}::ng-deep .igo-form-disable-switch{margin-right:8px}\n"] }] }], ctorParameters: () => [{ type: FormFieldService }], propDecorators: { field: [{ type: Input }] } }); const FORM_FIELD_DIRECTIVES = [ FormFieldComponent, FormFieldSelectComponent, FormFieldTextComponent, FormFieldTextareaComponent ]; /** * @deprecated import the components directly or FORM_FIELD_DIRECTIVES for every components/directives */ class IgoFormFieldModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoFormFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.15", ngImport: i0, type: IgoFormFieldModule, imports: [FormFieldComponent, FormFieldSelectComponent, FormFieldTextComponent, FormFieldTextareaComponent], exports: [FormFieldComponent, FormFieldSelectComponent, FormFieldTextComponent, FormFieldTextareaComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoFormFieldModule, imports: [FORM_FIELD_DIRECTIVES] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoFormFieldModule, decorators: [{ type: NgModule, args: [{ imports: [...FORM_FIELD_DIRECTIVES], exports: [...FORM_FIELD_DIRECTIVES] }] }] }); /** * A configurable form, optionnally bound to an entity * (for example in case of un update). Submitting that form * emits an event with the form data but no other operation is performed. */ class FormGroupComponent { /** * Form field group */ group; /** * Field placeholder */ errors; /** * Form group control */ get formControl() { return this.group.control; } /** * Return the number of columns a field should occupy. * The maximum allowed is 2, even if the field config says more. * @param field Field * @returns Number of columns * @internal */ getFieldColSpan(field) { let colSpan = 2; const options = field.options || {}; if (options.cols && options.cols > 0) { colSpan = Math.min(options.cols, 2); } return colSpan; } /** * Return the number of columns a field should occupy. * The maximum allowed is 2, even if the field config says more. * @param field Field * @returns Number of columns * @internal */ getFieldNgClass(field) { const colspan = this.getFieldColSpan(field); return { [`igo-form-field-colspan-${colspan}`]: true }; } /** * Get error message */ getErrorMessage() { const options = this.group.options || {}; return getControlErrorMessage(this.formControl, options.errors || {}); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: FormGroupComponent, isStandalone: true, selector: "igo-form-group", inputs: { group: "group", errors: "errors" }, ngImport: i0, template: "<div *ngIf=\"group && group.fields.length > 0\" class=\"igo-form-group-fields\">\n <div\n *ngFor=\"let field of group.fields\"\n class=\"igo-form-field-wrapper\"\n [ngClass]=\"getFieldNgClass(field)\"\n >\n <igo-form-field [field]=\"field\"></igo-form-field>\n </div>\n</div>\n\n<div class=\"igo-form-group-extra-content\">\n <ng-content></ng-content>\n</div>\n\n<mat-error *ngIf=\"formControl.errors\">{{\n getErrorMessage() | translate\n}}</mat-error>\n", styles: [":host{width:100%;height:100%;display:block;overflow:auto;padding:10px 5px;box-sizing:border-box}:host .igo-form-field-colspan-2{width:100%}:host .igo-form-field-colspan-1{width:50%}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: FormFieldComponent, selector: "igo-form-field", inputs: ["field"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "directive", type: i1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormGroupComponent, decorators: [{ type: Component, args: [{ selector: 'igo-form-group', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ NgIf, NgFor, NgClass, FormFieldComponent, MatFormFieldModule, IgoLanguageModule ], template: "<div *ngIf=\"group && group.fields.length > 0\" class=\"igo-form-group-fields\">\n <div\n *ngFor=\"let field of group.fields\"\n class=\"igo-form-field-wrapper\"\n [ngClass]=\"getFieldNgClass(field)\"\n >\n <igo-form-field [field]=\"field\"></igo-form-field>\n </div>\n</div>\n\n<div class=\"igo-form-group-extra-content\">\n <ng-content></ng-content>\n</div>\n\n<mat-error *ngIf=\"formControl.errors\">{{\n getErrorMessage() | translate\n}}</mat-error>\n", styles: [":host{width:100%;height:100%;display:block;overflow:auto;padding:10px 5px;box-sizing:border-box}:host .igo-form-field-colspan-2{width:100%}:host .igo-form-field-colspan-1{width:50%}\n"] }] }], propDecorators: { group: [{ type: Input }], errors: [{ type: Input }] } }); /** * @deprecated import the FormGroupComponent directly */ class IgoFormGroupModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoFormGroupModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.15", ngImport: i0, type: IgoFormGroupModule, imports: [FormGroupComponent], exports: [FormGroupComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoFormGroupModule, imports: [FormGroupComponent] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoFormGroupModule, decorators: [{ type: NgModule, args: [{ imports: [FormGroupComponent], exports: [FormGroupComponent] }] }] }); const FORM_DIRECTIVES = [ ...FORM_FIELD_DIRECTIVES, FormGroupComponent, FormComponent ]; /** * @deprecated import the components directly or FORM_DIRECTIVES for every components/directives */ class IgoFormModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoFormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.15", ngImport: i0, type: IgoFormModule, imports: [FormFieldComponent, FormFieldSelectComponent, FormFieldTextComponent, FormFieldTextareaComponent, FormGroupComponent, FormComponent], exports: [FormFieldComponent, FormFieldSelectComponent, FormFieldTextComponent, FormFieldTextareaComponent, FormGroupComponent, FormComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoFormModule, imports: [FORM_DIRECTIVES] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoFormModule, decorators: [{ type: NgModule, args: [{ imports: [...FORM_DIRECTIVES], exports: [...FORM_DIRECTIVES] }] }] }); class FormDialogComponent { languageService; dialogRef; formService; data; form$ = new BehaviorSubject(undefined); data$ = new BehaviorSubject(undefined); constructor(languageService, dialogRef, formService, data) { this.languageService = languageService; this.dialogRef = dialogRef; this.formService = formService; this.data = data; this.data.processButtonText = this.data.processButtonText ?? 'igo.common.formDialog.processButtonText'; this.data.cancelButtonText = this.data.cancelButtonText ?? 'igo.common.formDialog.cancelButtonText'; this.data.title = this.data.title ?? 'igo.common.formDialog.title'; this.data$ = this.data.data$; const fields = []; const groups = []; this.data.formFieldConfigs?.map((config) => fields.push(this.formService.field(config))); this.data.formGroupsConfigs?.map((formGroupsConfig) => { const fields = formGroupsConfig.formFieldConfigs?.map((config) => this.formService.field(config)); groups.push(this.formService.group({ name: formGroupsConfig.name }, fields)); }); const form = this.formService.form(fields, groups); this.form$.next(form); } onSubmit(data) { const form = this.form$.getValue(); if (form.control.valid) { this.dialogRef.close(data); } else { if (form.groups?.length) { form.groups.map((group) => { Object.keys(group.control.controls).map((k) => { group.control.controls[k].markAsTouched(); group.control.controls[k].updateValueAndValidity(); }); }); } else { form.fields.map((f) => { f.control.markAsTouched(); f.control.updateValueAndValidity(); }); } } } cancel() { this.dialogRef.close(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: FormDialogComponent, deps: [{ token: i1$1.LanguageService }, { token: i2$2.MatDialogRef }, { token: FormService }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: FormDialogComponent, isStandalone: true, selector: "igo-form-dialog", ngImport: i0, template: "<h1 mat-dialog-title>{{ data.title | translate }}</h1>\n\n<igo-form\n *ngIf=\"form$ | async as form\"\n [form]=\"form\"\n [formData]=\"data$ | async\"\n (submitForm)=\"onSubmit($event)\"\n>\n <div *ngIf=\"form.fields.length\" class=\"form-dialog-container\">\n <igo-form-field\n *ngFor=\"let field of form.fields\"\n [field]=\"field\"\n ></igo-form-field>\n <igo-form-group\n *ngFor=\"let group of form.groups\"\n [group]=\"group\"\n ></igo-form-group>\n </div>\n\n <div formButtons mat-dialog-actions>\n <button mat-stroked-button type=\"button\" color=\"primary\" (click)=\"cancel()\">\n {{ data.cancelButtonText | translate }}\n </button>\n <button mat-flat-button type=\"submit\" color=\"primary\">\n {{ data.processButtonText | translate }}\n </button>\n </div>\n</igo-form>\n<div>\n <igo-custom-html\n *ngIf=\"data.notice && data.notice !== ''\"\n [html]=\"data.notice\"\n >\n </igo-custom-html>\n</div>\n", styles: [":host div[mat-dialog-actions]{margin:10px 0 0}:host .form-dialog-container{width:100%;padding:10px}:host .form-dialog-container igo-form-field,:host .form-dialog-container igo-form-group{display:block;height:auto}\n"], dependencies: [{ kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormComponent, selector: "igo-form", inputs: ["form", "formData", "autocomplete"], outputs: ["submitForm"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", t