@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
JavaScript
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