UNPKG

@koalarx/ui

Version:

Koala UI is a Design System developed in Angular whose objective is to facilitate and make your development faster and simpler, making this framework your greatest ally.

581 lines 213 kB
import { Validators } from '@angular/forms'; import { DynamicFormTypeFieldEnum } from './enums/dynamic-form-type-field.enum'; import { CpfValidator } from './validators/cpf.validator'; import { CnpjValidator } from './validators/cnpj.validator'; import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { FormAbstract } from '../form.abstract'; import { debounceTime } from 'rxjs/operators'; import { BehaviorSubject } from 'rxjs'; import { AutocompleteSelectedValidator } from './validators/autocomplete-selected.validator'; import { delay } from "@koalarx/utils/operators/delay"; import { koala } from "@koalarx/utils"; import { DateMinValidator } from "./validators/date-min.validator"; import { DateMaxValidator } from "./validators/date-max.validator"; import { KoalaLanguageHelper } from "@koalarx/ui/core"; import { randomString } from "@koalarx/utils/operators/string"; import * as i0 from "@angular/core"; import * as i1 from "@angular/forms"; import * as i2 from "./koala.dynamic-form.service"; import * as i3 from "@angular/common"; import * as i4 from "ng2-currency-mask"; import * as i5 from "ngx-mask"; import * as i6 from "@koalarx/ui/file-button"; import * as i7 from "@angular/cdk/text-field"; import * as i8 from "@angular/material/form-field"; import * as i9 from "@angular/material/input"; import * as i10 from "@angular/material/select"; import * as i11 from "@angular/material/core"; import * as i12 from "@angular/material/radio"; import * as i13 from "@angular/material/checkbox"; import * as i14 from "@angular/material/autocomplete"; import * as i15 from "@angular/material/button"; import * as i16 from "@angular/material/icon"; import * as i17 from "@angular/material/expansion"; import * as i18 from "@angular/material/chips"; import * as i19 from "@koalarx/ui/button"; import * as i20 from "@angular/material/progress-spinner"; import * as i21 from "../directives/koala-autofocus.directive"; export class DynamicFormComponent extends FormAbstract { constructor(fb, dynamicFormService) { super(() => this.form); this.fb = fb; this.dynamicFormService = dynamicFormService; this.tabIndexStart = 1; this.typeField = DynamicFormTypeFieldEnum; this.hoursAndMinutesMask = '00:000'; this.errorMessage = KoalaLanguageHelper; this.formId = randomString(25, { lowercase: true, uppercase: true, numbers: false, specialCharacters: false }); } ngOnInit() { if (!this.form.get('formData')) { this.form.addControl('formData', this.fb.array([])); } this.controls = this.form.get('formData'); this.formConfig?.forEach((config, indexConfig) => { const newFormGroup = this.newControl(config); if (config.asyncValidators) { newFormGroup.get('value').setAsyncValidators(config.asyncValidators); } newFormGroup.get('value').updateValueAndValidity(); if (config.type === DynamicFormTypeFieldEnum.dynamicForm) { const formGroupDynamicFormsSubject = newFormGroup.get('dynamicFormConfig').value; formGroupDynamicFormsSubject.subscribe(formGroupConfig => { if (formGroupConfig) { formGroupConfig.form.valueChanges.subscribe(() => { if (formGroupConfig.form.valid && (config.valueChanges || this.showFieldsMoreItensConfig)) { const value = this.dynamicFormService.emitData(formGroupConfig.form); newFormGroup.get('value').setValue(value); } }); } }); } if (config.valueChanges || config.type === DynamicFormTypeFieldEnum.autocomplete || config.type === DynamicFormTypeFieldEnum.dynamicForm || this.showFieldsMoreItensConfig) { if (config.type === DynamicFormTypeFieldEnum.autocomplete) { const autocompleteOptionsSubject = newFormGroup.get('autocompleteOptions').value; if (autocompleteOptionsSubject) { autocompleteOptionsSubject.subscribe(options => newFormGroup.get('autocompleteOptionsFiltered').value.next(options)); } } newFormGroup.get('value') .valueChanges .pipe(debounceTime(300)) .subscribe(async (value) => { await this.setConfigDynamicForm(newFormGroup); if (config.type === DynamicFormTypeFieldEnum.autocomplete) { if (value && (value.hasOwnProperty('value') && value.hasOwnProperty('name') && Object.keys(value).length === 2) || (Array.isArray(value) && newFormGroup.get('multiple').value)) { if (newFormGroup.get('multiple').value) { if (Array.isArray(value)) { newFormGroup.get('autocompleteSelectedValue').setValue(value); newFormGroup.get('value').setValue(value[value.length - 1], { emitEvent: false }); } else { if (this.validateAutocompleteSelect(newFormGroup.get('autocompleteSelectedValue').value, value)) { newFormGroup.get('autocompleteSelectedValue').value.push(value); } } const autocompleteInput = document.querySelector(`#${this.formId} input#autocomplete-${newFormGroup.get('name')?.value}`); if (autocompleteInput) { autocompleteInput.value = ''; } } else { newFormGroup.get('autocompleteSelectedValue').setValue(value); } } else if (!newFormGroup.get('multiple').value) { newFormGroup.get('autocompleteSelectedValue').setValue(koala(this.formConfig) .array() .filter(newFormGroup.get('name').value, 'name') .getValue()[0]?.autocompleteDefaultValueOnClear ?? null); } if (config.type === DynamicFormTypeFieldEnum.autocomplete) { if (config.autocompleteType === 'all') { const autocompleteOptionsSubject = newFormGroup.get('autocompleteOptions').value; newFormGroup.get('autocompleteOptionsFiltered').value.next(this.autocompleteFilter(autocompleteOptionsSubject.value, value)); } else if (config.autocompleteType === 'onDemand' && typeof value !== "object") { const loader = newFormGroup.get('autocompleteLoading').value; loader.next(true); config.autocompleteFilter(value).subscribe(options => { newFormGroup.get('autocompleteOptionsFiltered').value.next(options); loader.next(false); }); } } } if (config.valueChanges) { if (config.type === DynamicFormTypeFieldEnum.autocomplete) { config.valueChanges((newFormGroup.get('multiple').value ? newFormGroup.get('autocompleteSelectedValue').value.map(item => item.value) : newFormGroup.get('autocompleteSelectedValue').value?.value)); } else { config.valueChanges(value); } } }); } this.controls.push(newFormGroup); if (config.moreItemsConfig) { if (config.moreItemsMinItems > 0) { for (let min = 0; min < config.moreItemsMinItems; min++) { if (min <= config.moreItemsMaxItems) { this.addMoreItem(indexConfig); } } } if (config.moreItemsConfig.setValues) { config.moreItemsConfig .setValues .subscribe(async (values) => { if (values.length > 0) { values.forEach((itemValue, indexValue) => { if (!this.controls.controls[indexConfig].get('moreItemsConfig').value[indexValue]) { this.addMoreItem(indexConfig); } setTimeout(() => { this.setValuesOnFields(itemValue, this.controls.controls[indexConfig].get('moreItemsConfig').value[indexValue].form); }, 300); }); } }); } } }); if (this.showFields) { this.changeVisibilityFields(this.showFields, this.form); } if (this.setValues) { this.setValuesOnFields(this.setValues, this.form); } } isValidNewAutocompleteOption(value) { return !!value && typeof value === 'string'; } hoursAndMinutesApplyMask(index, event) { const control = this.controls?.controls[index]; const type = control?.get('type').value; if (type === DynamicFormTypeFieldEnum.hoursAndMinutes) { const value = control?.get('value').value; if (event.key == 'Backspace' && value.length < 6) { this.hoursAndMinutesMask = '00:000'; } else if (event.key != 'Backspace' && value.length >= 6) { this.hoursAndMinutesMask = '000:00'; } } } passwordView(index) { const control = this.controls?.controls[index]; const hidePassword = !control?.get('hidePassword').value; control?.get('hidePassword').setValue(hidePassword); control?.get('type').setValue(hidePassword ? DynamicFormTypeFieldEnum.password : DynamicFormTypeFieldEnum.text); } addMoreItem(propIndex) { if (this.controls.controls[propIndex].get('moreItemsConfig').value.length < this.controls.controls[propIndex].get('moreItemsMaxItems').value) { const formGroup = this.fb.group({}); this.controls.controls[propIndex].get('moreItemsConfig').value.push({ form: formGroup, formConfig: this.formConfig[propIndex].moreItemsConfig.formConfig, showFields: new BehaviorSubject([]), showFieldsMoreItensConfig: this.formConfig[propIndex].moreItemsConfig.showFieldsConfig }); this.controls.controls[propIndex].get('moreItemsExpanded').setValue(this.controls.controls[propIndex].get('moreItemsConfig').value.length - 1); const formArrayMoreItems = this.controls.controls[propIndex].get('moreItemsFormGroup'); formArrayMoreItems.push(formGroup); } } removeMoreItem(propIndex, removeIndex) { const expandedItemIndex = removeIndex - 1; this.controls.controls[propIndex].get('moreItemsConfig').value.splice(removeIndex, 1); setTimeout(() => { this.controls.controls[propIndex].get('moreItemsExpanded').setValue((expandedItemIndex < 0) ? 0 : expandedItemIndex); }, 50); } clearAutocomplete(propIndex) { if (this.controls.controls[propIndex].get('multiple').value) { this.controls.controls[propIndex].get('autocompleteSelectedValue').setValue([]); this.controls.controls[propIndex].get('value').setValue(null); } else { this.controls.controls[propIndex].get('autocompleteSelectedValue').setValue(this.formConfig[propIndex].autocompleteDefaultValueOnClear ?? null); this.controls.controls[propIndex].get('value').setValue(this.formConfig[propIndex].autocompleteDefaultValueOnClear ?? null); } } display(option) { return option ? option.name : undefined; } removeOptionOnAutocomplete(propIndex, option) { const value = this.controls.controls[propIndex].get('autocompleteSelectedValue').value.filter(item => item !== option); this.controls.controls[propIndex].get('autocompleteSelectedValue').setValue(value); if (value.length === 0) { this.controls.controls[propIndex].get('autocompleteSelectedValue').setValue([]); this.controls.controls[propIndex].get('value').setValue(null); } else if (this.formConfig[propIndex].valueChanges) { this.formConfig[propIndex].valueChanges(value.map(item => item.value)); } } getColorChip(config) { return config.color; } getAutocompleteOptions(propriedade) { return propriedade.get('autocompleteOptionsFiltered').value; } getDynamicFormConfig(propriedade) { return propriedade.get('dynamicFormConfig').value; } getRandomString() { return randomString(20, { lowercase: true, numbers: true, specialCharacters: false, uppercase: true }); } newControl(config) { let validators = config.syncValidators ?? []; let value = config.value ?? ''; let valueSelectedAutocomplete = (config.multiple ? [] : (config.autocompleteDefaultValueOnClear ?? null)); if (config.required === true) validators.push(Validators.required); if (config.min && typeof config.min === "number") validators.push(Validators.min(config.min)); if (config.max && typeof config.max === "number") validators.push(Validators.max(config.max)); if (config.type === DynamicFormTypeFieldEnum.date || config.type === DynamicFormTypeFieldEnum.datetime || config.type === DynamicFormTypeFieldEnum.time) { if (config.min && typeof config.min === "string") { validators.push(DateMinValidator(config.min)); } if (config.max && typeof config.max === "string") { validators.push(DateMaxValidator(config.max)); } } if (config.minLength) validators.push(Validators.minLength(config.minLength)); if (config.maxLength) validators.push(Validators.maxLength(config.maxLength)); if (config.type === DynamicFormTypeFieldEnum.cpf) { validators.push(CpfValidator); } else if (config.type === DynamicFormTypeFieldEnum.cnpj) { validators.push(CnpjValidator); } else if (config.type === DynamicFormTypeFieldEnum.email) { validators.push(Validators.email); } else if (config.type === DynamicFormTypeFieldEnum.autocomplete) { if (value) { valueSelectedAutocomplete = value; value = (config.multiple ? valueSelectedAutocomplete[0] : value); } if (config.required === true) { validators.push(AutocompleteSelectedValidator); } } else if (config.type === DynamicFormTypeFieldEnum.checkbox) { value = config.value ?? false; } if (config.type === DynamicFormTypeFieldEnum.hoursAndMinutes && value.length >= 6) { this.hoursAndMinutesMask = '000:00'; } if (config.dynamicFormConfig) { const cloneDynamicFormConfig = {}; Object.assign(cloneDynamicFormConfig, config.dynamicFormConfig); cloneDynamicFormConfig.form = config.dynamicFormConfig.form; config.dynamicFormConfig = cloneDynamicFormConfig; } if (config.show === false) { validators = []; } const field = this.fb.group({ show: [new BehaviorSubject(config.show ?? true)], label: [config.label], name: [config.name], type: [config.type], fileButtonConfig: [{ icon: config?.fileButtonConfig?.icon ?? 'attach_file', text: config?.fileButtonConfig?.text ?? 'Clique para anexar arquivos', backgroundColor: config?.fileButtonConfig?.backgroundColor ?? 'white', color: config?.fileButtonConfig?.color ?? 'blue', accept: config?.fileButtonConfig?.accept ?? '*' }], dynamicFormConfig: [new BehaviorSubject(config.dynamicFormConfig)], dynamicFormGroup: this.fb.array([]), appearance: [config.appearance], floatLabel: [config.floatLabel], placeholder: [config.placeholder], class: [config.class], fieldClass: [config.fieldClass], textHint: [config.textHint], required: [config.required ?? false], min: [config.min ?? 0], max: [config.max ?? 99999999999], minLength: [config.minLength ?? 0], maxLength: [config.maxLength ?? 255], disabled: [config.disabled ?? false], focus: [config.focus ?? false], multiple: [config.multiple ?? false], opcoesSelect: [config.opcoesSelect ?? []], hidePassword: config.type === DynamicFormTypeFieldEnum.password ? true : null, moreItemsButtonIconAddlabel: [config.moreItemsButtonIconAddlabel], moreItemsMinItems: [config.moreItemsMinItems ?? 0], moreItemsMaxItems: [config.moreItemsMaxItems ?? 100], moreItemsIcon: [config.moreItemsIcon], moreItemsIconFontColor: [config.moreItemsIconFontColor], moreItemsIconBackgroundColor: [config.moreItemsIconBackgroundColor], moreItemsExpanded: [''], moreItemsConfig: [[]], moreItemsFormGroup: this.fb.array([]), autocompleteLoading: [new BehaviorSubject(false)], autocompleteOptions: [config.autocompleteOptions], autocompleteMultipleConfig: [config.autocompleteMultipleConfig], autocompleteOptionsFiltered: [new BehaviorSubject([])], autocompleteSelectedValue: [valueSelectedAutocomplete], autocompleteAddOption: [config.autocompleteAddOption], textLogs: [config?.textObs], customMasc: [config?.customMasc], customMascThousandSeparator: [config?.customMascThousandSeparator ?? ''], customMascSuffix: [config?.customMascSuffix ?? ''], customMascPrefix: [config?.customMascPrefix ?? ''], value: [{ value, disabled: config.disabled }, validators, config.asyncValidators] }); if (config.autocompleteType === "onDemand") { const loader = field.get('autocompleteLoading').value; loader.next(true); config.autocompleteFilter('').subscribe(options => { field.get('autocompleteOptionsFiltered').value.next(options); loader.next(false); }); } return field; } setValuesOnFields(subject, form) { subject.subscribe(item => { if (item) { const formArray = form.get('formData'); for (const prop of item.values()) { this.setValueByProp(formArray, prop); } } }); } changeVisibilityFields(subject, form) { subject.pipe(debounceTime(5)).subscribe(item => { if (item) { const formArray = form.get('formData'); for (const prop of item.values()) { for (const [indexControl, control] of formArray.controls.entries()) { if (control.get('name').value === prop.name) { control.get('show').value.next(prop.show); const config = this.formConfig[indexControl] ?? null; if (prop.show) { let validators = []; if (config) { if (config.type === DynamicFormTypeFieldEnum.dynamicForm) { const formArrayMoreItems = control.get('dynamicFormGroup'); formArrayMoreItems.push(config?.dynamicFormConfig?.form); } else { validators = config.syncValidators ?? []; if (config.required === true) { validators.push(Validators.required); } if (config.type === DynamicFormTypeFieldEnum.cpf) { validators.push(CpfValidator); } else if (config.type === DynamicFormTypeFieldEnum.cnpj) { validators.push(CnpjValidator); } else if (config.type === DynamicFormTypeFieldEnum.email) { validators.push(Validators.email); } else if (config.required === true && config.type === DynamicFormTypeFieldEnum.autocomplete) { validators.push(AutocompleteSelectedValidator); } if (config.min && typeof config.min === "number") validators.push(Validators.min(config.min)); if (config.max && typeof config.max === "number") validators.push(Validators.max(config.max)); if (config.type === DynamicFormTypeFieldEnum.date || config.type === DynamicFormTypeFieldEnum.datetime || config.type === DynamicFormTypeFieldEnum.time) { if (config.min && typeof config.min === "string") { validators.push(DateMinValidator(config.min)); } if (config.max && typeof config.max === "string") { validators.push(DateMaxValidator(config.max)); } } if (config.minLength) validators.push(Validators.minLength(config.minLength)); if (config.maxLength) validators.push(Validators.maxLength(config.maxLength)); control.get('value').setValidators(validators); if (config.asyncValidators) { control.get('value').setAsyncValidators(config.asyncValidators); } } control.get('value').updateValueAndValidity(); if (prop.clearCurrentValue) { control.get('value').setValue(null); } } } else { control.get('value').clearValidators(); control.get('value').clearAsyncValidators(); control.setErrors(null); control.get('value').setValue(null); control.get('value').updateValueAndValidity(); if (config.type === DynamicFormTypeFieldEnum.dynamicForm) { const formGroup = control; formGroup.removeControl('dynamicFormGroup'); formGroup.addControl('dynamicFormGroup', this.fb.array([])); } } break; } } } } }); } autocompleteFilter(arr, value) { return arr.filter(filter => { if (typeof value === 'string') { if (filter) { let find = true; value.toLowerCase() .split(' ') .forEach(part => { if (filter.name.toLowerCase().indexOf(part) < 0) { find = false; return false; } }); return find; } } else { return true; } }); } setValueByProp(formArray, prop) { if (formArray) { if (prop.name.indexOf(' > ') >= 0) { let dynamicFormSubject; const arrPropName = prop.name.split(' > '); let indexPropName = 0; do { const control = formArray.controls.find(control => control.get('name').value === arrPropName[indexPropName]); if (indexPropName === arrPropName.length - 2) { dynamicFormSubject = control.get('dynamicFormConfig').value; const dynamicForm = dynamicFormSubject.getValue(); if (dynamicForm.formConfig.find(fc => fc.name === arrPropName[arrPropName.length - 1])) { if (dynamicForm.setValues) { dynamicForm.setValues.next(koala(dynamicForm.setValues.getValue()).array().merge([{ name: arrPropName[arrPropName.length - 1], value: prop.value }]).getValue()); } else { dynamicForm.setValues = new BehaviorSubject([{ name: arrPropName[arrPropName.length - 1], value: prop.value }]); } } } indexPropName++; } while (indexPropName < arrPropName.length - 1); } else { for (const control of formArray.controls.values()) { if (control.get('name').value === prop.name) { control.get('value').setValue(prop.value); break; } } } } } async setConfigDynamicForm(newFormGroup) { if (this.showFieldsMoreItensConfig) { const value = newFormGroup.get('value').value; const configs = this.showFieldsMoreItensConfig .filter(config => config.nameField === newFormGroup.get('name').value) .sort(config => { if (config.fnShow(value)) { return 1; } return -1; }); for (const config of configs) { if (config) { if (config.dynamicFormConfig && config.fnShow(value)) { const controlDynamicFormConfig = this.controls .controls .find(control => config.fieldsToShow.indexOf(control.get('name').value) >= 0); const dynamicFormConfigSubject = controlDynamicFormConfig.get('dynamicFormConfig').value; dynamicFormConfigSubject.next(null); await delay(1); dynamicFormConfigSubject.next(config.dynamicFormConfig(value)); } this.dynamicFormService.showFields(this.showFields, config.fieldsToShow, config.fnShow(value), config.clearCurrentValue); } } } } validateAutocompleteSelect(selectedValues, value) { let isValid = true; for (const selectedItem of selectedValues.values()) { if (selectedItem.name === value.name) { isValid = false; break; } } return isValid; } } DynamicFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DynamicFormComponent, deps: [{ token: i1.UntypedFormBuilder }, { token: i2.KoalaDynamicFormService }], target: i0.ɵɵFactoryTarget.Component }); DynamicFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DynamicFormComponent, selector: "koala-dynamic-form", inputs: { form: "form", formConfig: "formConfig", showFields: "showFields", showFieldsMoreItensConfig: "showFieldsMoreItensConfig", setValues: "setValues", tabIndexStart: "tabIndexStart" }, usesInheritance: true, ngImport: i0, template: "<div [formGroup]=\"form\" class=\"p-relative w-100\" [id]=\"formId\">\n <div *ngFor=\"let propriedade of controls?.controls; let i = index;\"\n [ngClass]=\"(propriedade.get('show').value | async) ? propriedade.get('class').value : 'd-none'\"\n formArrayName=\"formData\">\n\t <div *ngIf=\"propriedade.get('show').value | async\">\n\t <mat-form-field\n\t\t *ngIf=\"propriedade.get('type').value == typeField.text ||\n\t propriedade.get('type').value == typeField.password ||\n\t propriedade.get('type').value == typeField.cpf ||\n\t propriedade.get('type').value == typeField.cnpj ||\n\t propriedade.get('type').value == typeField.datetime ||\n\t propriedade.get('type').value == typeField.email ||\n\t propriedade.get('type').value == typeField.number ||\n\t propriedade.get('type').value == typeField.stringNumber ||\n\t propriedade.get('type').value == typeField.time ||\n\t propriedade.get('type').value == typeField.date ||\n\t propriedade.get('type').value == typeField.hoursAndMinutes ||\n\t propriedade.get('type').value == typeField.phone ||\n\t propriedade.get('type').value == typeField.percent ||\n\t propriedade.get('type').value == typeField.color ||\n\t propriedade.get('type').value == typeField.month ||\n\t propriedade.get('type').value == typeField.competenceDate ||\n propriedade.get('type').value == typeField.stringWithCustomMasc\"\n\t\t [appearance]=\"propriedade.get('appearance').value\"\n\t\t [floatLabel]=\"propriedade.get('floatLabel').value\"\n\t\t [formGroupName]=\"i\"\n\t\t [ngClass]=\"propriedade.get('fieldClass').value\">\n\t <mat-label>{{propriedade.get('label').value}}</mat-label>\n\t <input\n\t\t [dropSpecialCharacters]=\"false\"\n\t\t [koalaAutoFocus]=\"propriedade.get('focus').value\"\n\t\t (keyup)=\"hoursAndMinutesApplyMask(i, $event)\"\n\t\t [required]=\"propriedade.get('required').value\"\n\t\t [tabIndex]=\"tabIndexStart + i\"\n\t\t [mask]=\"((propriedade.get('type').value == typeField.competenceDate) ? '00/0000' : null) ||\n\t\t ((propriedade.get('type').value == typeField.phone) ? '(00)0000-0000?0' : null) ||\n\t\t ((propriedade.get('type').value == typeField.stringNumber) ? '0{'+propriedade.get('maxLength').value+'}' : null) ||\n ((propriedade.get('type').value == typeField.cpf) ? '000.000.000-00' : null) ||\n ((propriedade.get('type').value == typeField.cnpj) ? '00.000.000/0000-00' : null) ||\n ((propriedade.get('type').value == typeField.percent) ? 'percent' : null) ||\n\t\t\t\t\t\t\t\t\t((propriedade.get('type').value == typeField.hoursAndMinutes) ? hoursAndMinutesMask : null) ||\n\t\t\t\t\t\t\t\t\t((propriedade.get('type').value == typeField.stringWithCustomMasc) ? propriedade.get('customMasc').value : null)\"\n\t\t [validation]=\"\n\t (propriedade.get('type').value == typeField.cpf && propriedade.get('value').errors?.cpfInvalid) ||\n\t (propriedade.get('type').value == typeField.cnpj && propriedade.get('value').errors?.cnpjInvalid)\"\n\t\t [type]=\"((propriedade.get('type').value == typeField.cpf ||\n propriedade.get('type').value == typeField.cnpj ||\n propriedade.get('type').value == typeField.phone ||\n propriedade.get('type').value == typeField.percent\n )) ? 'tel' : (\n propriedade.get('type').value == typeField.month ?\n 'month' : (\n propriedade.get('type').value == typeField.date ?\n 'date' : (\n propriedade.get('type').value == typeField.datetime ?\n 'datetime-local' : (\n propriedade.get('type').value == typeField.email ?\n 'email' : (\n propriedade.get('type').value == typeField.number ?\n 'number' : (\n propriedade.get('type').value == typeField.time ?\n 'time' : (\n propriedade.get('type').value == typeField.password ?\n 'password' : (\n propriedade.get('type').value == typeField.color ?\n 'color' : 'text'))))))))\"\n [min]=\"propriedade.get('min').value\"\n [max]=\"propriedade.get('max').value\"\n [minLength]=\"propriedade.get('minLength').value\"\n [maxLength]=\"propriedade.get('maxLength').value\"\n [thousandSeparator]=\"propriedade.get('customMascThousandSeparator').value\"\n [suffix]=\"propriedade.get('customMascSuffix').value\"\n [prefix]=\"propriedade.get('customMascPrefix').value\"\n separatorLimit=\"0\"\n [autocomplete]=\"getRandomString()\"\n\t\t formControlName=\"value\"\n\t\t matInput/>\n\t <button\n\t\t (click)=\"passwordView(i)\"\n\t\t *ngIf=\"propriedade.get('hidePassword').value !== null\"\n\t\t [attr.aria-label]=\"'Hide password'\"\n\t\t [attr.aria-pressed]=\"propriedade.get('hidePassword').value\"\n\t\t mat-icon-button matSuffix tabindex=\"-1\" type=\"button\">\n\t <mat-icon>{{propriedade.get('hidePassword').value ? 'visibility_off' : 'visibility'}}</mat-icon>\n\t </button>\n\t <mat-hint *ngIf=\"propriedade.get('textHint').value\">\n\t <mat-icon>info</mat-icon>\n\t\t {{propriedade.get('textHint').value}}\n\t </mat-hint>\n\t <mat-error *ngIf=\"propriedade.get('value').errors?.required\">\n\t <mat-icon>error</mat-icon>\n {{errorMessage.getRequiredMessage(propriedade.get('label').value)}}\n\t </mat-error>\n\t <mat-error *ngIf=\"propriedade.get('value').errors?.cpfInvalid\">\n\t <mat-icon>error</mat-icon>\n {{errorMessage.getInvalidMessage(propriedade.get('label').value)}}\n\t </mat-error>\n\t <mat-error *ngIf=\"propriedade.get('value').errors?.cnpjInvalid\">\n\t <mat-icon>error</mat-icon>\n {{errorMessage.getInvalidMessage(propriedade.get('label').value)}}\n\t </mat-error>\n\t <mat-error *ngIf=\"propriedade.get('value').errors?.email\">\n\t <mat-icon>error</mat-icon>\n {{errorMessage.getInvalidMessage(propriedade.get('label').value)}}\n\t </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.min\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMinMessage(propriedade.get('min').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.max\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMaxMessage(propriedade.get('max').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.minLength\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMinLengthMessage(propriedade.get('minLength').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.maxLength\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMaxLengthMessage(propriedade.get('maxLength').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.dateMin\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getDateMinMessage()}}\n {{propriedade.get('min').value | date:\"shortDate\"}}.\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.dateMax\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getDateMaxMessage()}}\n {{propriedade.get('max').value | date:\"shortDate\"}}.\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.customError\">\n <mat-icon>error</mat-icon>\n {{propriedade.get('value').errors?.customError.message}}.\n </mat-error>\n\t </mat-form-field>\n\t <mat-form-field\n\t\t *ngIf=\"propriedade.get('type').value == typeField.coin\"\n\t\t [appearance]=\"propriedade.get('appearance').value\"\n\t\t [floatLabel]=\"propriedade.get('floatLabel').value\"\n\t\t [formGroupName]=\"i\"\n\t\t [ngClass]=\"propriedade.get('fieldClass').value\">\n\t <mat-label>{{propriedade.get('label').value}}</mat-label>\n\t <input\n\t\t [koalaAutoFocus]=\"propriedade.get('focus').value\"\n\t\t [required]=\"propriedade.get('required').value\"\n [tabIndex]=\"tabIndexStart + i\"\n [min]=\"propriedade.get('min').value\"\n [max]=\"propriedade.get('max').value\"\n [minLength]=\"propriedade.get('minLength').value\"\n [maxLength]=\"propriedade.get('maxLength').value\"\n [autocomplete]=\"getRandomString()\"\n\t\t currencyMask\n\t\t formControlName=\"value\"\n\t\t matInput\n\t\t type=\"tel\"/>\n\t <mat-hint *ngIf=\"propriedade.get('textHint').value\">\n\t <mat-icon>info</mat-icon>\n\t\t {{propriedade.get('textHint').value}}\n\t </mat-hint>\n <mat-error *ngIf=\"propriedade.get('value').errors?.min\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMinMessage(propriedade.get('min').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.max\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMaxMessage(propriedade.get('max').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.minLength\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMinLengthMessage(propriedade.get('minLength').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.maxLength\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMaxLengthMessage(propriedade.get('maxLength').value)}}\n </mat-error>\n\t <mat-error *ngIf=\"propriedade.get('value').errors?.required\">\n\t <mat-icon>error</mat-icon>\n {{errorMessage.getRequiredMessage(propriedade.get('label').value)}}\n\t </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.customError\">\n <mat-icon>error</mat-icon>\n {{propriedade.get('value').errors?.customError.message}}.\n </mat-error>\n\t </mat-form-field>\n <mat-form-field\n *ngIf=\"propriedade.get('type').value == typeField.float\"\n [appearance]=\"propriedade.get('appearance').value\"\n [floatLabel]=\"propriedade.get('floatLabel').value\"\n [formGroupName]=\"i\"\n [ngClass]=\"propriedade.get('fieldClass').value\">\n <mat-label>{{propriedade.get('label').value}}</mat-label>\n <input\n [koalaAutoFocus]=\"propriedade.get('focus').value\"\n [required]=\"propriedade.get('required').value\"\n [tabIndex]=\"tabIndexStart + i\"\n [min]=\"propriedade.get('min').value\"\n [max]=\"propriedade.get('max').value\"\n [minLength]=\"propriedade.get('minLength').value\"\n [maxLength]=\"propriedade.get('maxLength').value\"\n [autocomplete]=\"getRandomString()\"\n currencyMask\n [options]=\"{prefix: ''}\"\n formControlName=\"value\"\n matInput\n type=\"tel\"/>\n <mat-hint *ngIf=\"propriedade.get('textHint').value\">\n <mat-icon>info</mat-icon>\n {{propriedade.get('textHint').value}}\n </mat-hint>\n <mat-error *ngIf=\"propriedade.get('value').errors?.min\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMinMessage(propriedade.get('min').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.max\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMaxMessage(propriedade.get('max').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.minLength\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMinLengthMessage(propriedade.get('minLength').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.maxLength\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMaxLengthMessage(propriedade.get('maxLength').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.required\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getRequiredMessage(propriedade.get('label').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.customError\">\n <mat-icon>error</mat-icon>\n {{propriedade.get('value').errors?.customError.message}}.\n </mat-error>\n </mat-form-field>\n\t <mat-form-field\n\t\t *ngIf=\"propriedade.get('type').value == typeField.valueList ||\n\t propriedade.get('type').value == typeField.textarea\"\n\t\t [appearance]=\"propriedade.get('appearance').value\"\n\t\t [floatLabel]=\"propriedade.get('floatLabel').value\"\n\t\t [formGroupName]=\"i\"\n\t\t [ngClass]=\"propriedade.get('fieldClass').value\">\n\t <mat-label>{{propriedade.get('label').value}}</mat-label>\n\t <textarea\n #textarea\n\t\t [koalaAutoFocus]=\"propriedade.get('focus').value\"\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n\t\t [cdkAutosizeMaxRows]=\"8\"\n\t\t [cdkAutosizeMinRows]=\"3\"\n\t\t [required]=\"propriedade.get('required').value\"\n [tabIndex]=\"tabIndexStart + i\"\n [minLength]=\"propriedade.get('minLength').value\"\n [maxLength]=\"propriedade.get('maxLength').value\"\n\t\t formControlName=\"value\"\n\t\t matInput>\n </textarea>\n\t <mat-hint *ngIf=\"propriedade.get('textHint').value\">\n\t <mat-icon>info</mat-icon>\n\t\t {{propriedade.get('textHint').value}}\n\t </mat-hint>\n <mat-hint align=\"end\" *ngIf=\"propriedade.get('maxLength').value\">\n {{textarea.value.length}}/{{propriedade.get('maxLength').value}}\n </mat-hint>\n <mat-error *ngIf=\"propriedade.get('value').errors?.minLength\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMinLengthMessage(propriedade.get('minLength').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.maxLength\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMaxLengthMessage(propriedade.get('maxLength').value)}}\n </mat-error>\n\t <mat-error *ngIf=\"propriedade.get('value').errors?.required\">\n\t <mat-icon>error</mat-icon>\n {{errorMessage.getRequiredMessage(propriedade.get('label').value)}}\n\t </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.customError\">\n <mat-icon>error</mat-icon>\n {{propriedade.get('value').errors?.customError.message}}.\n </mat-error>\n\t </mat-form-field>\n\t\t <mat-form-field\n\t\t\t *ngIf=\"propriedade.get('type').value == typeField.textLogs\"\n\t\t\t [appearance]=\"propriedade.get('appearance').value\"\n\t\t\t [floatLabel]=\"propriedade.get('floatLabel').value\"\n\t\t\t [formGroupName]=\"i\"\n\t\t\t [ngClass]=\"propriedade.get('fieldClass').value\">\n\t <mat-label>{{propriedade.get('label').value}}</mat-label>\n\t <div [innerHTML]=\"propriedade.get('textLogs').value\" class=\"text-obs\"></div>\n\t <textarea\n #textarea\n\t\t [koalaAutoFocus]=\"propriedade.get('focus').value\"\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n\t\t [cdkAutosizeMaxRows]=\"8\"\n\t\t [cdkAutosizeMinRows]=\"3\"\n\t\t [required]=\"propriedade.get('required').value\"\n [tabIndex]=\"tabIndexStart + i\"\n [minLength]=\"propriedade.get('minLength').value\"\n [maxLength]=\"propriedade.get('maxLength').value\"\n\t\t formControlName=\"value\"\n\t\t matInput>\n\t </textarea>\n\t <mat-hint *ngIf=\"propriedade.get('textHint').value\">\n\t <mat-icon>info</mat-icon>\n\t\t {{propriedade.get('textHint').value}}\n\t </mat-hint>\n <mat-hint align=\"end\" *ngIf=\"propriedade.get('maxLength').value\">\n {{textarea.value.length}}/{{propriedade.get('maxLength').value}}\n </mat-hint>\n <mat-error *ngIf=\"propriedade.get('value').errors?.minLength\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMinLengthMessage(propriedade.get('minLength').value)}}\n </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.maxLength\">\n <mat-icon>error</mat-icon>\n {{errorMessage.getMaxLengthMessage(propriedade.get('maxLength').value)}}\n </mat-error>\n\t <mat-error *ngIf=\"propriedade.get('value').errors?.required\">\n\t <mat-icon>error</mat-icon>\n {{errorMessage.getRequiredMessage(propriedade.get('label').value)}}\n\t </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.customError\">\n <mat-icon>error</mat-icon>\n {{propriedade.get('value').errors?.customError.message}}.\n </mat-error>\n\t </mat-form-field>\n\t <mat-form-field\n\t\t *ngIf=\"propriedade.get('type').value == typeField.select\"\n\t\t [appearance]=\"propriedade.get('appearance').value\"\n\t\t [floatLabel]=\"propriedade.get('floatLabel').value\"\n\t\t [formGroupName]=\"i\"\n\t\t [ngClass]=\"propriedade.get('fieldClass').value\">\n\t <mat-label>{{propriedade.get('label').value}}</mat-label>\n\t <mat-select [multiple]=\"propriedade.get('multiple').value\" [required]=\"propriedade.get('required').value\"\n [tabIndex]=\"tabIndexStart + i\" formControlName=\"value\">\n\t <mat-option *ngFor=\"let options of propriedade.get('opcoesSelect').value\" [value]=\"options.value\">\n\t {{options.name}}\n\t </mat-option>\n\t </mat-select>\n\t <mat-hint *ngIf=\"propriedade.get('textHint').value\">\n\t <mat-icon>info</mat-icon>\n\t\t {{propriedade.get('textHint').value}}\n\t </mat-hint>\n\t <mat-error *ngIf=\"propriedade.get('value').errors?.required\">\n\t <mat-icon>error</mat-icon>\n {{errorMessage.getRequiredMessage(propriedade.get('label').value)}}\n\t </mat-error>\n <mat-error *ngIf=\"propriedade.get('value').errors?.customError\">\n <mat-icon>error</mat-icon>\n {{propriedade.get('value').errors?.customError.message}}.\n </mat-error>\n\t </mat-form-field>\n <mat-form-field\n class=\"select-multip