@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.
1,086 lines (1,067 loc) • 146 kB
JavaScript
import * as i0 from '@angular/core';
import { Component, Input, Injectable, Directive, ChangeDetectionStrategy, NgModule } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { KoalaLanguageHelper } from '@koalarx/ui/core';
import * as i3 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i2 from '@angular/material/button';
import { MatButtonModule } from '@angular/material/button';
import * as i3$1 from '@angular/material/icon';
import { MatIconModule } from '@angular/material/icon';
import * as i4 from '@angular/material/progress-spinner';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import * as i1 from '@angular/forms';
import { Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
import { koala } from '@koalarx/utils';
import { unmaskCoin, randomString } from '@koalarx/utils/operators/string';
import * as i2$1 from 'ngx-device-detector';
import { debounceTime } from 'rxjs/operators';
import { delay } from '@koalarx/utils/operators/delay';
import * as i4$1 from 'ng2-currency-mask';
import { CurrencyMaskModule } from 'ng2-currency-mask';
import * as i5 from 'ngx-mask';
import { NgxMaskModule } from 'ngx-mask';
import * as i6 from '@koalarx/ui/file-button';
import { KoalaFileButtonModule } 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 { MatInputModule } from '@angular/material/input';
import * as i10 from '@angular/material/select';
import { MatSelectModule } from '@angular/material/select';
import * as i11 from '@angular/material/core';
import * as i12 from '@angular/material/radio';
import { MatRadioModule } from '@angular/material/radio';
import * as i13 from '@angular/material/checkbox';
import { MatCheckboxModule } from '@angular/material/checkbox';
import * as i14 from '@angular/material/autocomplete';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import * as i17 from '@angular/material/expansion';
import { MatExpansionModule } from '@angular/material/expansion';
import * as i18 from '@angular/material/chips';
import { MatChipsModule } from '@angular/material/chips';
import * as i19 from '@koalarx/ui/button';
import { KoalaButtonModule } from '@koalarx/ui/button';
import { maskOptions } from '@koalarx/ui/common';
class BtnSubmitComponent {
constructor() {
this.color = 'primary';
this.btnLabel = KoalaLanguageHelper.getBtnLabel();
this.btnSubmitDisabled = false;
this.disabled = new BehaviorSubject(false);
}
ngOnInit() {
if (!this.btnLabel) {
this.btnLabel = KoalaLanguageHelper.getBtnLabel();
}
}
ngOnChanges(changes) {
if (changes.btnSubmitDisabled) {
this.disabled.next(changes.btnSubmitDisabled.currentValue);
}
}
}
BtnSubmitComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: BtnSubmitComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
BtnSubmitComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: BtnSubmitComponent, selector: "koala-submit", inputs: { fg: "fg", color: "color", btnLabel: "btnLabel", btnSubmitDisabled: "btnSubmitDisabled", loader: "loader", iconButton: "iconButton", icon: "icon", iconColor: "iconColor" }, usesOnChanges: true, ngImport: i0, template: "<button\n\t*ngIf=\"!iconButton else btnIcon\"\n\t[color]=\"color\"\n\t[disabled]=\"(disabled | async) || fg.invalid || fg.pending\"\n\tmat-raised-button\n\ttype=\"submit\">\n <span>{{btnLabel}}</span>\n <mat-spinner *ngIf=\"loader | async\" diameter=\"20\"></mat-spinner>\n</button>\n<ng-template #btnIcon>\n <button\n\t [color]=\"color\"\n\t [disabled]=\"(disabled | async) || fg.invalid || fg.pending\"\n\t class=\"koala-icon-button\"\n\t mat-icon-button\n\t type=\"submit\">\n <mat-spinner *ngIf=\"loader | async\" [color]=\"color\" diameter=\"20\"></mat-spinner>\n <mat-icon *ngIf=\"!(loader | async)\">{{icon}}</mat-icon>\n </button>\n</ng-template>\n", styles: [".mat-spinner{display:inline-block;margin-left:8px}.koala-button{padding:2px 8px}.koala-icon-button mat-spinner{position:relative;display:inline-flex;margin:0}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i4.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: BtnSubmitComponent, decorators: [{
type: Component,
args: [{ selector: 'koala-submit', template: "<button\n\t*ngIf=\"!iconButton else btnIcon\"\n\t[color]=\"color\"\n\t[disabled]=\"(disabled | async) || fg.invalid || fg.pending\"\n\tmat-raised-button\n\ttype=\"submit\">\n <span>{{btnLabel}}</span>\n <mat-spinner *ngIf=\"loader | async\" diameter=\"20\"></mat-spinner>\n</button>\n<ng-template #btnIcon>\n <button\n\t [color]=\"color\"\n\t [disabled]=\"(disabled | async) || fg.invalid || fg.pending\"\n\t class=\"koala-icon-button\"\n\t mat-icon-button\n\t type=\"submit\">\n <mat-spinner *ngIf=\"loader | async\" [color]=\"color\" diameter=\"20\"></mat-spinner>\n <mat-icon *ngIf=\"!(loader | async)\">{{icon}}</mat-icon>\n </button>\n</ng-template>\n", styles: [".mat-spinner{display:inline-block;margin-left:8px}.koala-button{padding:2px 8px}.koala-icon-button mat-spinner{position:relative;display:inline-flex;margin:0}\n"] }]
}], propDecorators: { fg: [{
type: Input
}], color: [{
type: Input
}], btnLabel: [{
type: Input
}], btnSubmitDisabled: [{
type: Input
}], loader: [{
type: Input
}], iconButton: [{
type: Input
}], icon: [{
type: Input
}], iconColor: [{
type: Input
}] } });
var DynamicFormTypeFieldEnum;
(function (DynamicFormTypeFieldEnum) {
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["text"] = 1] = "text";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["password"] = 2] = "password";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["cpf"] = 3] = "cpf";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["cnpj"] = 4] = "cnpj";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["datetime"] = 5] = "datetime";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["email"] = 6] = "email";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["phone"] = 7] = "phone";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["number"] = 8] = "number";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["valueList"] = 9] = "valueList";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["textarea"] = 10] = "textarea";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["time"] = 11] = "time";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["hoursAndMinutes"] = 12] = "hoursAndMinutes";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["checkbox"] = 13] = "checkbox";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["select"] = 14] = "select";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["coin"] = 15] = "coin";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["percent"] = 16] = "percent";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["moreItems"] = 17] = "moreItems";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["id"] = 18] = "id";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["textLogs"] = 19] = "textLogs";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["file"] = 20] = "file";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["autocomplete"] = 21] = "autocomplete";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["color"] = 22] = "color";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["dynamicForm"] = 23] = "dynamicForm";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["date"] = 24] = "date";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["radio"] = 25] = "radio";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["float"] = 26] = "float";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["stringNumber"] = 27] = "stringNumber";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["selectMultipleNative"] = 28] = "selectMultipleNative";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["month"] = 29] = "month";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["competenceDate"] = 30] = "competenceDate";
DynamicFormTypeFieldEnum[DynamicFormTypeFieldEnum["stringWithCustomMasc"] = 31] = "stringWithCustomMasc";
})(DynamicFormTypeFieldEnum || (DynamicFormTypeFieldEnum = {}));
class FieldBase {
constructor(label, name, type, formConfig, fb, deviceService) {
this.formConfig = formConfig;
this.fb = fb;
this.deviceService = deviceService;
this.fieldConfig = {
label,
name,
type
};
this.appearance().grid();
}
hide(hide = true) {
this.fieldConfig.show = !hide;
return this;
}
focus() {
this.fieldConfig.focus = true;
return this;
}
syncValidator(validators) {
this.fieldConfig.syncValidators = validators;
return this;
}
asyncValidator(validators) {
this.fieldConfig.asyncValidators = validators;
return this;
}
disabled(disabled = true) {
this.fieldConfig.disabled = disabled;
return this;
}
required(required = true) {
this.fieldConfig.required = required;
return this;
}
textHint(hint) {
this.fieldConfig.textHint = hint;
return this;
}
min(min) {
this.fieldConfig.min = min;
return this;
}
max(max) {
this.fieldConfig.max = max;
return this;
}
minLength(min) {
this.fieldConfig.minLength = min;
return this;
}
maxLength(max) {
this.fieldConfig.maxLength = max;
return this;
}
multiple(multiple = true) {
this.fieldConfig.multiple = multiple;
return this;
}
valueChanges(fn) {
this.fieldConfig.valueChanges = fn;
return this;
}
setValue(value) {
this.fieldConfig.value = value;
return this;
}
appearance(type = "outline", floatLabel = "always") {
this.fieldConfig.appearance = type;
this.fieldConfig.floatLabel = floatLabel;
return this;
}
grid(size = 12, width = 100) {
if (this.deviceService.isMobile()) {
size = 12;
}
for (let colSize = 12; colSize >= 1; colSize--) {
this.fieldConfig.class = this.fieldConfig.class?.replace('col-' + colSize, '');
}
this.addClass('col-' + size);
this.addFieldClass('w-' + width);
return this;
}
setOptions(options) {
this.fieldConfig.opcoesSelect = options;
return this;
}
addClass(className) {
if (this.deviceService.isMobile() &&
className.indexOf('col-') >= 0 &&
className.indexOf('col-12') === 0) {
className = className.replace('col-1', 'col-12')
.replace('col-2', 'col-12')
.replace('col-3', 'col-12')
.replace('col-4', 'col-12')
.replace('col-5', 'col-12')
.replace('col-6', 'col-12')
.replace('col-7', 'col-12')
.replace('col-8', 'col-12')
.replace('col-9', 'col-12')
.replace('col-10', 'col-12')
.replace('col-11', 'col-12');
}
this.fieldConfig.class = koala(`${this.fieldConfig?.class ?? ''} ${className}`)
.string()
.split(' ')
.clearEmptyValues()
.toString(' ')
.getValue();
return this;
}
addFieldClass(className) {
this.fieldConfig.fieldClass = koala(`${this.fieldConfig?.fieldClass ?? ''} ${className}`)
.string()
.split(' ')
.clearEmptyValues()
.toString(' ')
.getValue();
return this;
}
setCustomMasc(mask, config) {
this.fieldConfig.customMasc = mask;
this.fieldConfig.customMascThousandSeparator = config?.thousandSeparator;
this.fieldConfig.customMascSuffix = config?.suffix;
this.fieldConfig.customMascPrefix = config?.prefix;
return this;
}
generate() {
let getLastConfig = (this.formConfig.formConfig.length > 0) ?
this.formConfig.formConfig[this.formConfig.formConfig.length - 1] :
null;
if (getLastConfig?.type === DynamicFormTypeFieldEnum.moreItems && getLastConfig?.name !== 'endMoreItems') {
this.formConfig.formConfig[this.formConfig.formConfig.length - 1].moreItemsConfig.formConfig.push(this.fieldConfig);
}
else {
if (getLastConfig?.name === 'endMoreItems') {
this.formConfig.formConfig.splice(this.formConfig.formConfig.length - 1, 1);
}
this.formConfig.formConfig.push(this.fieldConfig);
}
return new DynamicFormBuilder(this.fb, this.deviceService, this.formConfig.formConfig);
}
}
class AutocompleteBuilder extends FieldBase {
constructor(label, name, formConfig, fb, deviceService) {
super(label, name, DynamicFormTypeFieldEnum.autocomplete, formConfig, fb, deviceService);
}
service(service) {
this.service$ = service;
return this;
}
defaultValueOnClean(value) {
this.fieldConfig.autocompleteDefaultValueOnClear = value;
return this;
}
loadOptions(type, onDemandFilter) {
this.fieldConfig.autocompleteType = type;
if (type === "all") {
const options$ = new BehaviorSubject([]);
this.service$.subscribe(options => options$.next(options));
this.fieldConfig.autocompleteOptions = options$;
}
else {
this.fieldConfig.autocompleteFilter = onDemandFilter;
}
return this;
}
colorChipConfig(fn) {
this.fieldConfig.autocompleteMultipleConfig = new BehaviorSubject(null);
fn(this.fieldConfig.autocompleteMultipleConfig);
return this;
}
addOption(active = true) {
this.fieldConfig.autocompleteAddOption = active;
return this;
}
}
class FieldBuilder extends FieldBase {
constructor(label, name, type, formConfig, fb, deviceService) {
super(label, name, type, formConfig, fb, deviceService);
}
}
class MoreItemsBuilder {
constructor(label, name, btnAddLabel, min, max, formConfig, fb, deviceService) {
this.label = label;
this.name = name;
this.btnAddLabel = btnAddLabel;
this.min = min;
this.max = max;
this.formConfig = formConfig;
this.fb = fb;
this.deviceService = deviceService;
}
build() {
let getLastConfig = (this.formConfig.formConfig.length > 0) ?
this.formConfig.formConfig[this.formConfig.formConfig.length - 1] :
null;
this.fieldConfig = {
label: this.label,
name: this.name,
type: DynamicFormTypeFieldEnum.moreItems,
moreItemsIconBackgroundColor: '#fff',
moreItemsIconFontColor: '#212121',
moreItemsMinItems: this.min,
moreItemsMaxItems: this.max,
moreItemsButtonIconAddlabel: this.btnAddLabel,
moreItemsConfig: {
form: this.fb.group({}),
formConfig: [],
setValues: new BehaviorSubject([])
}
};
if (getLastConfig?.type === DynamicFormTypeFieldEnum.moreItems && getLastConfig?.name !== 'endMoreItems') {
let formConfigMoreItems = getLastConfig.moreItemsConfig.formConfig;
if (formConfigMoreItems.length > 0) {
let lastIndexMoreItems = 0;
formConfigMoreItems.forEach((item, index) => {
if (item.type === DynamicFormTypeFieldEnum.moreItems)
lastIndexMoreItems = index;
});
formConfigMoreItems[lastIndexMoreItems].moreItemsConfig.formConfig.push(this.fieldConfig);
}
else {
this.formConfig.formConfig[this.formConfig.formConfig.length - 1].moreItemsConfig.formConfig.push(this.fieldConfig);
}
}
else {
if (getLastConfig?.name === 'endMoreItems') {
this.formConfig.formConfig.splice(this.formConfig.formConfig.length - 1, 1);
}
this.formConfig.formConfig.push(this.fieldConfig);
}
return new DynamicFormBuilder(this.fb, this.deviceService, this.formConfig.formConfig);
}
}
class DynamicFormBuilder {
constructor(fb, deviceService, configInMemory) {
this.fb = fb;
this.deviceService = deviceService;
this.config = {
form: fb.group({}),
formConfig: configInMemory ?? [],
setValues: new BehaviorSubject(null),
showFields: new BehaviorSubject(null)
};
}
field(label, name, type) {
switch (type) {
case "id":
case "text":
case "textarea":
case "number":
case "stringNumber":
case "cnpj":
case "cpf":
case "coin":
case "color":
case "date":
case "datetime":
case "email":
case "float":
case "password":
case "percent":
case "phone":
case "time":
case "hoursAndMinutes":
case "textLogs":
case "valueList":
case "checkbox":
case "radio":
case "select":
case "selectMultipleNative":
case "month":
case "competenceDate":
case "stringWithCustomMasc":
return new FieldBuilder(label, name, DynamicFormTypeFieldEnum[type], this.config, this.fb, this.deviceService);
}
}
autocomplete(label, name) {
return new AutocompleteBuilder(label, name, this.config, this.fb, this.deviceService);
}
simpleMoreItems(label, name, btnAddLabel, min, max) {
return new MoreItemsBuilder(label, name, btnAddLabel, min, max, this.config, this.fb, this.deviceService);
}
autofill(object) {
if (object) {
const setValues = [];
Object.keys(object).forEach(indexName => {
const arrField = koala(this.config.formConfig).array().filter(indexName, 'name', { comparator: "=" }).getValue();
if (arrField.length === 1) {
const field = arrField[0] ?? null;
if (typeof object[indexName] !== "object" ||
field.type === DynamicFormTypeFieldEnum.autocomplete ||
field.type === DynamicFormTypeFieldEnum.selectMultipleNative) {
if (field.type === DynamicFormTypeFieldEnum.textLogs) {
field.textObs = object[indexName];
}
else {
setValues.push({
name: indexName,
value: object[indexName]
});
}
}
else {
if (field.type === DynamicFormTypeFieldEnum.moreItems) {
const setValuesMoreItems = [];
const objectMoreItems = object[indexName];
objectMoreItems.forEach(objectItem => {
const moreItemValues = [];
Object.keys(objectItem).forEach(objectIndexName => {
moreItemValues.push({
name: objectIndexName,
value: objectItem[objectIndexName]
});
});
setValuesMoreItems.push(new BehaviorSubject(moreItemValues));
});
field.moreItemsConfig?.setValues?.next(setValuesMoreItems);
}
else if (field.type === DynamicFormTypeFieldEnum.dynamicForm) {
const dynamicFormObject = object[indexName];
const dynamicFormSetValues = [];
Object.keys(dynamicFormObject).forEach(dynamicFormIndexName => {
const arrDynamicField = koala(field.dynamicFormConfig.formConfig).array().filter(indexName, 'name').getValue();
const dynamicField = arrDynamicField[0] ?? null;
if (dynamicField?.type === DynamicFormTypeFieldEnum.textLogs) {
dynamicField.textObs = object[indexName];
}
else {
dynamicFormSetValues.push({
name: dynamicFormIndexName,
value: dynamicFormObject[dynamicFormIndexName]
});
}
});
field.dynamicFormConfig?.setValues?.next(dynamicFormSetValues);
}
else {
this.autofill(object[indexName]);
}
}
}
});
this.config?.setValues?.next(setValues);
}
return this;
}
literalConfig(config) {
this.config.formConfig.push(config);
if (config.type === DynamicFormTypeFieldEnum.moreItems)
this.generateMoreItems();
return this;
}
generate(tabIndexStart = 0) {
this.config.formConfig = this.config.formConfig.filter(config => config.name !== 'endMoreItems');
this.config.tabIndexStart = tabIndexStart;
return this.config;
}
generateMoreItems() {
this.config.formConfig.push({
name: 'endMoreItems',
type: DynamicFormTypeFieldEnum.moreItems
});
return new DynamicFormBuilder(this.fb, this.deviceService, this.config.formConfig);
}
}
function DateMinValidator(min) {
return (control) => {
if (control.value && typeof min === 'string') {
if (new Date(control.value) < new Date(min)) {
return { dateMin: true };
}
}
return null;
};
}
function DateMaxValidator(max) {
return (control) => {
if (control.value && typeof max === 'string') {
if (new Date(control.value) > new Date(max)) {
return { dateMax: true };
}
}
return null;
};
}
class KoalaDynamicFormService {
constructor(fb, deviceService) {
this.fb = fb;
this.deviceService = deviceService;
}
build() {
return new DynamicFormBuilder(this.fb, this.deviceService);
}
updateValidator(formGroup, name, type, value) {
if (type === 'required' && typeof value !== 'boolean') {
throw new Error(`Type required cannot be a ${typeof value}`);
}
else if ((type === 'min' || type === 'max') && typeof value === "boolean") {
throw new Error(`Type ${type} cannot be a boolean`);
}
const formArray = formGroup.get('formData');
const control = formArray.controls.find(control => control.get('name').value === name);
if (control) {
const currentMin = control.get('min').value;
const currentMax = control.get('max').value;
const validators = [];
control.get('value').clearValidators();
control.get('value').setErrors(null);
if (type === "required" && value) {
validators.push(Validators.required);
control.get('value').setErrors({ required: true });
}
if ((type === "min" || currentMin)) {
if (typeof value === "number") {
validators.push(Validators.min((type === "min" ? value : currentMin)));
control.get('value').setErrors({ min: true });
}
else if (typeof value === "string") {
validators.push(DateMinValidator((type === "min" ? value : currentMin)));
control.get('value').setErrors({ dateMin: true });
}
}
if ((type === "max" || currentMax)) {
if (typeof value === "number") {
validators.push(Validators.max((type === "max" ? value : currentMax)));
control.get('value').setErrors({ max: true });
}
else if (typeof value === "string") {
validators.push(DateMaxValidator((type === "max" ? value : currentMax)));
control.get('value').setErrors({ dateMax: true });
}
}
if (type === "required") {
control.get('required').setValue(value);
}
else if (type === "min") {
control.get('min').setValue(value);
}
else if (type === "max") {
control.get('max').setValue(value);
}
control.get('value').setValidators(validators);
control.get('value').updateValueAndValidity();
}
}
disableFields(formGroup, disabled, fields) {
const formArray = formGroup.get('formData');
fields.forEach(field => {
const controlValue = formArray.controls.find(control => field === control.get('name').value)?.get('value');
if (controlValue && disabled) {
controlValue.disable();
}
else if (controlValue && !disabled) {
controlValue.enable();
}
const controlDisabled = formArray.controls.find(control => field === control.get('name').value)?.get('disabled');
controlDisabled.setValue(disabled);
});
}
emitData(form) {
const data = {};
const formArray = form.get('formData');
formArray?.controls.forEach(control => {
if (control.get('show').value.getValue() !== false) {
let value = control.get('value').value;
if (control.get('type').value === DynamicFormTypeFieldEnum.valueList) {
if (value === null || value === undefined) {
value = '';
}
value = koala(value).string().split().getValue();
}
else if (control.get('type').value === DynamicFormTypeFieldEnum.moreItems) {
const moreItems = control.get('moreItemsConfig').value;
value = [];
moreItems.forEach(item => {
value.push(this.emitData(item.form));
});
}
else if (control.get('type').value === DynamicFormTypeFieldEnum.autocomplete) {
if (control.get('multiple').value) {
const options = control.get('autocompleteSelectedValue').value;
value = options?.map(item => item?.value);
}
else {
value = (control.get('autocompleteSelectedValue').value?.value ?
control.get('autocompleteSelectedValue').value.value :
control.get('autocompleteSelectedValue').value);
}
}
else if (control.get('type').value === DynamicFormTypeFieldEnum.dynamicForm) {
const dynamicFormConfig = control.get('dynamicFormConfig').value;
value = this.emitData(dynamicFormConfig.getValue().form);
}
else if (control.get('type').value === DynamicFormTypeFieldEnum.number) {
value = parseInt(value);
}
else if ((control.get('type').value === DynamicFormTypeFieldEnum.float ||
control.get('type').value === DynamicFormTypeFieldEnum.percent) && typeof value === "string") {
value = parseFloat(value.replace(/,/g, '.'));
}
else if (control.get('type').value === DynamicFormTypeFieldEnum.coin &&
typeof value === "string") {
value = unmaskCoin(value);
}
data[control.get('name').value] = value;
}
});
return data;
}
resetForm(form) {
const formArray = form.get('formData');
formArray.controls.forEach(control => {
if (control.get('type').value === DynamicFormTypeFieldEnum.moreItems) {
control.get('moreItemsConfig').setValue([]);
}
else {
control.get('value').reset();
}
});
}
setValuesInMoreItemsForm(subject, values) {
const valuesMoreItems = [];
values.forEach(itemValue => {
valuesMoreItems.push(new BehaviorSubject(itemValue));
});
subject.next(valuesMoreItems);
}
autocompleteFilterOnServer(request, nameConfig, indexNameByValue) {
return new Observable(observe => {
request().then(response => {
const options = [];
response.forEach(item => {
let value = '';
if (indexNameByValue?.indexOf(' > ') >= 0) {
value = this.getValueByStringPath(indexNameByValue, item);
}
else if (indexNameByValue) {
value = item[indexNameByValue];
}
else {
value = item;
}
options.push({
name: koala(item).object().toString(nameConfig.propsByName, (nameConfig.delimiter ?? ' ')).getValue(),
value
});
});
observe.next(options);
});
});
}
showFields(subject, names, show, clearCurrentValue = false) {
const fields = [];
names.forEach(name => {
fields.push({
name,
show,
clearCurrentValue
});
});
subject.next(fields);
}
getValueByStringPath(indexNameByValue, item) {
let value;
const partsIndex = indexNameByValue.split(' > ');
let partIndex = 0;
do {
if (!value) {
value = item[partsIndex[partIndex]];
}
else {
value = value[partsIndex[partIndex]];
}
partIndex++;
} while (partIndex < partsIndex.length);
return value;
}
}
KoalaDynamicFormService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KoalaDynamicFormService, deps: [{ token: i1.UntypedFormBuilder }, { token: i2$1.DeviceDetectorService }], target: i0.ɵɵFactoryTarget.Injectable });
KoalaDynamicFormService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KoalaDynamicFormService, providedIn: "any" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KoalaDynamicFormService, decorators: [{
type: Injectable,
args: [{ providedIn: "any" }]
}], ctorParameters: function () { return [{ type: i1.UntypedFormBuilder }, { type: i2$1.DeviceDetectorService }]; } });
class ValidationHelper {
static validateCpf(value) {
function calcChecker1(digits) {
let sum = null;
for (let j = 0; j < 9; ++j) {
sum += digits.toString().charAt(j) * (10 - j);
}
const lastSumChecker1 = sum % 11;
return lastSumChecker1 < 2 ? 0 : 11 - lastSumChecker1;
}
function calcChecker2(cpfWithChecker1) {
let sum = null;
for (let k = 0; k < 10; ++k) {
sum += cpfWithChecker1.toString().charAt(k) * (11 - k);
}
const lastSumChecker2 = sum % 11;
return lastSumChecker2 < 2 ? 0 : 11 - lastSumChecker2;
}
const cleanCPF = value.replace(/\.|\-|\s/g, '');
const firstNineDigits = cleanCPF.substring(0, 9);
const checker = cleanCPF.substring(9, 11);
if (cleanCPF.length !== 11) {
return false;
}
// Checking if all digits are equal
for (let i = 0; i < 10; i++) {
if ('' + firstNineDigits + checker === Array(12).join(`${i}`)) {
return false;
}
}
const checker1 = calcChecker1(firstNineDigits);
const checker2 = calcChecker2(firstNineDigits + '' + checker1);
return checker.toString() === checker1.toString() + checker2.toString();
}
static validateCnpj(value) {
value = value.replace(/[^\d]+/g, '');
if (value === '') {
return false;
}
if (value.length !== 14) {
return false;
}
// Elimina CNPJs invalidos conhecidos
if (value === '00000000000000' ||
value === '11111111111111' ||
value === '22222222222222' ||
value === '33333333333333' ||
value === '44444444444444' ||
value === '55555555555555' ||
value === '66666666666666' ||
value === '77777777777777' ||
value === '88888888888888' ||
value === '99999999999999') {
return false;
}
// Valida DVs
let tamanho = value.length - 2;
let numeros = value.substring(0, tamanho);
const digitos = value.substring(tamanho);
let soma = 0;
let pos = tamanho - 7;
for (let i = tamanho; i >= 1; i--) {
soma += parseInt(numeros.charAt(tamanho - i), 10) * pos--;
if (pos < 2) {
pos = 9;
}
}
let resultado = soma % 11 < 2 ? 0 : 11 - soma % 11;
if (resultado !== parseInt(digitos.charAt(0), 10)) {
return false;
}
tamanho = tamanho + 1;
numeros = value.substring(0, tamanho);
soma = 0;
pos = tamanho - 7;
for (let i = tamanho; i >= 1; i--) {
soma += parseInt(numeros.charAt(tamanho - i), 10) * pos--;
if (pos < 2) {
pos = 9;
}
}
resultado = soma % 11 < 2 ? 0 : 11 - soma % 11;
return !(resultado !== parseInt(digitos.charAt(1), 10));
}
}
function CpfValidator(control) {
if (control.value) {
if (control.value.length <= 14 && !ValidationHelper.validateCpf(control.value)) {
return { cpfInvalid: true };
}
}
return null;
}
function CnpjValidator(control) {
if (control.value) {
if (control.value.length > 14 && !ValidationHelper.validateCnpj(control.value)) {
return { cnpjInvalid: true };
}
}
return null;
}
function AutocompleteSelectedValidator(control) {
if (control.value &&
control.value.hasOwnProperty('value') &&
control.value.hasOwnProperty('name') &&
Object.keys(control.value).length === 2) {
return null;
}
return { autocompleteSelected: true };
}
class KoalaDynamicFormValidatorResultHelper {
static generate(errorMessage) {
return {
customError: {
message: errorMessage
}
};
}
}
class ShowInvalidFields {
constructor() {
}
isErrorState(control, form) {
const isSubmitted = form && form.submitted;
return !!(control && control.invalid && (control.errors || control.dirty || control.touched || isSubmitted));
}
}
class FormAbstract {
constructor(formAbstract) {
this.formAbstract = formAbstract;
this.loader = new BehaviorSubject(false);
this.btnSubmitDisabled = false;
this.getData = new BehaviorSubject(false);
}
selecionarAutocomplete(controlName, obj, indexName) {
if (obj) {
let value = indexName ? obj[indexName] : obj;
if (Array.isArray(obj)) {
value = [];
obj.forEach(item => {
value.push(indexName ? item[indexName] : item);
});
}
this.formAbstract().get(controlName).setValue(value);
}
else {
this.formAbstract().get(controlName).setValue('');
}
}
btnClickGetData() {
this.getData.next(true);
}
enableShowInvalidFields() {
this.showInvalidFields = new ShowInvalidFields();
}
loading(show = true, btnLabel) {
this.btnSubmitDisabled = show;
this.loader.next(show);
if (show) {
this.btnLabel = btnLabel ? btnLabel : 'Enviando Dados...';
}
else {
this.btnLabel = btnLabel ? btnLabel : 'Enviar';
}
}
}
class KoalaAutofocusDirective {
constructor(el) {
this.el = el;
}
ngAfterContentInit() {
if (this.koalaAutoFocus) {
setTimeout(() => {
this.el.nativeElement.focus();
}, 500);
}
}
}
KoalaAutofocusDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KoalaAutofocusDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
KoalaAutofocusDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: KoalaAutofocusDirective, selector: "[koalaAutoFocus]", inputs: { koalaAutoFocus: "koalaAutoFocus" }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KoalaAutofocusDirective, decorators: [{
type: Directive,
args: [{
selector: '[koalaAutoFocus]'
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { koalaAutoFocus: [{
type: Input
}] } });
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 form