ui-core-abv 0.6.69 → 0.6.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ui-core-abv.mjs +573 -109
- package/fesm2022/ui-core-abv.mjs.map +1 -1
- package/lib/components/dynamic-form/form-wrapper/form-wrapper.component.d.ts +33 -2
- package/lib/components/dynamic-form/form.models.d.ts +17 -0
- package/lib/components/inputs/file-input/file-input.component.d.ts +1 -0
- package/lib/components/tree-admin/tree-admin.component.d.ts +4 -0
- package/lib/components/user-formbuilder/block-editor/field-editor/field-editor.component.d.ts +6 -1
- package/lib/components/user-formbuilder/user-formbuilder.component.d.ts +10 -0
- package/lib/translate/dictionary.en.d.ts +12 -0
- package/lib/translate/dictionary.es.d.ts +12 -0
- package/package.json +1 -1
package/fesm2022/ui-core-abv.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import * as i0 from '@angular/core';
|
|
|
4
4
|
import { Input, Component, EventEmitter, Output, Directive, forwardRef, InjectionToken, Optional, Inject, Injectable, inject, ChangeDetectorRef, Pipe, ViewContainerRef, ElementRef, ViewChild, createComponent, HostListener, ViewChildren, Host, DestroyRef, signal, computed, effect, TemplateRef, ContentChild, Injector, EnvironmentInjector, HostBinding, input, output } from '@angular/core';
|
|
5
5
|
import * as i1$1 from '@angular/forms';
|
|
6
6
|
import { NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';
|
|
7
|
-
import { BehaviorSubject, Subject, debounceTime, distinctUntilChanged, tap, switchMap, of, finalize, Subscription } from 'rxjs';
|
|
7
|
+
import { BehaviorSubject, Subject, debounceTime, distinctUntilChanged, tap, switchMap, of, finalize, isObservable, from, Subscription } from 'rxjs';
|
|
8
8
|
import { HttpClient } from '@angular/common/http';
|
|
9
9
|
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
|
|
10
10
|
import * as i1$2 from '@angular/cdk/portal';
|
|
@@ -470,6 +470,18 @@ const DICTIONARY_EN = {
|
|
|
470
470
|
iaValidationPrompt: 'IA Validation Prompt',
|
|
471
471
|
searchApi: 'Search API',
|
|
472
472
|
searchApi_tip: 'URL to fetch search options',
|
|
473
|
+
optionsSourceKey: 'Options source',
|
|
474
|
+
optionsSourceKey_tip: 'Logical key registered by the consuming application',
|
|
475
|
+
optionsSourceIdField: 'Option ID field',
|
|
476
|
+
optionsSourceIdField_tip: 'Path used as the option id. Example: id',
|
|
477
|
+
optionsSourceTextField: 'Option text field',
|
|
478
|
+
optionsSourceTextField_tip: 'Path used as the option text. Example: name',
|
|
479
|
+
optionsSourceTextTemplate: 'Text template',
|
|
480
|
+
optionsSourceTextTemplate_tip: 'Example: {{name}} ({{id}})',
|
|
481
|
+
optionsSourceDependsOn: 'Depends on',
|
|
482
|
+
optionsSourceDependsOn_tip: 'Parent field identifier that triggers reloads',
|
|
483
|
+
optionsSourceParamName: 'Parameter name',
|
|
484
|
+
optionsSourceParamName_tip: 'Name used to send the dependent value',
|
|
473
485
|
selectNullable_tip: 'Allows selecting an empty option',
|
|
474
486
|
selectSearchEnabled_tip: 'Enables search among options',
|
|
475
487
|
selectNullable: 'Allow empty option',
|
|
@@ -761,6 +773,18 @@ const DICTIONARY_ES = {
|
|
|
761
773
|
iaValidation: 'Validación IA',
|
|
762
774
|
iaValidationPrompt: 'Prompt de validación IA',
|
|
763
775
|
searchApi_tip: 'URL para obtener opciones de búsqueda',
|
|
776
|
+
optionsSourceKey: 'Fuente de opciones',
|
|
777
|
+
optionsSourceKey_tip: 'Clave lógica registrada por la aplicación consumidora',
|
|
778
|
+
optionsSourceIdField: 'Campo ID de opción',
|
|
779
|
+
optionsSourceIdField_tip: 'Ruta del valor usado como id. Ejemplo: id',
|
|
780
|
+
optionsSourceTextField: 'Campo texto de opción',
|
|
781
|
+
optionsSourceTextField_tip: 'Ruta del valor usado como texto. Ejemplo: name',
|
|
782
|
+
optionsSourceTextTemplate: 'Plantilla de texto',
|
|
783
|
+
optionsSourceTextTemplate_tip: 'Ejemplo: {{name}} ({{id}})',
|
|
784
|
+
optionsSourceDependsOn: 'Depende de',
|
|
785
|
+
optionsSourceDependsOn_tip: 'Identificador del campo padre que dispara la recarga',
|
|
786
|
+
optionsSourceParamName: 'Nombre del parámetro',
|
|
787
|
+
optionsSourceParamName_tip: 'Nombre con el que se envía el valor dependiente',
|
|
764
788
|
selectNullable_tip: 'Permite seleccionar una opción vacía',
|
|
765
789
|
selectSearchEnabled_tip: 'Habilita búsqueda entre opciones',
|
|
766
790
|
selectNullable: 'Permitir opción vacía',
|
|
@@ -1388,6 +1412,82 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
1388
1412
|
args: ['calendarTemplate']
|
|
1389
1413
|
}] } });
|
|
1390
1414
|
|
|
1415
|
+
let nextId$1 = 1;
|
|
1416
|
+
function createSuccessAlert(message, options) {
|
|
1417
|
+
return {
|
|
1418
|
+
id: nextId$1++,
|
|
1419
|
+
message,
|
|
1420
|
+
icon: 'ri-check-line',
|
|
1421
|
+
showProgressBar: true,
|
|
1422
|
+
type: 'success',
|
|
1423
|
+
duration: 3000,
|
|
1424
|
+
...options,
|
|
1425
|
+
};
|
|
1426
|
+
}
|
|
1427
|
+
function createErrorAlert(message, options) {
|
|
1428
|
+
return {
|
|
1429
|
+
id: nextId$1++,
|
|
1430
|
+
message,
|
|
1431
|
+
showProgressBar: true,
|
|
1432
|
+
type: 'error',
|
|
1433
|
+
icon: 'ri-error-warning-line',
|
|
1434
|
+
duration: 5000,
|
|
1435
|
+
...options,
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
function createWarningAlert(message, options) {
|
|
1439
|
+
return {
|
|
1440
|
+
id: nextId$1++,
|
|
1441
|
+
message,
|
|
1442
|
+
showProgressBar: true,
|
|
1443
|
+
type: 'warning',
|
|
1444
|
+
icon: 'ri-alarm-warning-line',
|
|
1445
|
+
duration: 4000,
|
|
1446
|
+
...options,
|
|
1447
|
+
};
|
|
1448
|
+
}
|
|
1449
|
+
function createInfoAlert(message, options) {
|
|
1450
|
+
return {
|
|
1451
|
+
id: nextId$1++,
|
|
1452
|
+
showProgressBar: true,
|
|
1453
|
+
message,
|
|
1454
|
+
icon: 'ri-information-2-line',
|
|
1455
|
+
type: 'info',
|
|
1456
|
+
duration: 3000,
|
|
1457
|
+
...options,
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
class UicPushAlertService {
|
|
1462
|
+
autoIncId = 0;
|
|
1463
|
+
alerts$ = new Subject();
|
|
1464
|
+
get stream() {
|
|
1465
|
+
return this.alerts$.asObservable();
|
|
1466
|
+
}
|
|
1467
|
+
show(alertData) {
|
|
1468
|
+
this.autoIncId++;
|
|
1469
|
+
const alert = { ...alertData, id: this.autoIncId };
|
|
1470
|
+
this.alerts$.next(alert);
|
|
1471
|
+
}
|
|
1472
|
+
success(message, options) {
|
|
1473
|
+
this.show(createSuccessAlert(message, options));
|
|
1474
|
+
}
|
|
1475
|
+
error(message, options) {
|
|
1476
|
+
this.show(createErrorAlert(message, options));
|
|
1477
|
+
}
|
|
1478
|
+
warning(message, options) {
|
|
1479
|
+
this.show(createWarningAlert(message, options));
|
|
1480
|
+
}
|
|
1481
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicPushAlertService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1482
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicPushAlertService, providedIn: 'root' });
|
|
1483
|
+
}
|
|
1484
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicPushAlertService, decorators: [{
|
|
1485
|
+
type: Injectable,
|
|
1486
|
+
args: [{
|
|
1487
|
+
providedIn: 'root'
|
|
1488
|
+
}]
|
|
1489
|
+
}] });
|
|
1490
|
+
|
|
1391
1491
|
const base$a = createValueAccessor();
|
|
1392
1492
|
class UicFileInputComponent extends base$a {
|
|
1393
1493
|
icon = ''; // Icono externo
|
|
@@ -1406,6 +1506,7 @@ class UicFileInputComponent extends base$a {
|
|
|
1406
1506
|
fileTypes = null;
|
|
1407
1507
|
fileUidResolverFn;
|
|
1408
1508
|
fileInput;
|
|
1509
|
+
push = inject(UicPushAlertService);
|
|
1409
1510
|
value = [];
|
|
1410
1511
|
files = [];
|
|
1411
1512
|
isDragging = false;
|
|
@@ -1613,6 +1714,7 @@ class UicFileInputComponent extends base$a {
|
|
|
1613
1714
|
}
|
|
1614
1715
|
if (item.fileUid && this.fileUidResolverFn) {
|
|
1615
1716
|
this.fileUidResolverFn(item.fileUid);
|
|
1717
|
+
this.push.success('Preparando...');
|
|
1616
1718
|
}
|
|
1617
1719
|
}
|
|
1618
1720
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicFileInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -3708,82 +3810,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
3708
3810
|
type: Input
|
|
3709
3811
|
}] } });
|
|
3710
3812
|
|
|
3711
|
-
let nextId$1 = 1;
|
|
3712
|
-
function createSuccessAlert(message, options) {
|
|
3713
|
-
return {
|
|
3714
|
-
id: nextId$1++,
|
|
3715
|
-
message,
|
|
3716
|
-
icon: 'ri-check-line',
|
|
3717
|
-
showProgressBar: true,
|
|
3718
|
-
type: 'success',
|
|
3719
|
-
duration: 3000,
|
|
3720
|
-
...options,
|
|
3721
|
-
};
|
|
3722
|
-
}
|
|
3723
|
-
function createErrorAlert(message, options) {
|
|
3724
|
-
return {
|
|
3725
|
-
id: nextId$1++,
|
|
3726
|
-
message,
|
|
3727
|
-
showProgressBar: true,
|
|
3728
|
-
type: 'error',
|
|
3729
|
-
icon: 'ri-error-warning-line',
|
|
3730
|
-
duration: 5000,
|
|
3731
|
-
...options,
|
|
3732
|
-
};
|
|
3733
|
-
}
|
|
3734
|
-
function createWarningAlert(message, options) {
|
|
3735
|
-
return {
|
|
3736
|
-
id: nextId$1++,
|
|
3737
|
-
message,
|
|
3738
|
-
showProgressBar: true,
|
|
3739
|
-
type: 'warning',
|
|
3740
|
-
icon: 'ri-alarm-warning-line',
|
|
3741
|
-
duration: 4000,
|
|
3742
|
-
...options,
|
|
3743
|
-
};
|
|
3744
|
-
}
|
|
3745
|
-
function createInfoAlert(message, options) {
|
|
3746
|
-
return {
|
|
3747
|
-
id: nextId$1++,
|
|
3748
|
-
showProgressBar: true,
|
|
3749
|
-
message,
|
|
3750
|
-
icon: 'ri-information-2-line',
|
|
3751
|
-
type: 'info',
|
|
3752
|
-
duration: 3000,
|
|
3753
|
-
...options,
|
|
3754
|
-
};
|
|
3755
|
-
}
|
|
3756
|
-
|
|
3757
|
-
class UicPushAlertService {
|
|
3758
|
-
autoIncId = 0;
|
|
3759
|
-
alerts$ = new Subject();
|
|
3760
|
-
get stream() {
|
|
3761
|
-
return this.alerts$.asObservable();
|
|
3762
|
-
}
|
|
3763
|
-
show(alertData) {
|
|
3764
|
-
this.autoIncId++;
|
|
3765
|
-
const alert = { ...alertData, id: this.autoIncId };
|
|
3766
|
-
this.alerts$.next(alert);
|
|
3767
|
-
}
|
|
3768
|
-
success(message, options) {
|
|
3769
|
-
this.show(createSuccessAlert(message, options));
|
|
3770
|
-
}
|
|
3771
|
-
error(message, options) {
|
|
3772
|
-
this.show(createErrorAlert(message, options));
|
|
3773
|
-
}
|
|
3774
|
-
warning(message, options) {
|
|
3775
|
-
this.show(createWarningAlert(message, options));
|
|
3776
|
-
}
|
|
3777
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicPushAlertService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3778
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicPushAlertService, providedIn: 'root' });
|
|
3779
|
-
}
|
|
3780
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicPushAlertService, decorators: [{
|
|
3781
|
-
type: Injectable,
|
|
3782
|
-
args: [{
|
|
3783
|
-
providedIn: 'root'
|
|
3784
|
-
}]
|
|
3785
|
-
}] });
|
|
3786
|
-
|
|
3787
3813
|
class UicFormStateService {
|
|
3788
3814
|
destroyRef = inject(DestroyRef);
|
|
3789
3815
|
formValueSignal = signal({});
|
|
@@ -4286,25 +4312,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
4286
4312
|
|
|
4287
4313
|
class UicFormWrapperComponent {
|
|
4288
4314
|
fb = inject(FormBuilder);
|
|
4315
|
+
elementRef = inject(ElementRef);
|
|
4289
4316
|
form = this.fb.group({});
|
|
4290
4317
|
effectiveSchema = { cols: 2, blocks: [{ fields: [] }] };
|
|
4291
4318
|
schema;
|
|
4292
4319
|
fields = [];
|
|
4293
4320
|
cols = 2;
|
|
4294
4321
|
externalData = {};
|
|
4322
|
+
selectOptionsResolver;
|
|
4295
4323
|
loading = false;
|
|
4296
4324
|
disabled = false;
|
|
4297
4325
|
showButtons = false;
|
|
4298
4326
|
fillSelects = false;
|
|
4299
4327
|
initialValues = {};
|
|
4328
|
+
focusFieldName = null;
|
|
4329
|
+
focusFieldTrigger = null;
|
|
4300
4330
|
fileUidResolverFn;
|
|
4301
4331
|
formSubmit = new EventEmitter();
|
|
4302
4332
|
formChange = new EventEmitter();
|
|
4333
|
+
optionsSourceError = new EventEmitter();
|
|
4303
4334
|
formValueSub = null;
|
|
4335
|
+
optionSourceSubs = new Map();
|
|
4336
|
+
optionSourceDependencyValueByField = new Map();
|
|
4337
|
+
hasFocusedCurrentTrigger = false;
|
|
4304
4338
|
ngOnInit() {
|
|
4305
4339
|
this.syncEffectiveSchema();
|
|
4306
4340
|
this.buildForm();
|
|
4307
4341
|
this.updateExtenalData();
|
|
4342
|
+
this.updateOptionsSources();
|
|
4308
4343
|
}
|
|
4309
4344
|
ngOnChanges(changes) {
|
|
4310
4345
|
const sourceChanged = (changes['schema'] && !changes['schema'].firstChange) ||
|
|
@@ -4319,18 +4354,30 @@ class UicFormWrapperComponent {
|
|
|
4319
4354
|
if (sourceChanged) {
|
|
4320
4355
|
this.buildForm();
|
|
4321
4356
|
this.updateExtenalData();
|
|
4357
|
+
this.updateOptionsSources();
|
|
4322
4358
|
}
|
|
4323
4359
|
if (changes['externalData']) {
|
|
4324
4360
|
this.updateExtenalData();
|
|
4325
4361
|
}
|
|
4362
|
+
if (changes['selectOptionsResolver'] && !changes['selectOptionsResolver'].firstChange) {
|
|
4363
|
+
this.updateOptionsSources(true);
|
|
4364
|
+
}
|
|
4326
4365
|
if (changes['initialValues'] && !changes['initialValues'].firstChange) {
|
|
4327
4366
|
this.buildForm();
|
|
4328
4367
|
this.updateExtenalData();
|
|
4368
|
+
this.updateOptionsSources();
|
|
4369
|
+
}
|
|
4370
|
+
const focusRequestChanged = (changes['focusFieldName'] && !changes['focusFieldName'].firstChange) ||
|
|
4371
|
+
(changes['focusFieldTrigger'] && !changes['focusFieldTrigger'].firstChange);
|
|
4372
|
+
if (focusRequestChanged) {
|
|
4373
|
+
this.hasFocusedCurrentTrigger = false;
|
|
4374
|
+
this.focusConfiguredField();
|
|
4329
4375
|
}
|
|
4330
4376
|
}
|
|
4331
4377
|
ngOnDestroy() {
|
|
4332
4378
|
this.formValueSub?.unsubscribe();
|
|
4333
4379
|
this.formValueSub = null;
|
|
4380
|
+
this.clearOptionSourceSubscriptions();
|
|
4334
4381
|
}
|
|
4335
4382
|
buildForm() {
|
|
4336
4383
|
this.formValueSub?.unsubscribe();
|
|
@@ -4350,9 +4397,31 @@ class UicFormWrapperComponent {
|
|
|
4350
4397
|
this.formValueSub = newForm.valueChanges.subscribe(() => {
|
|
4351
4398
|
this.normalizeNumericControls(newForm, numericFields);
|
|
4352
4399
|
this.handleFormChange();
|
|
4400
|
+
this.updateDependentOptionsSources();
|
|
4353
4401
|
});
|
|
4354
4402
|
this.form = newForm;
|
|
4403
|
+
this.optionSourceDependencyValueByField.clear();
|
|
4355
4404
|
this.updateDisabledState();
|
|
4405
|
+
this.focusConfiguredField();
|
|
4406
|
+
}
|
|
4407
|
+
focusConfiguredField() {
|
|
4408
|
+
if (!this.focusFieldName || this.hasFocusedCurrentTrigger)
|
|
4409
|
+
return;
|
|
4410
|
+
const fieldName = this.focusFieldName;
|
|
4411
|
+
requestAnimationFrame(() => {
|
|
4412
|
+
const target = this.findFocusableFieldElement(fieldName);
|
|
4413
|
+
if (!target)
|
|
4414
|
+
return;
|
|
4415
|
+
this.hasFocusedCurrentTrigger = true;
|
|
4416
|
+
target.focus();
|
|
4417
|
+
if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {
|
|
4418
|
+
target.select();
|
|
4419
|
+
}
|
|
4420
|
+
});
|
|
4421
|
+
}
|
|
4422
|
+
findFocusableFieldElement(fieldName) {
|
|
4423
|
+
const focusableElements = this.elementRef.nativeElement.querySelectorAll('input, textarea, select, button, [tabindex]');
|
|
4424
|
+
return Array.from(focusableElements).find(element => element.id === fieldName) ?? null;
|
|
4356
4425
|
}
|
|
4357
4426
|
updateDisabledState() {
|
|
4358
4427
|
if (!this.form)
|
|
@@ -4412,12 +4481,210 @@ class UicFormWrapperComponent {
|
|
|
4412
4481
|
updateFieldOptions(block) {
|
|
4413
4482
|
return block.fields.map(field => {
|
|
4414
4483
|
if (field.type === 'select' || field.type === 'pool' || field.type === 'multyselect') {
|
|
4484
|
+
if (this.hasUsableOptionsSource(field)) {
|
|
4485
|
+
return field;
|
|
4486
|
+
}
|
|
4415
4487
|
const externalOptions = this.externalData?.[field.name];
|
|
4416
4488
|
return { ...field, options: Array.isArray(externalOptions) ? externalOptions : (field.options ?? []) };
|
|
4417
4489
|
}
|
|
4418
4490
|
return field;
|
|
4419
4491
|
});
|
|
4420
4492
|
}
|
|
4493
|
+
updateOptionsSources(force = false) {
|
|
4494
|
+
const fields = this.collectAllFields().filter(field => this.hasUsableOptionsSource(field));
|
|
4495
|
+
const fieldNames = new Set(fields.map(field => field.name));
|
|
4496
|
+
for (const fieldName of this.optionSourceSubs.keys()) {
|
|
4497
|
+
if (!fieldNames.has(fieldName)) {
|
|
4498
|
+
this.optionSourceSubs.get(fieldName)?.unsubscribe();
|
|
4499
|
+
this.optionSourceSubs.delete(fieldName);
|
|
4500
|
+
this.optionSourceDependencyValueByField.delete(fieldName);
|
|
4501
|
+
}
|
|
4502
|
+
}
|
|
4503
|
+
fields.forEach(field => this.resolveOptionsSourceField(field, force));
|
|
4504
|
+
}
|
|
4505
|
+
updateDependentOptionsSources() {
|
|
4506
|
+
const fields = this.collectAllFields().filter(field => {
|
|
4507
|
+
const source = field.optionsSource;
|
|
4508
|
+
return this.hasUsableOptionsSource(field) && !!source?.dependsOn;
|
|
4509
|
+
});
|
|
4510
|
+
fields.forEach(field => this.resolveOptionsSourceField(field));
|
|
4511
|
+
}
|
|
4512
|
+
resolveOptionsSourceField(field, force = false) {
|
|
4513
|
+
const source = field.optionsSource;
|
|
4514
|
+
if (!source?.key)
|
|
4515
|
+
return;
|
|
4516
|
+
if (!this.selectOptionsResolver) {
|
|
4517
|
+
this.updateFieldOptionsState(field.name, {
|
|
4518
|
+
options: field.options ?? [],
|
|
4519
|
+
loading: false
|
|
4520
|
+
});
|
|
4521
|
+
return;
|
|
4522
|
+
}
|
|
4523
|
+
const values = this.toNestedValues(this.form?.getRawValue?.() ?? {});
|
|
4524
|
+
const dependencyValue = source.dependsOn ? this.getValueByPath(values, source.dependsOn) : undefined;
|
|
4525
|
+
const dependencyKey = source.dependsOn ? `${source.dependsOn}:${this.safeStringify(dependencyValue ?? null)}` : '__init__';
|
|
4526
|
+
const previousDependencyKey = this.optionSourceDependencyValueByField.get(field.name);
|
|
4527
|
+
if (!force && previousDependencyKey === dependencyKey) {
|
|
4528
|
+
return;
|
|
4529
|
+
}
|
|
4530
|
+
this.optionSourceDependencyValueByField.set(field.name, dependencyKey);
|
|
4531
|
+
if (source.dependsOn && (dependencyValue === null || dependencyValue === undefined || dependencyValue === '')) {
|
|
4532
|
+
this.optionSourceSubs.get(field.name)?.unsubscribe();
|
|
4533
|
+
this.optionSourceSubs.delete(field.name);
|
|
4534
|
+
this.clearFieldValue(field);
|
|
4535
|
+
this.updateFieldOptionsState(field.name, { options: [], loading: false });
|
|
4536
|
+
return;
|
|
4537
|
+
}
|
|
4538
|
+
this.optionSourceSubs.get(field.name)?.unsubscribe();
|
|
4539
|
+
this.updateFieldOptionsState(field.name, { loading: true });
|
|
4540
|
+
let optionsResult;
|
|
4541
|
+
try {
|
|
4542
|
+
optionsResult = this.selectOptionsResolver(source, {
|
|
4543
|
+
field,
|
|
4544
|
+
values,
|
|
4545
|
+
dependencyValue
|
|
4546
|
+
});
|
|
4547
|
+
}
|
|
4548
|
+
catch (error) {
|
|
4549
|
+
this.handleOptionsSourceError(field, source, error);
|
|
4550
|
+
return;
|
|
4551
|
+
}
|
|
4552
|
+
const sub = this.toObservable(optionsResult).subscribe({
|
|
4553
|
+
next: items => {
|
|
4554
|
+
const options = this.mapOptionsSourceItems(items, source);
|
|
4555
|
+
this.updateFieldOptionsState(field.name, { options, loading: false });
|
|
4556
|
+
this.clearInvalidFieldValue(field.name, options);
|
|
4557
|
+
},
|
|
4558
|
+
error: error => this.handleOptionsSourceError(field, source, error),
|
|
4559
|
+
complete: () => this.updateFieldOptionsState(field.name, { loading: false })
|
|
4560
|
+
});
|
|
4561
|
+
this.optionSourceSubs.set(field.name, sub);
|
|
4562
|
+
}
|
|
4563
|
+
handleOptionsSourceError(field, source, error) {
|
|
4564
|
+
this.updateFieldOptionsState(field.name, { options: [], loading: false });
|
|
4565
|
+
this.optionsSourceError.emit({ field, source, error });
|
|
4566
|
+
}
|
|
4567
|
+
toObservable(value) {
|
|
4568
|
+
if (isObservable(value)) {
|
|
4569
|
+
return value;
|
|
4570
|
+
}
|
|
4571
|
+
if (value instanceof Promise) {
|
|
4572
|
+
return from(value);
|
|
4573
|
+
}
|
|
4574
|
+
return of(value ?? []);
|
|
4575
|
+
}
|
|
4576
|
+
mapOptionsSourceItems(items, source) {
|
|
4577
|
+
if (!Array.isArray(items))
|
|
4578
|
+
return [];
|
|
4579
|
+
return items.map(item => this.mapOptionsSourceItem(item, source));
|
|
4580
|
+
}
|
|
4581
|
+
mapOptionsSourceItem(item, source) {
|
|
4582
|
+
if (item && typeof item === 'object') {
|
|
4583
|
+
const record = item;
|
|
4584
|
+
const id = this.getValueByPath(record, source.idField?.trim() || 'id');
|
|
4585
|
+
const fallbackText = this.getValueByPath(record, source.textField?.trim() || 'text');
|
|
4586
|
+
const optionId = this.isValidOptionId(id)
|
|
4587
|
+
? id
|
|
4588
|
+
: this.isValidOptionId(fallbackText)
|
|
4589
|
+
? fallbackText
|
|
4590
|
+
: String(fallbackText ?? '');
|
|
4591
|
+
return {
|
|
4592
|
+
detail: typeof record['detail'] === 'string' ? record['detail'] : undefined,
|
|
4593
|
+
icon: typeof record['icon'] === 'string' ? record['icon'] : undefined,
|
|
4594
|
+
iconColor: typeof record['iconColor'] === 'string' ? record['iconColor'] : undefined,
|
|
4595
|
+
id: optionId,
|
|
4596
|
+
text: source.textTemplate
|
|
4597
|
+
? this.renderOptionsSourceTemplate(source.textTemplate, record)
|
|
4598
|
+
: String(fallbackText ?? id ?? '')
|
|
4599
|
+
};
|
|
4600
|
+
}
|
|
4601
|
+
return {
|
|
4602
|
+
id: String(item ?? ''),
|
|
4603
|
+
text: String(item ?? '')
|
|
4604
|
+
};
|
|
4605
|
+
}
|
|
4606
|
+
renderOptionsSourceTemplate(template, item) {
|
|
4607
|
+
return template.replace(/\{\{\s*([\w.]+)\s*\}\}/g, (_match, path) => {
|
|
4608
|
+
const value = this.getValueByPath(item, path);
|
|
4609
|
+
return value === null || value === undefined ? '' : String(value);
|
|
4610
|
+
});
|
|
4611
|
+
}
|
|
4612
|
+
updateFieldOptionsState(fieldName, values) {
|
|
4613
|
+
if (!this.effectiveSchema?.blocks?.length)
|
|
4614
|
+
return;
|
|
4615
|
+
for (const block of this.effectiveSchema.blocks) {
|
|
4616
|
+
const index = block.fields.findIndex(field => field.name === fieldName);
|
|
4617
|
+
if (index === -1)
|
|
4618
|
+
continue;
|
|
4619
|
+
const field = block.fields[index];
|
|
4620
|
+
block.fields[index] = {
|
|
4621
|
+
...field,
|
|
4622
|
+
...(values.options !== undefined ? { options: values.options } : {}),
|
|
4623
|
+
...(values.loading !== undefined ? { loading: values.loading } : {})
|
|
4624
|
+
};
|
|
4625
|
+
block.fields = [...block.fields];
|
|
4626
|
+
this.effectiveSchema.blocks = [...this.effectiveSchema.blocks];
|
|
4627
|
+
return;
|
|
4628
|
+
}
|
|
4629
|
+
}
|
|
4630
|
+
clearInvalidFieldValue(fieldName, options) {
|
|
4631
|
+
const control = this.getFieldControl(fieldName);
|
|
4632
|
+
if (!control)
|
|
4633
|
+
return;
|
|
4634
|
+
const currentValue = control.value;
|
|
4635
|
+
if (currentValue === null || currentValue === undefined || currentValue === '')
|
|
4636
|
+
return;
|
|
4637
|
+
if (Array.isArray(currentValue)) {
|
|
4638
|
+
const validIds = new Set(options.map(option => option.id));
|
|
4639
|
+
const filteredValue = currentValue.filter(value => validIds.has(value));
|
|
4640
|
+
if (filteredValue.length !== currentValue.length) {
|
|
4641
|
+
control.setValue(filteredValue, { emitEvent: false });
|
|
4642
|
+
this.handleFormChange();
|
|
4643
|
+
}
|
|
4644
|
+
return;
|
|
4645
|
+
}
|
|
4646
|
+
if (!options.some(option => option.id === currentValue)) {
|
|
4647
|
+
control.setValue(null, { emitEvent: false });
|
|
4648
|
+
this.handleFormChange();
|
|
4649
|
+
}
|
|
4650
|
+
}
|
|
4651
|
+
clearFieldValue(field) {
|
|
4652
|
+
const control = this.getFieldControl(field.name);
|
|
4653
|
+
if (!control)
|
|
4654
|
+
return;
|
|
4655
|
+
const blankValue = this.blankValue(field);
|
|
4656
|
+
if (control.value !== blankValue) {
|
|
4657
|
+
control.setValue(blankValue, { emitEvent: false });
|
|
4658
|
+
this.handleFormChange();
|
|
4659
|
+
}
|
|
4660
|
+
}
|
|
4661
|
+
hasUsableOptionsSource(field) {
|
|
4662
|
+
return this.supportsOptions(field) && !!field.optionsSource?.key?.trim();
|
|
4663
|
+
}
|
|
4664
|
+
supportsOptions(field) {
|
|
4665
|
+
return field.type === 'select' || field.type === 'pool' || field.type === 'multyselect' || field.type === 'radio';
|
|
4666
|
+
}
|
|
4667
|
+
isValidOptionId(value) {
|
|
4668
|
+
return typeof value === 'string' || typeof value === 'number' || value === null;
|
|
4669
|
+
}
|
|
4670
|
+
getValueByPath(source, path) {
|
|
4671
|
+
if (!path)
|
|
4672
|
+
return undefined;
|
|
4673
|
+
return path.split('.').reduce((current, key) => current?.[key], source);
|
|
4674
|
+
}
|
|
4675
|
+
safeStringify(value) {
|
|
4676
|
+
try {
|
|
4677
|
+
return JSON.stringify(value);
|
|
4678
|
+
}
|
|
4679
|
+
catch {
|
|
4680
|
+
return String(value);
|
|
4681
|
+
}
|
|
4682
|
+
}
|
|
4683
|
+
clearOptionSourceSubscriptions() {
|
|
4684
|
+
this.optionSourceSubs.forEach(sub => sub.unsubscribe());
|
|
4685
|
+
this.optionSourceSubs.clear();
|
|
4686
|
+
this.optionSourceDependencyValueByField.clear();
|
|
4687
|
+
}
|
|
4421
4688
|
collectAllFields() {
|
|
4422
4689
|
return (this.effectiveSchema?.blocks ?? []).flatMap(block => block.fields ?? []);
|
|
4423
4690
|
}
|
|
@@ -4673,7 +4940,7 @@ class UicFormWrapperComponent {
|
|
|
4673
4940
|
};
|
|
4674
4941
|
}
|
|
4675
4942
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicFormWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4676
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: UicFormWrapperComponent, isStandalone: true, selector: "ui-form-wrapper", inputs: { schema: "schema", fields: "fields", cols: "cols", externalData: "externalData", loading: "loading", disabled: "disabled", showButtons: "showButtons", fillSelects: "fillSelects", initialValues: "initialValues", fileUidResolverFn: "fileUidResolverFn" }, outputs: { formSubmit: "formSubmit", formChange: "formChange" }, providers: [UicFormStateService], usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"form\" (ngSubmit)=\"handleSubmit()\">\r\n @for (block of effectiveSchema.blocks; track $index) {\r\n \r\n <section class=\"form-block\">\r\n @if (block.title){\r\n <div class=\"block-title\">{{ block.title }}</div>\r\n }\r\n @if (block.subtitle){\r\n <div class=\"block-subtitle\">{{ block.subtitle }}</div>\r\n }\r\n @if (loading) {\r\n <ui-skeleton-loader\r\n [cols]=\"effectiveSchema.cols\"\r\n [inputs]=\"block.fields.length\"\r\n ></ui-skeleton-loader>\r\n } @else {\r\n <ui-dynamic-form\n [cols]=\"effectiveSchema.cols\"\n [disabled]=\"disabled\"\n [fileUidResolverFn]=\"fileUidResolverFn\"\n [fields]=\"block.fields\"\n [form]=\"form\">\n </ui-dynamic-form>\n }\r\n </section>\r\n }\r\n @if ( showButtons ) {\r\n\r\n <div class=\"form-buttons\">\r\n <ui-button color=\"black\" type=\"bordered\" (click)=\"clean()\">{{'common.clear' | uicTranslate}}</ui-button>\r\n <ui-button color=\"black\" (click)=\"submit()\">{{'common.save' | uicTranslate}}</ui-button>\r\n </div>\r\n }\r\n</form>\r\n", styles: [":host{display:block;padding:.25rem 0}.block-title{font-size:1.625rem;font-weight:600;line-height:calc(1.625rem + 4px);margin:1rem 0;color:var(--grey-950)}.block-subtitle{font-size:1.25rem;font-weight:600;line-height:calc(1.25rem + 4px);margin:.75rem 0;color:var(--grey-950)}.form-buttons{display:flex;gap:10px;width:100%}\n"], dependencies: [{ kind: "component", type: UicDynamicFormComponent, selector: "ui-dynamic-form", inputs: ["fields", "form", "disabled", "voiceToTextSilenceMs", "cols", "fileUidResolverFn"] }, { kind: "component", type: UicSkeletonLoaderComponent, selector: "ui-skeleton-loader", inputs: ["inputs", "cols"] }, { kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }] });
|
|
4943
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: UicFormWrapperComponent, isStandalone: true, selector: "ui-form-wrapper", inputs: { schema: "schema", fields: "fields", cols: "cols", externalData: "externalData", selectOptionsResolver: "selectOptionsResolver", loading: "loading", disabled: "disabled", showButtons: "showButtons", fillSelects: "fillSelects", initialValues: "initialValues", focusFieldName: "focusFieldName", focusFieldTrigger: "focusFieldTrigger", fileUidResolverFn: "fileUidResolverFn" }, outputs: { formSubmit: "formSubmit", formChange: "formChange", optionsSourceError: "optionsSourceError" }, providers: [UicFormStateService], usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"form\" (ngSubmit)=\"handleSubmit()\">\r\n @for (block of effectiveSchema.blocks; track $index) {\r\n \r\n <section class=\"form-block\">\r\n @if (block.title){\r\n <div class=\"block-title\">{{ block.title }}</div>\r\n }\r\n @if (block.subtitle){\r\n <div class=\"block-subtitle\">{{ block.subtitle }}</div>\r\n }\r\n @if (loading) {\r\n <ui-skeleton-loader\r\n [cols]=\"effectiveSchema.cols\"\r\n [inputs]=\"block.fields.length\"\r\n ></ui-skeleton-loader>\r\n } @else {\r\n <ui-dynamic-form\n [cols]=\"effectiveSchema.cols\"\n [disabled]=\"disabled\"\n [fileUidResolverFn]=\"fileUidResolverFn\"\n [fields]=\"block.fields\"\n [form]=\"form\">\n </ui-dynamic-form>\n }\r\n </section>\r\n }\r\n @if ( showButtons ) {\r\n\r\n <div class=\"form-buttons\">\r\n <ui-button color=\"black\" type=\"bordered\" (click)=\"clean()\">{{'common.clear' | uicTranslate}}</ui-button>\r\n <ui-button color=\"black\" (click)=\"submit()\">{{'common.save' | uicTranslate}}</ui-button>\r\n </div>\r\n }\r\n</form>\r\n", styles: [":host{display:block;padding:.25rem 0}.block-title{font-size:1.625rem;font-weight:600;line-height:calc(1.625rem + 4px);margin:1rem 0;color:var(--grey-950)}.block-subtitle{font-size:1.25rem;font-weight:600;line-height:calc(1.25rem + 4px);margin:.75rem 0;color:var(--grey-950)}.form-buttons{display:flex;gap:10px;width:100%}\n"], dependencies: [{ kind: "component", type: UicDynamicFormComponent, selector: "ui-dynamic-form", inputs: ["fields", "form", "disabled", "voiceToTextSilenceMs", "cols", "fileUidResolverFn"] }, { kind: "component", type: UicSkeletonLoaderComponent, selector: "ui-skeleton-loader", inputs: ["inputs", "cols"] }, { kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }] });
|
|
4677
4944
|
}
|
|
4678
4945
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicFormWrapperComponent, decorators: [{
|
|
4679
4946
|
type: Component,
|
|
@@ -4692,6 +4959,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
4692
4959
|
type: Input
|
|
4693
4960
|
}], externalData: [{
|
|
4694
4961
|
type: Input
|
|
4962
|
+
}], selectOptionsResolver: [{
|
|
4963
|
+
type: Input
|
|
4695
4964
|
}], loading: [{
|
|
4696
4965
|
type: Input
|
|
4697
4966
|
}], disabled: [{
|
|
@@ -4702,12 +4971,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
4702
4971
|
type: Input
|
|
4703
4972
|
}], initialValues: [{
|
|
4704
4973
|
type: Input
|
|
4974
|
+
}], focusFieldName: [{
|
|
4975
|
+
type: Input
|
|
4976
|
+
}], focusFieldTrigger: [{
|
|
4977
|
+
type: Input
|
|
4705
4978
|
}], fileUidResolverFn: [{
|
|
4706
4979
|
type: Input
|
|
4707
4980
|
}], formSubmit: [{
|
|
4708
4981
|
type: Output
|
|
4709
4982
|
}], formChange: [{
|
|
4710
4983
|
type: Output
|
|
4984
|
+
}], optionsSourceError: [{
|
|
4985
|
+
type: Output
|
|
4711
4986
|
}] } });
|
|
4712
4987
|
|
|
4713
4988
|
class UicStepTabsComponent {
|
|
@@ -4819,7 +5094,7 @@ class UicStepsFormComponent {
|
|
|
4819
5094
|
return this.currentIdx === this.steps.length - 1;
|
|
4820
5095
|
}
|
|
4821
5096
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicStepsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4822
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: UicStepsFormComponent, isStandalone: true, selector: "ui-steps-form", inputs: { steps: "steps", navigationEnabled: "navigationEnabled", showStepTitle: "showStepTitle", showButtons: "showButtons", buttonsColor: "buttonsColor" }, outputs: { formSubmit: "formSubmit" }, viewQueries: [{ propertyName: "allForms", predicate: UicFormWrapperComponent, descendants: true }], ngImport: i0, template: "<ui-step-tabs \r\n [(currentTab)]=\"currentTabTitle\" \r\n [navigationEnabled]=\"navigationEnabled\"\r\n [showStepTitle]=\"showStepTitle\"\r\n [tabs]=\"tabs\"></ui-step-tabs>\r\n\r\n\r\n<!-- formulario -->\r\n@for (step of steps; track $index) {\r\n <div [class.hidden-form]=\"step.title!==currentTabTitle\" >\r\n <ui-form-wrapper [schema]=\"step.form\" \r\n [externalData]=\"externalData\"\r\n [disabled]=\"formDisabled\"\r\n [loading]=\"loading\"></ui-form-wrapper>\r\n </div>\r\n}\r\n\r\n@if (showButtons) {\r\n <div style=\"display: flex; gap: 10px;\">\r\n <ui-button [color]=\"buttonsColor\" type=\"bordered\" [disabled]=\"isFirst\" (click)=\"back()\" >{{'step_form.back' | uicTranslate}}</ui-button>\r\n <ui-button [color]=\"buttonsColor\" (click)=\"next()\">{{isLast?('step_form.submit' | uicTranslate):('step_form.next' | uicTranslate)}}</ui-button>\r\n </div>\r\n}\r\n", styles: [".hidden-form{display:none}\n"], dependencies: [{ kind: "component", type: UicStepTabsComponent, selector: "ui-step-tabs", inputs: ["tabs", "currentTab", "navigationEnabled", "showStepTitle"], outputs: ["currentTabChange"] }, { kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "component", type: UicFormWrapperComponent, selector: "ui-form-wrapper", inputs: ["schema", "fields", "cols", "externalData", "loading", "disabled", "showButtons", "fillSelects", "initialValues", "fileUidResolverFn"], outputs: ["formSubmit", "formChange"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }] });
|
|
5097
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: UicStepsFormComponent, isStandalone: true, selector: "ui-steps-form", inputs: { steps: "steps", navigationEnabled: "navigationEnabled", showStepTitle: "showStepTitle", showButtons: "showButtons", buttonsColor: "buttonsColor" }, outputs: { formSubmit: "formSubmit" }, viewQueries: [{ propertyName: "allForms", predicate: UicFormWrapperComponent, descendants: true }], ngImport: i0, template: "<ui-step-tabs \r\n [(currentTab)]=\"currentTabTitle\" \r\n [navigationEnabled]=\"navigationEnabled\"\r\n [showStepTitle]=\"showStepTitle\"\r\n [tabs]=\"tabs\"></ui-step-tabs>\r\n\r\n\r\n<!-- formulario -->\r\n@for (step of steps; track $index) {\r\n <div [class.hidden-form]=\"step.title!==currentTabTitle\" >\r\n <ui-form-wrapper [schema]=\"step.form\" \r\n [externalData]=\"externalData\"\r\n [disabled]=\"formDisabled\"\r\n [loading]=\"loading\"></ui-form-wrapper>\r\n </div>\r\n}\r\n\r\n@if (showButtons) {\r\n <div style=\"display: flex; gap: 10px;\">\r\n <ui-button [color]=\"buttonsColor\" type=\"bordered\" [disabled]=\"isFirst\" (click)=\"back()\" >{{'step_form.back' | uicTranslate}}</ui-button>\r\n <ui-button [color]=\"buttonsColor\" (click)=\"next()\">{{isLast?('step_form.submit' | uicTranslate):('step_form.next' | uicTranslate)}}</ui-button>\r\n </div>\r\n}\r\n", styles: [".hidden-form{display:none}\n"], dependencies: [{ kind: "component", type: UicStepTabsComponent, selector: "ui-step-tabs", inputs: ["tabs", "currentTab", "navigationEnabled", "showStepTitle"], outputs: ["currentTabChange"] }, { kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "component", type: UicFormWrapperComponent, selector: "ui-form-wrapper", inputs: ["schema", "fields", "cols", "externalData", "selectOptionsResolver", "loading", "disabled", "showButtons", "fillSelects", "initialValues", "focusFieldName", "focusFieldTrigger", "fileUidResolverFn"], outputs: ["formSubmit", "formChange", "optionsSourceError"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }] });
|
|
4823
5098
|
}
|
|
4824
5099
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicStepsFormComponent, decorators: [{
|
|
4825
5100
|
type: Component,
|
|
@@ -6983,7 +7258,9 @@ class UicTreeAdminComponent {
|
|
|
6983
7258
|
{
|
|
6984
7259
|
id: 11,
|
|
6985
7260
|
enabled: true,
|
|
6986
|
-
name: 'Miembro 3'
|
|
7261
|
+
name: 'Miembro 3',
|
|
7262
|
+
tag: 'Admin',
|
|
7263
|
+
tagColor: 'red'
|
|
6987
7264
|
},
|
|
6988
7265
|
{
|
|
6989
7266
|
id: 12,
|
|
@@ -7108,14 +7385,20 @@ class UicTreeAdminComponent {
|
|
|
7108
7385
|
clearFilter() {
|
|
7109
7386
|
this.filterTerm = '';
|
|
7110
7387
|
}
|
|
7388
|
+
getVisibleTree() {
|
|
7389
|
+
if (!this.hasActiveFilter()) {
|
|
7390
|
+
return this.tree;
|
|
7391
|
+
}
|
|
7392
|
+
return this.tree.filter((item) => this.getFilteredChildren(item).length > 0);
|
|
7393
|
+
}
|
|
7111
7394
|
getFilteredChildren(item) {
|
|
7112
7395
|
if (!item.children?.length) {
|
|
7113
7396
|
return [];
|
|
7114
7397
|
}
|
|
7115
|
-
|
|
7116
|
-
if (!term) {
|
|
7398
|
+
if (!this.hasActiveFilter()) {
|
|
7117
7399
|
return item.children;
|
|
7118
7400
|
}
|
|
7401
|
+
const term = this.filterTerm.trim().toLowerCase();
|
|
7119
7402
|
return item.children.filter((child) => child.name.toLowerCase().includes(term));
|
|
7120
7403
|
}
|
|
7121
7404
|
finalizeParentEdit(item) {
|
|
@@ -7245,6 +7528,9 @@ class UicTreeAdminComponent {
|
|
|
7245
7528
|
}
|
|
7246
7529
|
return parent.children.some((child) => child.id !== subitem.id && child.name.trim().toLowerCase() === trimmed);
|
|
7247
7530
|
}
|
|
7531
|
+
hasActiveFilter() {
|
|
7532
|
+
return this.filterTerm.trim().length > 0;
|
|
7533
|
+
}
|
|
7248
7534
|
cleanupPendingCreateIds() {
|
|
7249
7535
|
if (!this.pendingCreateIds.size) {
|
|
7250
7536
|
return;
|
|
@@ -7264,7 +7550,7 @@ class UicTreeAdminComponent {
|
|
|
7264
7550
|
}
|
|
7265
7551
|
}
|
|
7266
7552
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicTreeAdminComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7267
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: UicTreeAdminComponent, isStandalone: true, selector: "ui-tree-admin", inputs: { searchEnabled: "searchEnabled", loading: "loading", emptyMessage: "emptyMessage", duplicateNameMessage: "duplicateNameMessage", tree: "tree" }, outputs: { edit: "edit", remove: "remove", deactivate: "deactivate", nameChange: "nameChange", create: "create" }, viewQueries: [{ propertyName: "childNameInputs", predicate: ["childNameInput"], descendants: true }, { propertyName: "parentNameInputs", predicate: ["parentNameInput"], descendants: true }], ngImport: i0, template: "@if (loading) {\r\n <div class=\"tree-skeleton\">\r\n <ui-skeleton-loader [inputs]=\"4\" [cols]=\"1\"></ui-skeleton-loader>\r\n </div>\r\n} @else {\r\n @if (searchEnabled) {\r\n <div class=\"filter-bar\">\r\n {{'tree.search_label' | uicTranslate}}\r\n <ui-input>\r\n <input #inp [placeholder]=\"'tree.search_placeholder' | uicTranslate\" [value]=\"filterTerm\" (input)=\"updateFilter($event)\">\r\n </ui-input>\r\n <ui-button\r\n [iconOnly]=\"true\"\r\n icon=\"ri-eraser-line\"\r\n type=\"bordered\"\r\n color=\"black\"\r\n [disabled]=\"!filterTerm\"\r\n (click)=\"clearFilter(); inp.focus()\"\r\n ></ui-button>\r\n </div>\r\n }\r\n @for (item of tree; track item.id) {\r\n <div class=\"tree-item\" [class.is-collapsed]=\"!isExpanded(item)\">\r\n <div class=\"tree-header\" (click)=\"toggleItem(item)\">\r\n <i class=\"ri-arrow-down-s-line tree-arrow\" [class.is-collapsed]=\"!isExpanded(item)\"></i>\r\n <div class=\"tree-header-name\">\r\n @if (isEditingParent(item)) {\r\n <input\r\n #parentNameInput\r\n class=\"tree-name-input\"\r\n [attr.data-id]=\"item.id\"\r\n [value]=\"item.name\"\r\n (input)=\"updateParentName(item, $event)\"\r\n (blur)=\"finalizeParentEdit(item)\"\r\n (keydown.enter)=\"finalizeParentEdit(item)\"\r\n (keydown.escape)=\"cancelParentEdit(item)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n } @else {\r\n <div class=\"tree-name-text\" (click)=\"startEditParent(item, $event)\">\r\n {{item.name}}\r\n </div>\r\n }\r\n <span>{{item.children?.length || 0}}</span>\r\n </div>\r\n <div>\r\n <ui-switch\r\n [checked]=\"item.enabled\"\r\n (click)=\"$event.stopPropagation()\"\r\n (checkedChange)=\"emitDeactivateParent(item, $event)\"\r\n ></ui-switch>\r\n </div>\r\n <ui-button (click)=\"addSubItem(item, $event)\" icon=\"ri-add-line\" type=\"ghost\" [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n <ui-button (click)=\"emitEditParent(item, $event)\" icon=\"ri-edit-line\" type=\"ghost\" [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n @if (!item.children?.length) {\r\n <ui-button (click)=\"emitDeleteParent(item, $event)\" icon=\"ri-delete-bin-line\" type=\"ghost\" [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n }\r\n </div>\r\n <div class=\"tree-body\">\r\n @if (getFilteredChildren(item).length) {\r\n @for (subitem of getFilteredChildren(item); track subitem.id) {\r\n <div\r\n class=\"tree-subitem\"\r\n [class.is-disabled]=\"!subitem.enabled\"\r\n [class.is-pending]=\"isPendingCreate(subitem)\"\r\n [class.is-parent-disabled]=\"!item.enabled\"\r\n >\r\n <div class=\"tree-subitem-name\">\r\n <i\r\n class=\"ri-circle-fill tree-subitem-status\"\r\n [class.is-enabled]=\"subitem.enabled\"\r\n [class.is-disabled]=\"!subitem.enabled\"\r\n ></i>\r\n @if (isEditingChild(subitem)) {\r\n <input\r\n #childNameInput\r\n class=\"tree-name-input tree-name-input--sub\"\r\n [attr.data-id]=\"subitem.id\"\r\n [value]=\"subitem.name\"\r\n (input)=\"updateChildName(item, subitem, $event)\"\r\n (blur)=\"finalizeChildEdit(item, subitem)\"\r\n (keydown.enter)=\"finalizeChildEdit(item, subitem)\"\r\n (keydown.escape)=\"cancelChildEdit(item, subitem)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n } @else {\r\n <span\r\n class=\"tree-name-text\"\r\n (click)=\"!isPendingCreate(subitem) && startEditChild(subitem, $event)\"\r\n >{{subitem.name}}</span>\r\n }\r\n </div>\r\n <div class=\"tree-subitem-actions\">\r\n <ui-switch\r\n [checked]=\"subitem.enabled\"\r\n [disabled]=\"isPendingCreate(subitem)\"\r\n (checkedChange)=\"emitDeactivateChild(item, subitem, $event)\"\r\n ></ui-switch>\r\n <ui-button\r\n (click)=\"emitEditChild(item, subitem, $event)\"\r\n [disabled]=\"isPendingCreate(subitem)\"\r\n icon=\"ri-edit-line\"\r\n type=\"ghost\"\r\n [iconOnly]=\"true\"\r\n size=\"s\"\r\n ></ui-button>\r\n <ui-button \r\n (click)=\"emitDeleteChild(item, subitem, $event)\" \r\n icon=\"ri-delete-bin-line\" \r\n [disabled]=\"isPendingCreate(subitem)\"\r\n type=\"ghost\" \r\n [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n </div>\r\n </div>\r\n }\r\n } @else {\r\n <div class=\"tree-empty\">\r\n {{emptyMessage | uicTranslate}}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n}\r\n\r\n", styles: [":host{width:100%}.tree-item{border:solid 1px var(--grey-400);border-radius:10px;overflow:hidden;margin-bottom:4px;background:linear-gradient(180deg,var(--grey-100) 0%,var(--grey-50) 100%);transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.tree-header{width:100%;display:flex;align-items:center;gap:5px;padding:4px 10px;border-bottom:solid 1px var(--grey-400);background-color:var(--grey-100);cursor:pointer;transition:background-color .16s ease}.tree-header:hover{background-color:var(--grey-200)}.tree-header-name{flex:1 1;display:flex;align-items:center;gap:10px}.tree-header-name span{border-radius:10px;padding:2px 10px;font-size:10px;color:var(--blue-800);background-color:var(--blue-100)}.tree-arrow{transition:transform .18s ease}.tree-arrow.is-collapsed{transform:rotate(-90deg)}.tree-body{background-color:var(--white);padding:2px 16px;display:flex;flex-direction:column;gap:1px;max-height:600px;opacity:1;transition:max-height .2s ease,opacity .2s ease,padding .2s ease}.tree-empty{padding:8px 10px;font-size:12px;color:var(--grey-500);background-color:var(--grey-50);border-radius:8px}.tree-subitem{color:var(--grey-700);border-radius:5px;padding:3px 15px;gap:5px;font-size:13px;display:flex;align-items:center;justify-content:space-between}.tree-subitem-name{flex:1 1;display:inline-flex;align-items:center;gap:6px}.tree-subitem-status{font-size:10px;color:var(--grey-400)}.tree-subitem-status.is-enabled{color:var(--blue-500)}.tree-subitem-status.is-disabled{color:var(--grey-400)}.tree-subitem-actions{display:inline-flex;align-items:center;gap:4px;opacity:0;pointer-events:none;transform:translateY(-2px);transition:opacity .16s ease,transform .16s ease}.tree-subitem:hover{background-color:var(--blue-100)}.tree-subitem:hover .tree-subitem-actions{opacity:1;pointer-events:auto;transform:translateY(0)}.tree-subitem.is-disabled .tree-name-text,.tree-subitem.is-disabled .tree-name-input,.tree-subitem.is-parent-disabled .tree-name-text,.tree-subitem.is-parent-disabled .tree-name-input{color:var(--grey-500)}.tree-subitem.is-parent-disabled .tree-subitem-status{color:var(--grey-400)}.tree-subitem.is-pending .tree-name-text{cursor:default;color:var(--grey-500)}.tree-name-text{width:50%;color:var(--grey-900);cursor:text}.filter-bar{display:flex;gap:10px;align-items:center;margin-bottom:10px;font-size:14px}.filter-bar input{flex:1 1}.tree-name-input{flex:1 1;min-width:0;border:solid 1px var(--grey-300);border-radius:6px;padding:7px;font-size:13px;color:var(--grey-900);background-color:var(--white);outline:none;transition:border-color .16s ease,box-shadow .16s ease;width:300px}.tree-name-input:focus{border-color:var(--blue-500);box-shadow:0 0 0 2px #3b82f626}.tree-name-input--sub{font-size:12px;padding:5px}.tree-item.is-collapsed .tree-body{max-height:0;opacity:0;padding-top:0;padding-bottom:0;overflow:hidden}.tree-skeleton{padding:8px;border:solid 1px var(--grey-400);border-radius:10px;background-color:var(--grey-50)}\n"], dependencies: [{ kind: "component", type: UicInputComponent, selector: "ui-input", inputs: ["icon", "iconColor", "internalIcon", "internalIconColor", "size", "label", "error", "tip", "disabled", "loading"], outputs: ["clickButton"] }, { kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "component", type: UicSkeletonLoaderComponent, selector: "ui-skeleton-loader", inputs: ["inputs", "cols"] }, { kind: "component", type: UicSwichComponent, selector: "ui-switch", inputs: ["checked", "disabled", "placeholder", "label"], outputs: ["checkedChange"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }] });
|
|
7553
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: UicTreeAdminComponent, isStandalone: true, selector: "ui-tree-admin", inputs: { searchEnabled: "searchEnabled", loading: "loading", emptyMessage: "emptyMessage", duplicateNameMessage: "duplicateNameMessage", tree: "tree" }, outputs: { edit: "edit", remove: "remove", deactivate: "deactivate", nameChange: "nameChange", create: "create" }, viewQueries: [{ propertyName: "childNameInputs", predicate: ["childNameInput"], descendants: true }, { propertyName: "parentNameInputs", predicate: ["parentNameInput"], descendants: true }], ngImport: i0, template: "@if (loading) {\r\n <div class=\"tree-skeleton\">\r\n <ui-skeleton-loader [inputs]=\"4\" [cols]=\"1\"></ui-skeleton-loader>\r\n </div>\r\n} @else {\r\n @if (searchEnabled) {\r\n <div class=\"filter-bar\">\r\n {{'tree.search_label' | uicTranslate}}\r\n <ui-input>\r\n <input #inp [placeholder]=\"'tree.search_placeholder' | uicTranslate\" [value]=\"filterTerm\" (input)=\"updateFilter($event)\">\r\n </ui-input>\r\n <ui-button\r\n [iconOnly]=\"true\"\r\n icon=\"ri-eraser-line\"\r\n type=\"bordered\"\r\n color=\"black\"\r\n [disabled]=\"!filterTerm\"\r\n (click)=\"clearFilter(); inp.focus()\"\r\n ></ui-button>\r\n </div>\r\n }\r\n @for (item of getVisibleTree(); track item.id) {\r\n <div class=\"tree-item\" [class.is-collapsed]=\"!isExpanded(item)\">\r\n <div class=\"tree-header\" (click)=\"toggleItem(item)\">\r\n <i class=\"ri-arrow-down-s-line tree-arrow\" [class.is-collapsed]=\"!isExpanded(item)\"></i>\r\n <div class=\"tree-header-name\">\r\n @if (isEditingParent(item)) {\r\n <input\r\n #parentNameInput\r\n class=\"tree-name-input\"\r\n [attr.data-id]=\"item.id\"\r\n [value]=\"item.name\"\r\n (input)=\"updateParentName(item, $event)\"\r\n (blur)=\"finalizeParentEdit(item)\"\r\n (keydown.enter)=\"finalizeParentEdit(item)\"\r\n (keydown.escape)=\"cancelParentEdit(item)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n } @else {\r\n <div class=\"tree-name-text\" (click)=\"startEditParent(item, $event)\">\r\n {{item.name}}\r\n </div>\r\n }\r\n <span>{{item.children?.length || 0}}</span>\r\n </div>\r\n <div>\r\n <ui-switch\r\n [checked]=\"item.enabled\"\r\n (click)=\"$event.stopPropagation()\"\r\n (checkedChange)=\"emitDeactivateParent(item, $event)\"\r\n ></ui-switch>\r\n </div>\r\n <ui-button (click)=\"addSubItem(item, $event)\" icon=\"ri-add-line\" type=\"ghost\" [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n <ui-button (click)=\"emitEditParent(item, $event)\" icon=\"ri-edit-line\" type=\"ghost\" [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n @if (!item.children?.length) {\r\n <ui-button (click)=\"emitDeleteParent(item, $event)\" icon=\"ri-delete-bin-line\" type=\"ghost\" [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n }\r\n </div>\r\n <div class=\"tree-body\">\r\n @if (getFilteredChildren(item).length) {\r\n @for (subitem of getFilteredChildren(item); track subitem.id) {\r\n <div\r\n class=\"tree-subitem\"\r\n [class.is-disabled]=\"!subitem.enabled\"\r\n [class.is-pending]=\"isPendingCreate(subitem)\"\r\n [class.is-parent-disabled]=\"!item.enabled\"\r\n >\r\n <div class=\"tree-subitem-name\">\r\n <i\r\n class=\"ri-circle-fill tree-subitem-status\"\r\n [class.is-enabled]=\"subitem.enabled\"\r\n [class.is-disabled]=\"!subitem.enabled\"\r\n ></i>\r\n @if (isEditingChild(subitem)) {\r\n <input\r\n #childNameInput\r\n class=\"tree-name-input tree-name-input--sub\"\r\n [attr.data-id]=\"subitem.id\"\r\n [value]=\"subitem.name\"\r\n (input)=\"updateChildName(item, subitem, $event)\"\r\n (blur)=\"finalizeChildEdit(item, subitem)\"\r\n (keydown.enter)=\"finalizeChildEdit(item, subitem)\"\r\n (keydown.escape)=\"cancelChildEdit(item, subitem)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n } @else {\r\n <span\r\n class=\"tree-name-text\"\r\n (click)=\"!isPendingCreate(subitem) && startEditChild(subitem, $event)\"\r\n >{{subitem.name}}</span> \r\n @if (subitem.tag) {\r\n <span class=\"tree-tag tag-{{subitem.tagColor}}\" >{{subitem.tag}}</span>\r\n }\r\n }\r\n </div>\r\n <div class=\"tree-subitem-actions\">\r\n <ui-switch\r\n [checked]=\"subitem.enabled\"\r\n [disabled]=\"isPendingCreate(subitem)\"\r\n (checkedChange)=\"emitDeactivateChild(item, subitem, $event)\"\r\n ></ui-switch>\r\n <ui-button\r\n (click)=\"emitEditChild(item, subitem, $event)\"\r\n [disabled]=\"isPendingCreate(subitem)\"\r\n icon=\"ri-edit-line\"\r\n type=\"ghost\"\r\n [iconOnly]=\"true\"\r\n size=\"s\"\r\n ></ui-button>\r\n <ui-button \r\n (click)=\"emitDeleteChild(item, subitem, $event)\" \r\n icon=\"ri-delete-bin-line\" \r\n [disabled]=\"isPendingCreate(subitem)\"\r\n type=\"ghost\" \r\n [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n </div>\r\n </div>\r\n }\r\n } @else {\r\n <div class=\"tree-empty\">\r\n {{emptyMessage | uicTranslate}}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n}\r\n\r\n", styles: [":host{width:100%}.tree-item{border:solid 1px var(--grey-400);border-radius:10px;overflow:hidden;margin-bottom:4px;background:linear-gradient(180deg,var(--grey-100) 0%,var(--grey-50) 100%);transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.tree-header{width:100%;display:flex;align-items:center;gap:5px;padding:4px 10px;border-bottom:solid 1px var(--grey-400);background-color:var(--grey-100);cursor:pointer;transition:background-color .16s ease}.tree-header:hover{background-color:var(--grey-200)}.tree-header-name{flex:1 1;display:flex;align-items:center;gap:10px}.tree-header-name span{border-radius:10px;padding:2px 10px;font-size:10px;color:var(--blue-800);background-color:var(--blue-100)}.tree-arrow{transition:transform .18s ease}.tree-arrow.is-collapsed{transform:rotate(-90deg)}.tree-body{background-color:var(--white);padding:2px 16px;display:flex;flex-direction:column;gap:1px;max-height:600px;opacity:1;transition:max-height .2s ease,opacity .2s ease,padding .2s ease}.tree-empty{padding:8px 10px;font-size:12px;color:var(--grey-500);background-color:var(--grey-50);border-radius:8px}.tree-subitem{color:var(--grey-700);border-radius:5px;padding:3px 15px;gap:5px;font-size:13px;display:flex;align-items:center}.tree-subitem-name{flex:1 1;display:inline-flex;align-items:center;gap:6px}.tree-subitem-status{font-size:10px;color:var(--grey-400)}.tree-subitem-status.is-enabled{color:var(--blue-500)}.tree-subitem-status.is-disabled{color:var(--grey-400)}.tree-subitem-actions{display:inline-flex;align-items:center;gap:4px;opacity:0;pointer-events:none;transform:translateY(-2px);transition:opacity .16s ease,transform .16s ease}.tree-subitem:hover{background-color:var(--blue-100)}.tree-subitem:hover .tree-subitem-actions{opacity:1;pointer-events:auto;transform:translateY(0)}.tree-subitem.is-disabled .tree-name-text,.tree-subitem.is-disabled .tree-name-input,.tree-subitem.is-parent-disabled .tree-name-text,.tree-subitem.is-parent-disabled .tree-name-input{color:var(--grey-500)}.tree-subitem.is-parent-disabled .tree-subitem-status{color:var(--grey-400)}.tree-subitem.is-pending .tree-name-text{cursor:default;color:var(--grey-500)}.tree-name-text{color:var(--grey-900);padding:0 20px;cursor:text}.filter-bar{display:flex;gap:10px;align-items:center;margin-bottom:10px;font-size:14px}.filter-bar input{flex:1 1}.tree-name-input{flex:1 1;min-width:0;border:solid 1px var(--grey-300);border-radius:6px;padding:7px;font-size:13px;color:var(--grey-900);background-color:var(--white);outline:none;transition:border-color .16s ease,box-shadow .16s ease;width:300px}.tree-name-input:focus{border-color:var(--blue-500);box-shadow:0 0 0 2px #3b82f626}.tree-name-input--sub{font-size:12px;padding:5px}.tree-item.is-collapsed .tree-body{max-height:0;opacity:0;padding-top:0;padding-bottom:0;overflow:hidden}.tree-skeleton{padding:8px;border:solid 1px var(--grey-400);border-radius:10px;background-color:var(--grey-50)}.tree-tag{font-size:11px;padding:2px 10px;font-weight:300;border-radius:10px}.tag-yellow{background-color:var(--yellow-100)}.tag-red{background-color:var(--red-100)}.tag-green{background-color:var(--green-100)}.tag-blue{background-color:var(--blue-100)}\n"], dependencies: [{ kind: "component", type: UicInputComponent, selector: "ui-input", inputs: ["icon", "iconColor", "internalIcon", "internalIconColor", "size", "label", "error", "tip", "disabled", "loading"], outputs: ["clickButton"] }, { kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "component", type: UicSkeletonLoaderComponent, selector: "ui-skeleton-loader", inputs: ["inputs", "cols"] }, { kind: "component", type: UicSwichComponent, selector: "ui-switch", inputs: ["checked", "disabled", "placeholder", "label"], outputs: ["checkedChange"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }] });
|
|
7268
7554
|
}
|
|
7269
7555
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicTreeAdminComponent, decorators: [{
|
|
7270
7556
|
type: Component,
|
|
@@ -7274,7 +7560,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
7274
7560
|
UicSkeletonLoaderComponent,
|
|
7275
7561
|
UicSwichComponent,
|
|
7276
7562
|
UicTranslatePipe
|
|
7277
|
-
], template: "@if (loading) {\r\n <div class=\"tree-skeleton\">\r\n <ui-skeleton-loader [inputs]=\"4\" [cols]=\"1\"></ui-skeleton-loader>\r\n </div>\r\n} @else {\r\n @if (searchEnabled) {\r\n <div class=\"filter-bar\">\r\n {{'tree.search_label' | uicTranslate}}\r\n <ui-input>\r\n <input #inp [placeholder]=\"'tree.search_placeholder' | uicTranslate\" [value]=\"filterTerm\" (input)=\"updateFilter($event)\">\r\n </ui-input>\r\n <ui-button\r\n [iconOnly]=\"true\"\r\n icon=\"ri-eraser-line\"\r\n type=\"bordered\"\r\n color=\"black\"\r\n [disabled]=\"!filterTerm\"\r\n (click)=\"clearFilter(); inp.focus()\"\r\n ></ui-button>\r\n </div>\r\n }\r\n @for (item of tree; track item.id) {\r\n <div class=\"tree-item\" [class.is-collapsed]=\"!isExpanded(item)\">\r\n <div class=\"tree-header\" (click)=\"toggleItem(item)\">\r\n <i class=\"ri-arrow-down-s-line tree-arrow\" [class.is-collapsed]=\"!isExpanded(item)\"></i>\r\n <div class=\"tree-header-name\">\r\n @if (isEditingParent(item)) {\r\n <input\r\n #parentNameInput\r\n class=\"tree-name-input\"\r\n [attr.data-id]=\"item.id\"\r\n [value]=\"item.name\"\r\n (input)=\"updateParentName(item, $event)\"\r\n (blur)=\"finalizeParentEdit(item)\"\r\n (keydown.enter)=\"finalizeParentEdit(item)\"\r\n (keydown.escape)=\"cancelParentEdit(item)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n } @else {\r\n <div class=\"tree-name-text\" (click)=\"startEditParent(item, $event)\">\r\n {{item.name}}\r\n </div>\r\n }\r\n <span>{{item.children?.length || 0}}</span>\r\n </div>\r\n <div>\r\n <ui-switch\r\n [checked]=\"item.enabled\"\r\n (click)=\"$event.stopPropagation()\"\r\n (checkedChange)=\"emitDeactivateParent(item, $event)\"\r\n ></ui-switch>\r\n </div>\r\n <ui-button (click)=\"addSubItem(item, $event)\" icon=\"ri-add-line\" type=\"ghost\" [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n <ui-button (click)=\"emitEditParent(item, $event)\" icon=\"ri-edit-line\" type=\"ghost\" [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n @if (!item.children?.length) {\r\n <ui-button (click)=\"emitDeleteParent(item, $event)\" icon=\"ri-delete-bin-line\" type=\"ghost\" [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n }\r\n </div>\r\n <div class=\"tree-body\">\r\n @if (getFilteredChildren(item).length) {\r\n @for (subitem of getFilteredChildren(item); track subitem.id) {\r\n <div\r\n class=\"tree-subitem\"\r\n [class.is-disabled]=\"!subitem.enabled\"\r\n [class.is-pending]=\"isPendingCreate(subitem)\"\r\n [class.is-parent-disabled]=\"!item.enabled\"\r\n >\r\n <div class=\"tree-subitem-name\">\r\n <i\r\n class=\"ri-circle-fill tree-subitem-status\"\r\n [class.is-enabled]=\"subitem.enabled\"\r\n [class.is-disabled]=\"!subitem.enabled\"\r\n ></i>\r\n @if (isEditingChild(subitem)) {\r\n <input\r\n #childNameInput\r\n class=\"tree-name-input tree-name-input--sub\"\r\n [attr.data-id]=\"subitem.id\"\r\n [value]=\"subitem.name\"\r\n (input)=\"updateChildName(item, subitem, $event)\"\r\n (blur)=\"finalizeChildEdit(item, subitem)\"\r\n (keydown.enter)=\"finalizeChildEdit(item, subitem)\"\r\n (keydown.escape)=\"cancelChildEdit(item, subitem)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n } @else {\r\n <span\r\n class=\"tree-name-text\"\r\n (click)=\"!isPendingCreate(subitem) && startEditChild(subitem, $event)\"\r\n >{{subitem.name}}</span>\r\n }\r\n </div>\r\n <div class=\"tree-subitem-actions\">\r\n <ui-switch\r\n [checked]=\"subitem.enabled\"\r\n [disabled]=\"isPendingCreate(subitem)\"\r\n (checkedChange)=\"emitDeactivateChild(item, subitem, $event)\"\r\n ></ui-switch>\r\n <ui-button\r\n (click)=\"emitEditChild(item, subitem, $event)\"\r\n [disabled]=\"isPendingCreate(subitem)\"\r\n icon=\"ri-edit-line\"\r\n type=\"ghost\"\r\n [iconOnly]=\"true\"\r\n size=\"s\"\r\n ></ui-button>\r\n <ui-button \r\n (click)=\"emitDeleteChild(item, subitem, $event)\" \r\n icon=\"ri-delete-bin-line\" \r\n [disabled]=\"isPendingCreate(subitem)\"\r\n type=\"ghost\" \r\n [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n </div>\r\n </div>\r\n }\r\n } @else {\r\n <div class=\"tree-empty\">\r\n {{emptyMessage | uicTranslate}}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n}\r\n\r\n", styles: [":host{width:100%}.tree-item{border:solid 1px var(--grey-400);border-radius:10px;overflow:hidden;margin-bottom:4px;background:linear-gradient(180deg,var(--grey-100) 0%,var(--grey-50) 100%);transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.tree-header{width:100%;display:flex;align-items:center;gap:5px;padding:4px 10px;border-bottom:solid 1px var(--grey-400);background-color:var(--grey-100);cursor:pointer;transition:background-color .16s ease}.tree-header:hover{background-color:var(--grey-200)}.tree-header-name{flex:1 1;display:flex;align-items:center;gap:10px}.tree-header-name span{border-radius:10px;padding:2px 10px;font-size:10px;color:var(--blue-800);background-color:var(--blue-100)}.tree-arrow{transition:transform .18s ease}.tree-arrow.is-collapsed{transform:rotate(-90deg)}.tree-body{background-color:var(--white);padding:2px 16px;display:flex;flex-direction:column;gap:1px;max-height:600px;opacity:1;transition:max-height .2s ease,opacity .2s ease,padding .2s ease}.tree-empty{padding:8px 10px;font-size:12px;color:var(--grey-500);background-color:var(--grey-50);border-radius:8px}.tree-subitem{color:var(--grey-700);border-radius:5px;padding:3px 15px;gap:5px;font-size:13px;display:flex;align-items:center;justify-content:space-between}.tree-subitem-name{flex:1 1;display:inline-flex;align-items:center;gap:6px}.tree-subitem-status{font-size:10px;color:var(--grey-400)}.tree-subitem-status.is-enabled{color:var(--blue-500)}.tree-subitem-status.is-disabled{color:var(--grey-400)}.tree-subitem-actions{display:inline-flex;align-items:center;gap:4px;opacity:0;pointer-events:none;transform:translateY(-2px);transition:opacity .16s ease,transform .16s ease}.tree-subitem:hover{background-color:var(--blue-100)}.tree-subitem:hover .tree-subitem-actions{opacity:1;pointer-events:auto;transform:translateY(0)}.tree-subitem.is-disabled .tree-name-text,.tree-subitem.is-disabled .tree-name-input,.tree-subitem.is-parent-disabled .tree-name-text,.tree-subitem.is-parent-disabled .tree-name-input{color:var(--grey-500)}.tree-subitem.is-parent-disabled .tree-subitem-status{color:var(--grey-400)}.tree-subitem.is-pending .tree-name-text{cursor:default;color:var(--grey-500)}.tree-name-text{width:50%;color:var(--grey-900);cursor:text}.filter-bar{display:flex;gap:10px;align-items:center;margin-bottom:10px;font-size:14px}.filter-bar input{flex:1 1}.tree-name-input{flex:1 1;min-width:0;border:solid 1px var(--grey-300);border-radius:6px;padding:7px;font-size:13px;color:var(--grey-900);background-color:var(--white);outline:none;transition:border-color .16s ease,box-shadow .16s ease;width:300px}.tree-name-input:focus{border-color:var(--blue-500);box-shadow:0 0 0 2px #3b82f626}.tree-name-input--sub{font-size:12px;padding:5px}.tree-item.is-collapsed .tree-body{max-height:0;opacity:0;padding-top:0;padding-bottom:0;overflow:hidden}.tree-skeleton{padding:8px;border:solid 1px var(--grey-400);border-radius:10px;background-color:var(--grey-50)}\n"] }]
|
|
7563
|
+
], template: "@if (loading) {\r\n <div class=\"tree-skeleton\">\r\n <ui-skeleton-loader [inputs]=\"4\" [cols]=\"1\"></ui-skeleton-loader>\r\n </div>\r\n} @else {\r\n @if (searchEnabled) {\r\n <div class=\"filter-bar\">\r\n {{'tree.search_label' | uicTranslate}}\r\n <ui-input>\r\n <input #inp [placeholder]=\"'tree.search_placeholder' | uicTranslate\" [value]=\"filterTerm\" (input)=\"updateFilter($event)\">\r\n </ui-input>\r\n <ui-button\r\n [iconOnly]=\"true\"\r\n icon=\"ri-eraser-line\"\r\n type=\"bordered\"\r\n color=\"black\"\r\n [disabled]=\"!filterTerm\"\r\n (click)=\"clearFilter(); inp.focus()\"\r\n ></ui-button>\r\n </div>\r\n }\r\n @for (item of getVisibleTree(); track item.id) {\r\n <div class=\"tree-item\" [class.is-collapsed]=\"!isExpanded(item)\">\r\n <div class=\"tree-header\" (click)=\"toggleItem(item)\">\r\n <i class=\"ri-arrow-down-s-line tree-arrow\" [class.is-collapsed]=\"!isExpanded(item)\"></i>\r\n <div class=\"tree-header-name\">\r\n @if (isEditingParent(item)) {\r\n <input\r\n #parentNameInput\r\n class=\"tree-name-input\"\r\n [attr.data-id]=\"item.id\"\r\n [value]=\"item.name\"\r\n (input)=\"updateParentName(item, $event)\"\r\n (blur)=\"finalizeParentEdit(item)\"\r\n (keydown.enter)=\"finalizeParentEdit(item)\"\r\n (keydown.escape)=\"cancelParentEdit(item)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n } @else {\r\n <div class=\"tree-name-text\" (click)=\"startEditParent(item, $event)\">\r\n {{item.name}}\r\n </div>\r\n }\r\n <span>{{item.children?.length || 0}}</span>\r\n </div>\r\n <div>\r\n <ui-switch\r\n [checked]=\"item.enabled\"\r\n (click)=\"$event.stopPropagation()\"\r\n (checkedChange)=\"emitDeactivateParent(item, $event)\"\r\n ></ui-switch>\r\n </div>\r\n <ui-button (click)=\"addSubItem(item, $event)\" icon=\"ri-add-line\" type=\"ghost\" [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n <ui-button (click)=\"emitEditParent(item, $event)\" icon=\"ri-edit-line\" type=\"ghost\" [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n @if (!item.children?.length) {\r\n <ui-button (click)=\"emitDeleteParent(item, $event)\" icon=\"ri-delete-bin-line\" type=\"ghost\" [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n }\r\n </div>\r\n <div class=\"tree-body\">\r\n @if (getFilteredChildren(item).length) {\r\n @for (subitem of getFilteredChildren(item); track subitem.id) {\r\n <div\r\n class=\"tree-subitem\"\r\n [class.is-disabled]=\"!subitem.enabled\"\r\n [class.is-pending]=\"isPendingCreate(subitem)\"\r\n [class.is-parent-disabled]=\"!item.enabled\"\r\n >\r\n <div class=\"tree-subitem-name\">\r\n <i\r\n class=\"ri-circle-fill tree-subitem-status\"\r\n [class.is-enabled]=\"subitem.enabled\"\r\n [class.is-disabled]=\"!subitem.enabled\"\r\n ></i>\r\n @if (isEditingChild(subitem)) {\r\n <input\r\n #childNameInput\r\n class=\"tree-name-input tree-name-input--sub\"\r\n [attr.data-id]=\"subitem.id\"\r\n [value]=\"subitem.name\"\r\n (input)=\"updateChildName(item, subitem, $event)\"\r\n (blur)=\"finalizeChildEdit(item, subitem)\"\r\n (keydown.enter)=\"finalizeChildEdit(item, subitem)\"\r\n (keydown.escape)=\"cancelChildEdit(item, subitem)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n } @else {\r\n <span\r\n class=\"tree-name-text\"\r\n (click)=\"!isPendingCreate(subitem) && startEditChild(subitem, $event)\"\r\n >{{subitem.name}}</span> \r\n @if (subitem.tag) {\r\n <span class=\"tree-tag tag-{{subitem.tagColor}}\" >{{subitem.tag}}</span>\r\n }\r\n }\r\n </div>\r\n <div class=\"tree-subitem-actions\">\r\n <ui-switch\r\n [checked]=\"subitem.enabled\"\r\n [disabled]=\"isPendingCreate(subitem)\"\r\n (checkedChange)=\"emitDeactivateChild(item, subitem, $event)\"\r\n ></ui-switch>\r\n <ui-button\r\n (click)=\"emitEditChild(item, subitem, $event)\"\r\n [disabled]=\"isPendingCreate(subitem)\"\r\n icon=\"ri-edit-line\"\r\n type=\"ghost\"\r\n [iconOnly]=\"true\"\r\n size=\"s\"\r\n ></ui-button>\r\n <ui-button \r\n (click)=\"emitDeleteChild(item, subitem, $event)\" \r\n icon=\"ri-delete-bin-line\" \r\n [disabled]=\"isPendingCreate(subitem)\"\r\n type=\"ghost\" \r\n [iconOnly]=\"true\" size=\"s\"></ui-button>\r\n </div>\r\n </div>\r\n }\r\n } @else {\r\n <div class=\"tree-empty\">\r\n {{emptyMessage | uicTranslate}}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n}\r\n\r\n", styles: [":host{width:100%}.tree-item{border:solid 1px var(--grey-400);border-radius:10px;overflow:hidden;margin-bottom:4px;background:linear-gradient(180deg,var(--grey-100) 0%,var(--grey-50) 100%);transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.tree-header{width:100%;display:flex;align-items:center;gap:5px;padding:4px 10px;border-bottom:solid 1px var(--grey-400);background-color:var(--grey-100);cursor:pointer;transition:background-color .16s ease}.tree-header:hover{background-color:var(--grey-200)}.tree-header-name{flex:1 1;display:flex;align-items:center;gap:10px}.tree-header-name span{border-radius:10px;padding:2px 10px;font-size:10px;color:var(--blue-800);background-color:var(--blue-100)}.tree-arrow{transition:transform .18s ease}.tree-arrow.is-collapsed{transform:rotate(-90deg)}.tree-body{background-color:var(--white);padding:2px 16px;display:flex;flex-direction:column;gap:1px;max-height:600px;opacity:1;transition:max-height .2s ease,opacity .2s ease,padding .2s ease}.tree-empty{padding:8px 10px;font-size:12px;color:var(--grey-500);background-color:var(--grey-50);border-radius:8px}.tree-subitem{color:var(--grey-700);border-radius:5px;padding:3px 15px;gap:5px;font-size:13px;display:flex;align-items:center}.tree-subitem-name{flex:1 1;display:inline-flex;align-items:center;gap:6px}.tree-subitem-status{font-size:10px;color:var(--grey-400)}.tree-subitem-status.is-enabled{color:var(--blue-500)}.tree-subitem-status.is-disabled{color:var(--grey-400)}.tree-subitem-actions{display:inline-flex;align-items:center;gap:4px;opacity:0;pointer-events:none;transform:translateY(-2px);transition:opacity .16s ease,transform .16s ease}.tree-subitem:hover{background-color:var(--blue-100)}.tree-subitem:hover .tree-subitem-actions{opacity:1;pointer-events:auto;transform:translateY(0)}.tree-subitem.is-disabled .tree-name-text,.tree-subitem.is-disabled .tree-name-input,.tree-subitem.is-parent-disabled .tree-name-text,.tree-subitem.is-parent-disabled .tree-name-input{color:var(--grey-500)}.tree-subitem.is-parent-disabled .tree-subitem-status{color:var(--grey-400)}.tree-subitem.is-pending .tree-name-text{cursor:default;color:var(--grey-500)}.tree-name-text{color:var(--grey-900);padding:0 20px;cursor:text}.filter-bar{display:flex;gap:10px;align-items:center;margin-bottom:10px;font-size:14px}.filter-bar input{flex:1 1}.tree-name-input{flex:1 1;min-width:0;border:solid 1px var(--grey-300);border-radius:6px;padding:7px;font-size:13px;color:var(--grey-900);background-color:var(--white);outline:none;transition:border-color .16s ease,box-shadow .16s ease;width:300px}.tree-name-input:focus{border-color:var(--blue-500);box-shadow:0 0 0 2px #3b82f626}.tree-name-input--sub{font-size:12px;padding:5px}.tree-item.is-collapsed .tree-body{max-height:0;opacity:0;padding-top:0;padding-bottom:0;overflow:hidden}.tree-skeleton{padding:8px;border:solid 1px var(--grey-400);border-radius:10px;background-color:var(--grey-50)}.tree-tag{font-size:11px;padding:2px 10px;font-weight:300;border-radius:10px}.tag-yellow{background-color:var(--yellow-100)}.tag-red{background-color:var(--red-100)}.tag-green{background-color:var(--green-100)}.tag-blue{background-color:var(--blue-100)}\n"] }]
|
|
7278
7564
|
}], propDecorators: { searchEnabled: [{
|
|
7279
7565
|
type: Input
|
|
7280
7566
|
}], loading: [{
|
|
@@ -8094,14 +8380,14 @@ const FIELDS_CONFIG = [
|
|
|
8094
8380
|
{ value: 'textarea', icon: 'ri-file-text-line', detail: 'Texto multilinea con ajuste de altura', label: 'Area de texto', properties: ['placeholder', 'minLength', 'maxLength', 'showCounter', 'voiceToTextEnabled', 'textareaResize', 'resizeMinRows', 'resizeMaxRows'] },
|
|
8095
8381
|
{ value: 'number', icon: 'ri-hashtag', detail: 'Campo numerico con control de paso', label: 'Numero', properties: ['placeholder', 'step', 'min', 'max'] },
|
|
8096
8382
|
{ value: 'phone', icon: 'ri-phone-line', detail: 'Telefono con pais y codigo', label: 'Telefono', properties: ['placeholder'] },
|
|
8097
|
-
{ value: 'select', icon: 'ri-list-unordered', detail: 'Seleccion simple desde opciones', label: 'Selector', properties: ['options', 'selectSearchEnabled', 'selectNullable'] },
|
|
8098
|
-
{ value: 'multyselect', icon: 'ri-list-check-2', detail: 'Seleccion multiple desde opciones', label: 'Selector multiple', properties: ['options'] },
|
|
8383
|
+
{ value: 'select', icon: 'ri-list-unordered', detail: 'Seleccion simple desde opciones', label: 'Selector', properties: ['options', 'optionsSource.key', 'optionsSource.idField', 'optionsSource.textField', 'optionsSource.textTemplate', 'optionsSource.dependsOn', 'optionsSource.paramName', 'selectSearchEnabled', 'selectNullable'] },
|
|
8384
|
+
{ value: 'multyselect', icon: 'ri-list-check-2', detail: 'Seleccion multiple desde opciones', label: 'Selector multiple', properties: ['options', 'optionsSource.key', 'optionsSource.idField', 'optionsSource.textField', 'optionsSource.textTemplate', 'optionsSource.dependsOn', 'optionsSource.paramName'] },
|
|
8099
8385
|
{ value: 'date', icon: 'ri-calendar-2-line', detail: 'Selector de fecha o mes', label: 'Fecha', properties: ['monthMode', 'monthDay', 'minDate', 'maxDate'] },
|
|
8100
8386
|
{ value: 'time', icon: 'ri-timer-2-line', detail: 'Selector de hora', label: 'Hora', properties: ['timeInterval'] },
|
|
8101
|
-
{ value: 'radio', icon: 'ri-radio-button-line', detail: 'Seleccion unica entre opciones', label: 'Radio', properties: ['options'] },
|
|
8387
|
+
{ value: 'radio', icon: 'ri-radio-button-line', detail: 'Seleccion unica entre opciones', label: 'Radio', properties: ['options', 'optionsSource.key', 'optionsSource.idField', 'optionsSource.textField', 'optionsSource.textTemplate', 'optionsSource.dependsOn', 'optionsSource.paramName'] },
|
|
8102
8388
|
{ value: 'checkbox', icon: 'ri-checkbox-line', detail: 'Campo booleano tipo check', label: 'Checkbox', properties: ['placeholder'] },
|
|
8103
8389
|
{ value: 'switch', icon: 'ri-toggle-line', detail: 'Campo booleano tipo switch', label: 'Switch', properties: ['placeholder'] },
|
|
8104
|
-
{ value: 'pool', icon: 'ri-list-indefinite', detail: 'Seleccion con lista y detalle por item', label: 'Multiopciones', properties: ['options', 'multyEnabled', 'poolEnabledListView', 'poolTitle'] },
|
|
8390
|
+
{ value: 'pool', icon: 'ri-list-indefinite', detail: 'Seleccion con lista y detalle por item', label: 'Multiopciones', properties: ['options', 'optionsSource.key', 'optionsSource.idField', 'optionsSource.textField', 'optionsSource.textTemplate', 'optionsSource.dependsOn', 'optionsSource.paramName', 'multyEnabled', 'poolEnabledListView', 'poolTitle'] },
|
|
8105
8391
|
{ value: 'file', icon: 'ri-attachment-line', detail: 'Carga de archivos', label: 'Archivo', properties: ['multyEnabled', 'fileTypes', 'iaValidation', 'iaValidationPrompt'] },
|
|
8106
8392
|
{ value: 'searcher', icon: 'ri-seo-line', detail: 'Buscador con fuente de datos externa', label: 'Buscador', properties: ['placeholder', 'searchApi'] },
|
|
8107
8393
|
{ value: 'slider', icon: 'ri-equalizer-2-line', detail: 'Control deslizante continuo', label: 'Deslizador', properties: ['min', 'max', 'sliderInterval', 'sliderMarks'] }
|
|
@@ -8216,6 +8502,83 @@ const EXTRA_FORM_FIELDS = [
|
|
|
8216
8502
|
tip: 'form_builder.extra.searchApi_tip',
|
|
8217
8503
|
type: 'text'
|
|
8218
8504
|
},
|
|
8505
|
+
{
|
|
8506
|
+
name: 'optionsSource.key',
|
|
8507
|
+
label: 'form_builder.extra.optionsSourceKey',
|
|
8508
|
+
internalIcon: 'ri-database-2-line',
|
|
8509
|
+
tip: 'form_builder.extra.optionsSourceKey_tip',
|
|
8510
|
+
type: 'text'
|
|
8511
|
+
},
|
|
8512
|
+
{
|
|
8513
|
+
name: 'optionsSource.idField',
|
|
8514
|
+
label: 'form_builder.extra.optionsSourceIdField',
|
|
8515
|
+
internalIcon: 'ri-key-line',
|
|
8516
|
+
tip: 'form_builder.extra.optionsSourceIdField_tip',
|
|
8517
|
+
type: 'text',
|
|
8518
|
+
visibilityRules: [
|
|
8519
|
+
{
|
|
8520
|
+
fieldName: 'optionsSource.key',
|
|
8521
|
+
operator: 'notEquals',
|
|
8522
|
+
value: ''
|
|
8523
|
+
}
|
|
8524
|
+
]
|
|
8525
|
+
},
|
|
8526
|
+
{
|
|
8527
|
+
name: 'optionsSource.textField',
|
|
8528
|
+
label: 'form_builder.extra.optionsSourceTextField',
|
|
8529
|
+
internalIcon: 'ri-text',
|
|
8530
|
+
tip: 'form_builder.extra.optionsSourceTextField_tip',
|
|
8531
|
+
type: 'text',
|
|
8532
|
+
visibilityRules: [
|
|
8533
|
+
{
|
|
8534
|
+
fieldName: 'optionsSource.key',
|
|
8535
|
+
operator: 'notEquals',
|
|
8536
|
+
value: ''
|
|
8537
|
+
}
|
|
8538
|
+
]
|
|
8539
|
+
},
|
|
8540
|
+
{
|
|
8541
|
+
name: 'optionsSource.textTemplate',
|
|
8542
|
+
label: 'form_builder.extra.optionsSourceTextTemplate',
|
|
8543
|
+
internalIcon: 'ri-braces-line',
|
|
8544
|
+
tip: 'form_builder.extra.optionsSourceTextTemplate_tip',
|
|
8545
|
+
type: 'text',
|
|
8546
|
+
visibilityRules: [
|
|
8547
|
+
{
|
|
8548
|
+
fieldName: 'optionsSource.key',
|
|
8549
|
+
operator: 'notEquals',
|
|
8550
|
+
value: ''
|
|
8551
|
+
}
|
|
8552
|
+
]
|
|
8553
|
+
},
|
|
8554
|
+
{
|
|
8555
|
+
name: 'optionsSource.dependsOn',
|
|
8556
|
+
label: 'form_builder.extra.optionsSourceDependsOn',
|
|
8557
|
+
internalIcon: 'ri-git-branch-line',
|
|
8558
|
+
tip: 'form_builder.extra.optionsSourceDependsOn_tip',
|
|
8559
|
+
type: 'text',
|
|
8560
|
+
visibilityRules: [
|
|
8561
|
+
{
|
|
8562
|
+
fieldName: 'optionsSource.key',
|
|
8563
|
+
operator: 'notEquals',
|
|
8564
|
+
value: ''
|
|
8565
|
+
}
|
|
8566
|
+
]
|
|
8567
|
+
},
|
|
8568
|
+
{
|
|
8569
|
+
name: 'optionsSource.paramName',
|
|
8570
|
+
label: 'form_builder.extra.optionsSourceParamName',
|
|
8571
|
+
internalIcon: 'ri-code-line',
|
|
8572
|
+
tip: 'form_builder.extra.optionsSourceParamName_tip',
|
|
8573
|
+
type: 'text',
|
|
8574
|
+
visibilityRules: [
|
|
8575
|
+
{
|
|
8576
|
+
fieldName: 'optionsSource.key',
|
|
8577
|
+
operator: 'notEquals',
|
|
8578
|
+
value: ''
|
|
8579
|
+
}
|
|
8580
|
+
]
|
|
8581
|
+
},
|
|
8219
8582
|
{
|
|
8220
8583
|
name: 'iaValidation',
|
|
8221
8584
|
label: 'form_builder.extra.iaValidation',
|
|
@@ -8481,7 +8844,7 @@ class FormPreviewComponent {
|
|
|
8481
8844
|
console.log(fr.form);
|
|
8482
8845
|
}
|
|
8483
8846
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FormPreviewComponent, deps: [{ token: MODAL_DATA }], target: i0.ɵɵFactoryTarget.Component });
|
|
8484
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FormPreviewComponent, isStandalone: true, selector: "lib-form-preview", ngImport: i0, template: "<ui-form-wrapper \r\n [schema]=\"schema\" \r\n [showButtons]=\"true\"\r\n (formSubmit)=\"save($event)\">\r\n</ui-form-wrapper>\r\n", styles: [""], dependencies: [{ kind: "component", type: UicFormWrapperComponent, selector: "ui-form-wrapper", inputs: ["schema", "fields", "cols", "externalData", "loading", "disabled", "showButtons", "fillSelects", "initialValues", "fileUidResolverFn"], outputs: ["formSubmit", "formChange"] }] });
|
|
8847
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FormPreviewComponent, isStandalone: true, selector: "lib-form-preview", ngImport: i0, template: "<ui-form-wrapper \r\n [schema]=\"schema\" \r\n [showButtons]=\"true\"\r\n (formSubmit)=\"save($event)\">\r\n</ui-form-wrapper>\r\n", styles: [""], dependencies: [{ kind: "component", type: UicFormWrapperComponent, selector: "ui-form-wrapper", inputs: ["schema", "fields", "cols", "externalData", "selectOptionsResolver", "loading", "disabled", "showButtons", "fillSelects", "initialValues", "focusFieldName", "focusFieldTrigger", "fileUidResolverFn"], outputs: ["formSubmit", "formChange", "optionsSourceError"] }] });
|
|
8485
8848
|
}
|
|
8486
8849
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FormPreviewComponent, decorators: [{
|
|
8487
8850
|
type: Component,
|
|
@@ -8529,11 +8892,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
8529
8892
|
|
|
8530
8893
|
class FieldEditorComponent {
|
|
8531
8894
|
translateService = inject(UicTranslateService);
|
|
8895
|
+
elementRef = inject(ElementRef);
|
|
8896
|
+
currentFieldCode = null;
|
|
8532
8897
|
hasOptions = computed(() => {
|
|
8533
8898
|
const fieldType = this.fieldType();
|
|
8534
8899
|
return !!fieldType?.properties.includes('options');
|
|
8535
8900
|
});
|
|
8536
8901
|
config = input.required();
|
|
8902
|
+
focusRequiredField = input(false);
|
|
8537
8903
|
options = input({});
|
|
8538
8904
|
hiddenSections = signal([]);
|
|
8539
8905
|
fieldChange = output();
|
|
@@ -8568,8 +8934,19 @@ class FieldEditorComponent {
|
|
|
8568
8934
|
fieldType = computed(() => FIELDS_CONFIG.find(f => f.value === this.config().fieldData?.type));
|
|
8569
8935
|
constructor() {
|
|
8570
8936
|
effect(() => {
|
|
8571
|
-
const
|
|
8937
|
+
const config = this.config();
|
|
8938
|
+
const field = config.fieldData;
|
|
8572
8939
|
this.localField.set(field);
|
|
8940
|
+
if (this.currentFieldCode !== config.code) {
|
|
8941
|
+
this.currentFieldCode = config.code;
|
|
8942
|
+
this.scrollPropertiesToTop();
|
|
8943
|
+
}
|
|
8944
|
+
});
|
|
8945
|
+
}
|
|
8946
|
+
scrollPropertiesToTop() {
|
|
8947
|
+
requestAnimationFrame(() => {
|
|
8948
|
+
const scrollContainer = this.elementRef.nativeElement.closest('.formeditor-properties-form');
|
|
8949
|
+
scrollContainer?.scrollTo({ top: 0 });
|
|
8573
8950
|
});
|
|
8574
8951
|
}
|
|
8575
8952
|
updateRuleValue(fr) {
|
|
@@ -8581,6 +8958,7 @@ class FieldEditorComponent {
|
|
|
8581
8958
|
return;
|
|
8582
8959
|
const visibilityRules = {
|
|
8583
8960
|
fieldName,
|
|
8961
|
+
fieldLabel: this.getDependencyFieldLabel(fieldName),
|
|
8584
8962
|
operator,
|
|
8585
8963
|
value
|
|
8586
8964
|
};
|
|
@@ -8630,6 +9008,9 @@ class FieldEditorComponent {
|
|
|
8630
9008
|
this.localField.set(updatedField);
|
|
8631
9009
|
this.fieldChange.emit(updatedField);
|
|
8632
9010
|
}
|
|
9011
|
+
getDependencyFieldLabel(fieldName) {
|
|
9012
|
+
return this.options()['fieldName']?.find(option => option.id === fieldName)?.text ?? fieldName;
|
|
9013
|
+
}
|
|
8633
9014
|
toggleSection(section) {
|
|
8634
9015
|
const currentHidden = this.hiddenSections();
|
|
8635
9016
|
if (currentHidden.includes(section)) {
|
|
@@ -8678,7 +9059,7 @@ class FieldEditorComponent {
|
|
|
8678
9059
|
}));
|
|
8679
9060
|
}
|
|
8680
9061
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FieldEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8681
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: FieldEditorComponent, isStandalone: true, selector: "lib-field-editor", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fieldChange: "fieldChange" }, ngImport: i0, template: "<div class=\"props-title\">{{'form_builder.field_editor.basic' | uicTranslate}} <i (click)=\"toggleSection('basic')\" class=\"{{hiddenSections().includes('basic') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('basic')\">\n <ui-form-wrapper\n [fields]=\"requiredFields\" \n [initialValues]=\"initialValues()\"\n [cols]=\"1\" \n (formChange)=\"updateFieldValues($event)\">\n </ui-form-wrapper>\n @if (hasOptions()) {\n <ui-field-options-editor [options]=\"localField().options ?? []\" (optionsChange)=\"updateOptions($event)\"></ui-field-options-editor>\n }\n</div>\n\n<div class=\"props-title\">{{'form_builder.field_editor.advanced' | uicTranslate}} <i (click)=\"toggleSection('advanced')\" class=\"{{hiddenSections().includes('advanced') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('advanced')\">\n <ui-form-wrapper\n [fields]=\"advancedFields()\" \n [initialValues]=\"initialValues()\"\n [cols]=\"1\" \n (formChange)=\"updateFieldValues($event)\">\n </ui-form-wrapper>\n</div>\n\n<div class=\"props-title\">{{'form_builder.field_editor.style' | uicTranslate}} <i (click)=\"toggleSection('style')\" class=\"{{hiddenSections().includes('style') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('style')\">\n <ui-form-wrapper\n [fields]=\"styleFields()\" \n [initialValues]=\"initialValues()\"\n [cols]=\"1\" \n (formChange)=\"updateFieldValues($event)\"> \n </ui-form-wrapper>\n</div>\n\n<div class=\"props-title\">{{'form_builder.field_editor.dependency_title' | uicTranslate}} <i (click)=\"toggleSection('dependency')\" class=\"{{hiddenSections().includes('dependency') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('dependency')\">\n @if (localField().visibilityRules ) {\n <p>{{'form_builder.field_editor.dependency_description' | uicTranslate}}</p>\n <ui-form-wrapper\n [fields]=\"branchFields\" \n [initialValues]=\"branchInitialValues()\"\n [externalData]=\"options()\"\n [cols]=\"1\" \n (formChange)=\"updateRuleValue($event)\">\n </ui-form-wrapper>\n <ui-button color=\"black\" size=\"s\" (click)=\"removeRule()\">{{'form_builder.field_editor.remove_relation' | uicTranslate}}</ui-button>\n }@else {\n <ui-button color=\"black\" size=\"s\" (click)=\"addRule()\">{{'form_builder.field_editor.add_relation' | uicTranslate}}</ui-button>\n }\n</div>\n", styles: [".hidden{display:none}.props-title{font-size:14px;font-weight:600;margin-bottom:8px;background:var(--grey-200);padding:5px;border-radius:5px;display:flex;justify-content:space-between}.props-title i{cursor:pointer}.props-inputs{padding-left:20px;margin-bottom:10px}p{font-size:14px;margin:10px 0;color:var(--yellow-800)}\n"], dependencies: [{ kind: "component", type: UicFormWrapperComponent, selector: "ui-form-wrapper", inputs: ["schema", "fields", "cols", "externalData", "loading", "disabled", "showButtons", "fillSelects", "initialValues", "fileUidResolverFn"], outputs: ["formSubmit", "formChange"] }, { kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }, { kind: "component", type: UicFieldOptionsEditorComponent, selector: "ui-field-options-editor", inputs: ["options"], outputs: ["optionsChange"] }] });
|
|
9062
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: FieldEditorComponent, isStandalone: true, selector: "lib-field-editor", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, focusRequiredField: { classPropertyName: "focusRequiredField", publicName: "focusRequiredField", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fieldChange: "fieldChange" }, ngImport: i0, template: "<div class=\"props-title\">{{'form_builder.field_editor.basic' | uicTranslate}} <i (click)=\"toggleSection('basic')\" class=\"{{hiddenSections().includes('basic') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('basic')\">\n <ui-form-wrapper\n [fields]=\"requiredFields\" \n [initialValues]=\"initialValues()\"\n [focusFieldName]=\"focusRequiredField() ? 'label' : null\"\n [focusFieldTrigger]=\"focusRequiredField() ? config().code : null\"\n [cols]=\"1\" \n (formChange)=\"updateFieldValues($event)\">\n </ui-form-wrapper>\n @if (hasOptions()) {\n <ui-field-options-editor [options]=\"localField().options ?? []\" (optionsChange)=\"updateOptions($event)\"></ui-field-options-editor>\n }\n</div>\n\n<div class=\"props-title\">{{'form_builder.field_editor.advanced' | uicTranslate}} <i (click)=\"toggleSection('advanced')\" class=\"{{hiddenSections().includes('advanced') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('advanced')\">\n <ui-form-wrapper\n [fields]=\"advancedFields()\" \n [initialValues]=\"initialValues()\"\n [cols]=\"1\" \n (formChange)=\"updateFieldValues($event)\">\n </ui-form-wrapper>\n</div>\n\n<div class=\"props-title\">{{'form_builder.field_editor.style' | uicTranslate}} <i (click)=\"toggleSection('style')\" class=\"{{hiddenSections().includes('style') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('style')\">\n <ui-form-wrapper\n [fields]=\"styleFields()\" \n [initialValues]=\"initialValues()\"\n [cols]=\"1\" \n (formChange)=\"updateFieldValues($event)\"> \n </ui-form-wrapper>\n</div>\n\n<div class=\"props-title\">{{'form_builder.field_editor.dependency_title' | uicTranslate}} <i (click)=\"toggleSection('dependency')\" class=\"{{hiddenSections().includes('dependency') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('dependency')\">\n @if (localField().visibilityRules ) {\n <p>{{'form_builder.field_editor.dependency_description' | uicTranslate}}</p>\n <ui-form-wrapper\n [fields]=\"branchFields\" \n [initialValues]=\"branchInitialValues()\"\n [externalData]=\"options()\"\n [cols]=\"1\" \n (formChange)=\"updateRuleValue($event)\">\n </ui-form-wrapper>\n <ui-button color=\"black\" size=\"s\" (click)=\"removeRule()\">{{'form_builder.field_editor.remove_relation' | uicTranslate}}</ui-button>\n }@else {\n <ui-button color=\"black\" size=\"s\" (click)=\"addRule()\">{{'form_builder.field_editor.add_relation' | uicTranslate}}</ui-button>\n }\n</div>\n", styles: [".hidden{display:none}.props-title{font-size:14px;font-weight:600;margin-bottom:8px;background:var(--grey-200);padding:5px;border-radius:5px;display:flex;justify-content:space-between}.props-title i{cursor:pointer}.props-inputs{padding-left:20px;margin-bottom:10px}p{font-size:14px;margin:10px 0;color:var(--yellow-800)}\n"], dependencies: [{ kind: "component", type: UicFormWrapperComponent, selector: "ui-form-wrapper", inputs: ["schema", "fields", "cols", "externalData", "selectOptionsResolver", "loading", "disabled", "showButtons", "fillSelects", "initialValues", "focusFieldName", "focusFieldTrigger", "fileUidResolverFn"], outputs: ["formSubmit", "formChange", "optionsSourceError"] }, { kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }, { kind: "component", type: UicFieldOptionsEditorComponent, selector: "ui-field-options-editor", inputs: ["options"], outputs: ["optionsChange"] }] });
|
|
8682
9063
|
}
|
|
8683
9064
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FieldEditorComponent, decorators: [{
|
|
8684
9065
|
type: Component,
|
|
@@ -8687,7 +9068,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
8687
9068
|
UicButtonComponent,
|
|
8688
9069
|
UicTranslatePipe,
|
|
8689
9070
|
UicFieldOptionsEditorComponent
|
|
8690
|
-
], template: "<div class=\"props-title\">{{'form_builder.field_editor.basic' | uicTranslate}} <i (click)=\"toggleSection('basic')\" class=\"{{hiddenSections().includes('basic') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('basic')\">\n <ui-form-wrapper\n [fields]=\"requiredFields\" \n [initialValues]=\"initialValues()\"\n [cols]=\"1\" \n (formChange)=\"updateFieldValues($event)\">\n </ui-form-wrapper>\n @if (hasOptions()) {\n <ui-field-options-editor [options]=\"localField().options ?? []\" (optionsChange)=\"updateOptions($event)\"></ui-field-options-editor>\n }\n</div>\n\n<div class=\"props-title\">{{'form_builder.field_editor.advanced' | uicTranslate}} <i (click)=\"toggleSection('advanced')\" class=\"{{hiddenSections().includes('advanced') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('advanced')\">\n <ui-form-wrapper\n [fields]=\"advancedFields()\" \n [initialValues]=\"initialValues()\"\n [cols]=\"1\" \n (formChange)=\"updateFieldValues($event)\">\n </ui-form-wrapper>\n</div>\n\n<div class=\"props-title\">{{'form_builder.field_editor.style' | uicTranslate}} <i (click)=\"toggleSection('style')\" class=\"{{hiddenSections().includes('style') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('style')\">\n <ui-form-wrapper\n [fields]=\"styleFields()\" \n [initialValues]=\"initialValues()\"\n [cols]=\"1\" \n (formChange)=\"updateFieldValues($event)\"> \n </ui-form-wrapper>\n</div>\n\n<div class=\"props-title\">{{'form_builder.field_editor.dependency_title' | uicTranslate}} <i (click)=\"toggleSection('dependency')\" class=\"{{hiddenSections().includes('dependency') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('dependency')\">\n @if (localField().visibilityRules ) {\n <p>{{'form_builder.field_editor.dependency_description' | uicTranslate}}</p>\n <ui-form-wrapper\n [fields]=\"branchFields\" \n [initialValues]=\"branchInitialValues()\"\n [externalData]=\"options()\"\n [cols]=\"1\" \n (formChange)=\"updateRuleValue($event)\">\n </ui-form-wrapper>\n <ui-button color=\"black\" size=\"s\" (click)=\"removeRule()\">{{'form_builder.field_editor.remove_relation' | uicTranslate}}</ui-button>\n }@else {\n <ui-button color=\"black\" size=\"s\" (click)=\"addRule()\">{{'form_builder.field_editor.add_relation' | uicTranslate}}</ui-button>\n }\n</div>\n", styles: [".hidden{display:none}.props-title{font-size:14px;font-weight:600;margin-bottom:8px;background:var(--grey-200);padding:5px;border-radius:5px;display:flex;justify-content:space-between}.props-title i{cursor:pointer}.props-inputs{padding-left:20px;margin-bottom:10px}p{font-size:14px;margin:10px 0;color:var(--yellow-800)}\n"] }]
|
|
9071
|
+
], template: "<div class=\"props-title\">{{'form_builder.field_editor.basic' | uicTranslate}} <i (click)=\"toggleSection('basic')\" class=\"{{hiddenSections().includes('basic') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('basic')\">\n <ui-form-wrapper\n [fields]=\"requiredFields\" \n [initialValues]=\"initialValues()\"\n [focusFieldName]=\"focusRequiredField() ? 'label' : null\"\n [focusFieldTrigger]=\"focusRequiredField() ? config().code : null\"\n [cols]=\"1\" \n (formChange)=\"updateFieldValues($event)\">\n </ui-form-wrapper>\n @if (hasOptions()) {\n <ui-field-options-editor [options]=\"localField().options ?? []\" (optionsChange)=\"updateOptions($event)\"></ui-field-options-editor>\n }\n</div>\n\n<div class=\"props-title\">{{'form_builder.field_editor.advanced' | uicTranslate}} <i (click)=\"toggleSection('advanced')\" class=\"{{hiddenSections().includes('advanced') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('advanced')\">\n <ui-form-wrapper\n [fields]=\"advancedFields()\" \n [initialValues]=\"initialValues()\"\n [cols]=\"1\" \n (formChange)=\"updateFieldValues($event)\">\n </ui-form-wrapper>\n</div>\n\n<div class=\"props-title\">{{'form_builder.field_editor.style' | uicTranslate}} <i (click)=\"toggleSection('style')\" class=\"{{hiddenSections().includes('style') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('style')\">\n <ui-form-wrapper\n [fields]=\"styleFields()\" \n [initialValues]=\"initialValues()\"\n [cols]=\"1\" \n (formChange)=\"updateFieldValues($event)\"> \n </ui-form-wrapper>\n</div>\n\n<div class=\"props-title\">{{'form_builder.field_editor.dependency_title' | uicTranslate}} <i (click)=\"toggleSection('dependency')\" class=\"{{hiddenSections().includes('dependency') ? 'ri-arrow-down-s-line' : 'ri-arrow-up-s-line'}}\"></i> </div>\n<div class=\"props-inputs\" [class.hidden]=\"hiddenSections().includes('dependency')\">\n @if (localField().visibilityRules ) {\n <p>{{'form_builder.field_editor.dependency_description' | uicTranslate}}</p>\n <ui-form-wrapper\n [fields]=\"branchFields\" \n [initialValues]=\"branchInitialValues()\"\n [externalData]=\"options()\"\n [cols]=\"1\" \n (formChange)=\"updateRuleValue($event)\">\n </ui-form-wrapper>\n <ui-button color=\"black\" size=\"s\" (click)=\"removeRule()\">{{'form_builder.field_editor.remove_relation' | uicTranslate}}</ui-button>\n }@else {\n <ui-button color=\"black\" size=\"s\" (click)=\"addRule()\">{{'form_builder.field_editor.add_relation' | uicTranslate}}</ui-button>\n }\n</div>\n", styles: [".hidden{display:none}.props-title{font-size:14px;font-weight:600;margin-bottom:8px;background:var(--grey-200);padding:5px;border-radius:5px;display:flex;justify-content:space-between}.props-title i{cursor:pointer}.props-inputs{padding-left:20px;margin-bottom:10px}p{font-size:14px;margin:10px 0;color:var(--yellow-800)}\n"] }]
|
|
8691
9072
|
}], ctorParameters: () => [] });
|
|
8692
9073
|
|
|
8693
9074
|
class FieldTypeSelectorComponent {
|
|
@@ -8744,7 +9125,7 @@ class BlockEditorComponent {
|
|
|
8744
9125
|
this.blockChange.emit({ ...this.block(), fields: nextFields });
|
|
8745
9126
|
}
|
|
8746
9127
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BlockEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8747
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: BlockEditorComponent, isStandalone: true, selector: "lib-block-editor", inputs: { block: { classPropertyName: "block", publicName: "block", isSignal: true, isRequired: false, transformFunction: null }, selectedFieldId: { classPropertyName: "selectedFieldId", publicName: "selectedFieldId", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { blockChange: "blockChange", addFieldRequest: "addFieldRequest", deleteBlock: "deleteBlock", notifySelectedField: "notifySelectedField" }, ngImport: i0, template: "<div class=\"form-block-card\">\n <div class=\"form-block-card-header\">\n <div>\n <input [placeholder]=\"'form_builder.block_title' | uicTranslate\" [ngModel]=\"block().title\" (ngModelChange)=\"changeTitle($event)\">\n <input [placeholder]=\"'form_builder.block_subtitle' | uicTranslate\" [ngModel]=\"block().subtitle\" (ngModelChange)=\"changeSubtitle($event)\">\n </div>\n <ui-button [uiTooltip]=\"'form_builder.delete_block' | uicTranslate\" (click)=\"deleteBlock.emit(block().code)\" size=\"s\" icon=\"ri-delete-bin-line\" color=\"red\" type=\"ghost\" [iconOnly]=\"true\"></ui-button>\n </div>\n <div\n class=\"form-block-card-body\"\n cdkDropList\n [cdkDropListData]=\"block().fields\"\n (cdkDropListDropped)=\"reorderFields($event)\">\n \n <!-- FIELDS -->\n @for(edtField of block().fields; track edtField.code; let i = $index) {\n <div\n class=\"xfield-card\"\n cdkDrag\n [class.selected-field]=\"selectedFieldId === edtField.code\"\n (click)=\"selectField(edtField)\">\n <i class=\"ri-draggable field-drag-handle\" cdkDragHandle></i>\n\n <div class=\"xfield-card-icon\">\n <i [class]=\"edtField.field?.icon ?? ''\"></i> \n </div>\n <div class=\"xfield-card-body\">\n <b> {{edtField.fieldData.label}} \n @if(edtField.fieldData.visibilityRules) {\n <i class=\"branched-field ri-git-merge-line\"></i> \n <span> {{edtField.fieldData.visibilityRules[0]?.fieldName??'-'}} </span>\n }\n </b>\n <p> {{edtField.field?.label ?? edtField.type ?? edtField.fieldData.type}} </p>\n </div>\n <div class=\"xfield-card-actions\">\n <ui-button (click)=\"deleteField(edtField.code, $event)\" size=\"s\" icon=\"ri-delete-bin-line\" color=\"red\" type=\"ghost\" [iconOnly]=\"true\"></ui-button>\n </div>\n </div>\n\n }\n\n </div>\n <div class=\"new-field\">\n {{'form_builder.add_new_field' | uicTranslate}}\n <lib-field-type-selector (selectType)=\"addField($event)\"></lib-field-type-selector>\n </div>\n</div>\n", styles: [".form-block-card{border:solid 1px var(--blue-500);border-radius:5px;overflow:hidden}.form-block-card-header{display:flex;gap:5px;align-items:center;background-color:#fff;padding:10px;border-bottom:solid 1px var(--grey-300)}.form-block-card-header>div{flex:1 1;gap:4px;display:flex;flex-direction:column}.form-block-card-header>div input{border:solid 1px var(--grey-100);padding:3px 6px;border-radius:5px}.form-block-card-header>div input:focus{border:solid 1px var(--primary-500);outline:none}.form-block-card-body{padding:15px;display:flex;flex-direction:column;background-color:var(--grey-50);gap:10px}.xfield-card{background-color:#fff;border-radius:5px;padding:10px;gap:10px;display:flex;align-items:center;border:solid 2px var(--grey-200);cursor:pointer;transition:border-color .3s ease}.xfield-card:hover{border-color:var(--grey-300)}.xfield-card-icon{display:flex;justify-content:center;align-items:center;border-radius:5px;width:30px;height:30px;font-size:20px;background-color:var(--grey-300);color:var(--grey-600)}.xfield-card-body{flex:1 1}.xfield-card-body b{display:flex;align-items:center;gap:5px}.xfield-card-body p{color:var(--grey-400);font-size:12px}.field-drag-handle{cursor:grab;color:var(--grey-400);transition:color .2s ease}.field-drag-handle:active{cursor:grabbing}.xfield-card:hover .field-drag-handle{color:var(--grey-600)}.cdk-drag-preview{box-sizing:border-box;border-radius:5px;box-shadow:0 6px 12px #0000002e}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.form-block-card-body.cdk-drop-list-dragging .xfield-card:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.branched-field{color:var(--yellow-600)}.selected-field,.selected-field:hover{border-color:var(--primary-500)}.new-field{border-top:solid 1px var(--grey-300);padding:10px;background-color:#fff;display:flex;flex-direction:column;gap:5px;font-size:14px}\n"], dependencies: [{ kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "directive", type: UicToolTipDirective, selector: "[uiTooltip]", inputs: ["uiTooltip"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1$3.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: FieldTypeSelectorComponent, selector: "lib-field-type-selector", outputs: ["selectType"] }] });
|
|
9128
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: BlockEditorComponent, isStandalone: true, selector: "lib-block-editor", inputs: { block: { classPropertyName: "block", publicName: "block", isSignal: true, isRequired: false, transformFunction: null }, selectedFieldId: { classPropertyName: "selectedFieldId", publicName: "selectedFieldId", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { blockChange: "blockChange", addFieldRequest: "addFieldRequest", deleteBlock: "deleteBlock", notifySelectedField: "notifySelectedField" }, ngImport: i0, template: "<div class=\"form-block-card\">\n <div class=\"form-block-card-header\">\n <div>\n <input [placeholder]=\"'form_builder.block_title' | uicTranslate\" [ngModel]=\"block().title\" (ngModelChange)=\"changeTitle($event)\">\n <input [placeholder]=\"'form_builder.block_subtitle' | uicTranslate\" [ngModel]=\"block().subtitle\" (ngModelChange)=\"changeSubtitle($event)\">\n </div>\n <ui-button [uiTooltip]=\"'form_builder.delete_block' | uicTranslate\" (click)=\"deleteBlock.emit(block().code)\" size=\"s\" icon=\"ri-delete-bin-line\" color=\"red\" type=\"ghost\" [iconOnly]=\"true\"></ui-button>\n </div>\n <div\n class=\"form-block-card-body\"\n cdkDropList\n [cdkDropListData]=\"block().fields\"\n (cdkDropListDropped)=\"reorderFields($event)\">\n \n <!-- FIELDS -->\n @for(edtField of block().fields; track edtField.code; let i = $index) {\n <div\n class=\"xfield-card\"\n cdkDrag\n [class.selected-field]=\"selectedFieldId === edtField.code\"\n (click)=\"selectField(edtField)\">\n <i class=\"ri-draggable field-drag-handle\" cdkDragHandle></i>\n\n <div class=\"xfield-card-icon\">\n <i [class]=\"edtField.field?.icon ?? ''\"></i> \n </div>\n <div class=\"xfield-card-body\">\n <b> {{edtField.fieldData.label}} \n @if(edtField.fieldData.visibilityRules) {\n <i class=\"branched-field ri-git-merge-line\"></i> \n <span class=\"vs-rule\"> {{edtField.fieldData.visibilityRules[0]?.fieldLabel ?? edtField.fieldData.visibilityRules[0]?.fieldName ?? '-'}} </span>\n }\n </b>\n <p> {{edtField.field?.label ?? edtField.type ?? edtField.fieldData.type}} </p>\n </div>\n <div class=\"xfield-card-actions\">\n <ui-button (click)=\"deleteField(edtField.code, $event)\" size=\"s\" icon=\"ri-delete-bin-line\" color=\"red\" type=\"ghost\" [iconOnly]=\"true\"></ui-button>\n </div>\n </div>\n\n }\n\n </div>\n <div class=\"new-field\">\n {{'form_builder.add_new_field' | uicTranslate}}\n <lib-field-type-selector (selectType)=\"addField($event)\"></lib-field-type-selector>\n </div>\n</div>\n", styles: [".form-block-card{border:solid 1px var(--blue-500);border-radius:5px;overflow:hidden}.form-block-card-header{display:flex;gap:5px;align-items:center;background-color:#fff;padding:10px;border-bottom:solid 1px var(--grey-300)}.form-block-card-header>div{flex:1 1;gap:4px;display:flex;flex-direction:column}.form-block-card-header>div input{border:solid 1px var(--grey-100);padding:3px 6px;border-radius:5px}.form-block-card-header>div input:focus{border:solid 1px var(--primary-500);outline:none}.form-block-card-body{padding:15px;display:flex;flex-direction:column;background-color:var(--grey-50);gap:10px}.xfield-card{background-color:#fff;border-radius:5px;padding:10px;gap:10px;display:flex;align-items:center;border:solid 2px var(--grey-200);cursor:pointer;transition:border-color .3s ease}.xfield-card:hover{border-color:var(--grey-300)}.xfield-card-icon{display:flex;justify-content:center;align-items:center;border-radius:5px;width:30px;height:30px;font-size:20px;background-color:var(--grey-300);color:var(--grey-600)}.xfield-card-body{flex:1 1}.xfield-card-body b{display:flex;align-items:center;gap:5px}.xfield-card-body p{color:var(--grey-400);font-size:12px}.field-drag-handle{cursor:grab;color:var(--grey-400);transition:color .2s ease}.field-drag-handle:active{cursor:grabbing}.xfield-card:hover .field-drag-handle{color:var(--grey-600)}.cdk-drag-preview{box-sizing:border-box;border-radius:5px;box-shadow:0 6px 12px #0000002e}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.form-block-card-body.cdk-drop-list-dragging .xfield-card:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.branched-field{color:var(--yellow-600)}.selected-field,.selected-field:hover{border-color:var(--primary-500)}.new-field{border-top:solid 1px var(--grey-300);padding:10px;background-color:#fff;display:flex;flex-direction:column;gap:5px;font-size:14px}.vs-rule{font-size:12px;color:var(--grey-600)}\n"], dependencies: [{ kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "directive", type: UicToolTipDirective, selector: "[uiTooltip]", inputs: ["uiTooltip"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1$3.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: FieldTypeSelectorComponent, selector: "lib-field-type-selector", outputs: ["selectType"] }] });
|
|
8748
9129
|
}
|
|
8749
9130
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BlockEditorComponent, decorators: [{
|
|
8750
9131
|
type: Component,
|
|
@@ -8755,7 +9136,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
8755
9136
|
DragDropModule,
|
|
8756
9137
|
FormsModule,
|
|
8757
9138
|
FieldTypeSelectorComponent
|
|
8758
|
-
], template: "<div class=\"form-block-card\">\n <div class=\"form-block-card-header\">\n <div>\n <input [placeholder]=\"'form_builder.block_title' | uicTranslate\" [ngModel]=\"block().title\" (ngModelChange)=\"changeTitle($event)\">\n <input [placeholder]=\"'form_builder.block_subtitle' | uicTranslate\" [ngModel]=\"block().subtitle\" (ngModelChange)=\"changeSubtitle($event)\">\n </div>\n <ui-button [uiTooltip]=\"'form_builder.delete_block' | uicTranslate\" (click)=\"deleteBlock.emit(block().code)\" size=\"s\" icon=\"ri-delete-bin-line\" color=\"red\" type=\"ghost\" [iconOnly]=\"true\"></ui-button>\n </div>\n <div\n class=\"form-block-card-body\"\n cdkDropList\n [cdkDropListData]=\"block().fields\"\n (cdkDropListDropped)=\"reorderFields($event)\">\n \n <!-- FIELDS -->\n @for(edtField of block().fields; track edtField.code; let i = $index) {\n <div\n class=\"xfield-card\"\n cdkDrag\n [class.selected-field]=\"selectedFieldId === edtField.code\"\n (click)=\"selectField(edtField)\">\n <i class=\"ri-draggable field-drag-handle\" cdkDragHandle></i>\n\n <div class=\"xfield-card-icon\">\n <i [class]=\"edtField.field?.icon ?? ''\"></i> \n </div>\n <div class=\"xfield-card-body\">\n <b> {{edtField.fieldData.label}} \n @if(edtField.fieldData.visibilityRules) {\n <i class=\"branched-field ri-git-merge-line\"></i> \n <span> {{edtField.fieldData.visibilityRules[0]?.fieldName??'-'}} </span>\n }\n </b>\n <p> {{edtField.field?.label ?? edtField.type ?? edtField.fieldData.type}} </p>\n </div>\n <div class=\"xfield-card-actions\">\n <ui-button (click)=\"deleteField(edtField.code, $event)\" size=\"s\" icon=\"ri-delete-bin-line\" color=\"red\" type=\"ghost\" [iconOnly]=\"true\"></ui-button>\n </div>\n </div>\n\n }\n\n </div>\n <div class=\"new-field\">\n {{'form_builder.add_new_field' | uicTranslate}}\n <lib-field-type-selector (selectType)=\"addField($event)\"></lib-field-type-selector>\n </div>\n</div>\n", styles: [".form-block-card{border:solid 1px var(--blue-500);border-radius:5px;overflow:hidden}.form-block-card-header{display:flex;gap:5px;align-items:center;background-color:#fff;padding:10px;border-bottom:solid 1px var(--grey-300)}.form-block-card-header>div{flex:1 1;gap:4px;display:flex;flex-direction:column}.form-block-card-header>div input{border:solid 1px var(--grey-100);padding:3px 6px;border-radius:5px}.form-block-card-header>div input:focus{border:solid 1px var(--primary-500);outline:none}.form-block-card-body{padding:15px;display:flex;flex-direction:column;background-color:var(--grey-50);gap:10px}.xfield-card{background-color:#fff;border-radius:5px;padding:10px;gap:10px;display:flex;align-items:center;border:solid 2px var(--grey-200);cursor:pointer;transition:border-color .3s ease}.xfield-card:hover{border-color:var(--grey-300)}.xfield-card-icon{display:flex;justify-content:center;align-items:center;border-radius:5px;width:30px;height:30px;font-size:20px;background-color:var(--grey-300);color:var(--grey-600)}.xfield-card-body{flex:1 1}.xfield-card-body b{display:flex;align-items:center;gap:5px}.xfield-card-body p{color:var(--grey-400);font-size:12px}.field-drag-handle{cursor:grab;color:var(--grey-400);transition:color .2s ease}.field-drag-handle:active{cursor:grabbing}.xfield-card:hover .field-drag-handle{color:var(--grey-600)}.cdk-drag-preview{box-sizing:border-box;border-radius:5px;box-shadow:0 6px 12px #0000002e}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.form-block-card-body.cdk-drop-list-dragging .xfield-card:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.branched-field{color:var(--yellow-600)}.selected-field,.selected-field:hover{border-color:var(--primary-500)}.new-field{border-top:solid 1px var(--grey-300);padding:10px;background-color:#fff;display:flex;flex-direction:column;gap:5px;font-size:14px}\n"] }]
|
|
9139
|
+
], template: "<div class=\"form-block-card\">\n <div class=\"form-block-card-header\">\n <div>\n <input [placeholder]=\"'form_builder.block_title' | uicTranslate\" [ngModel]=\"block().title\" (ngModelChange)=\"changeTitle($event)\">\n <input [placeholder]=\"'form_builder.block_subtitle' | uicTranslate\" [ngModel]=\"block().subtitle\" (ngModelChange)=\"changeSubtitle($event)\">\n </div>\n <ui-button [uiTooltip]=\"'form_builder.delete_block' | uicTranslate\" (click)=\"deleteBlock.emit(block().code)\" size=\"s\" icon=\"ri-delete-bin-line\" color=\"red\" type=\"ghost\" [iconOnly]=\"true\"></ui-button>\n </div>\n <div\n class=\"form-block-card-body\"\n cdkDropList\n [cdkDropListData]=\"block().fields\"\n (cdkDropListDropped)=\"reorderFields($event)\">\n \n <!-- FIELDS -->\n @for(edtField of block().fields; track edtField.code; let i = $index) {\n <div\n class=\"xfield-card\"\n cdkDrag\n [class.selected-field]=\"selectedFieldId === edtField.code\"\n (click)=\"selectField(edtField)\">\n <i class=\"ri-draggable field-drag-handle\" cdkDragHandle></i>\n\n <div class=\"xfield-card-icon\">\n <i [class]=\"edtField.field?.icon ?? ''\"></i> \n </div>\n <div class=\"xfield-card-body\">\n <b> {{edtField.fieldData.label}} \n @if(edtField.fieldData.visibilityRules) {\n <i class=\"branched-field ri-git-merge-line\"></i> \n <span class=\"vs-rule\"> {{edtField.fieldData.visibilityRules[0]?.fieldLabel ?? edtField.fieldData.visibilityRules[0]?.fieldName ?? '-'}} </span>\n }\n </b>\n <p> {{edtField.field?.label ?? edtField.type ?? edtField.fieldData.type}} </p>\n </div>\n <div class=\"xfield-card-actions\">\n <ui-button (click)=\"deleteField(edtField.code, $event)\" size=\"s\" icon=\"ri-delete-bin-line\" color=\"red\" type=\"ghost\" [iconOnly]=\"true\"></ui-button>\n </div>\n </div>\n\n }\n\n </div>\n <div class=\"new-field\">\n {{'form_builder.add_new_field' | uicTranslate}}\n <lib-field-type-selector (selectType)=\"addField($event)\"></lib-field-type-selector>\n </div>\n</div>\n", styles: [".form-block-card{border:solid 1px var(--blue-500);border-radius:5px;overflow:hidden}.form-block-card-header{display:flex;gap:5px;align-items:center;background-color:#fff;padding:10px;border-bottom:solid 1px var(--grey-300)}.form-block-card-header>div{flex:1 1;gap:4px;display:flex;flex-direction:column}.form-block-card-header>div input{border:solid 1px var(--grey-100);padding:3px 6px;border-radius:5px}.form-block-card-header>div input:focus{border:solid 1px var(--primary-500);outline:none}.form-block-card-body{padding:15px;display:flex;flex-direction:column;background-color:var(--grey-50);gap:10px}.xfield-card{background-color:#fff;border-radius:5px;padding:10px;gap:10px;display:flex;align-items:center;border:solid 2px var(--grey-200);cursor:pointer;transition:border-color .3s ease}.xfield-card:hover{border-color:var(--grey-300)}.xfield-card-icon{display:flex;justify-content:center;align-items:center;border-radius:5px;width:30px;height:30px;font-size:20px;background-color:var(--grey-300);color:var(--grey-600)}.xfield-card-body{flex:1 1}.xfield-card-body b{display:flex;align-items:center;gap:5px}.xfield-card-body p{color:var(--grey-400);font-size:12px}.field-drag-handle{cursor:grab;color:var(--grey-400);transition:color .2s ease}.field-drag-handle:active{cursor:grabbing}.xfield-card:hover .field-drag-handle{color:var(--grey-600)}.cdk-drag-preview{box-sizing:border-box;border-radius:5px;box-shadow:0 6px 12px #0000002e}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.form-block-card-body.cdk-drop-list-dragging .xfield-card:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.branched-field{color:var(--yellow-600)}.selected-field,.selected-field:hover{border-color:var(--primary-500)}.new-field{border-top:solid 1px var(--grey-300);padding:10px;background-color:#fff;display:flex;flex-direction:column;gap:5px;font-size:14px}.vs-rule{font-size:12px;color:var(--grey-600)}\n"] }]
|
|
8759
9140
|
}], propDecorators: { selectedFieldId: [{
|
|
8760
9141
|
type: Input
|
|
8761
9142
|
}] } });
|
|
@@ -8776,7 +9157,12 @@ class UicUserFormbuilderComponent {
|
|
|
8776
9157
|
editingSnapshot = signal(null);
|
|
8777
9158
|
isReadOnly = signal(true);
|
|
8778
9159
|
selectedField = signal(null);
|
|
9160
|
+
focusNewFieldCode = signal(null);
|
|
9161
|
+
propertiesWidth = signal(250);
|
|
8779
9162
|
previewSchema = computed(() => helperShowFormFromBuilder(this.editableBlocks(), this.editableCols()));
|
|
9163
|
+
isResizingProperties = false;
|
|
9164
|
+
resizeStartX = 0;
|
|
9165
|
+
resizeStartWidth = 0;
|
|
8780
9166
|
dependencyOptions = computed(() => {
|
|
8781
9167
|
const currentSelected = this.selectedField();
|
|
8782
9168
|
const options = this.editableBlocks()
|
|
@@ -8841,6 +9227,7 @@ class UicUserFormbuilderComponent {
|
|
|
8841
9227
|
const removedBlock = this.editableBlocks().find(block => block.code === code);
|
|
8842
9228
|
if (removedBlock && this.selectedField() && removedBlock.fields.some(field => field.code === this.selectedField()?.code)) {
|
|
8843
9229
|
this.selectedField.set(null);
|
|
9230
|
+
this.focusNewFieldCode.set(null);
|
|
8844
9231
|
}
|
|
8845
9232
|
this.editableBlocks.update(blocks => blocks.filter(block => block.code !== code));
|
|
8846
9233
|
}
|
|
@@ -8860,6 +9247,27 @@ class UicUserFormbuilderComponent {
|
|
|
8860
9247
|
this.editableBlocks.update(blocks => blocks.map(block => block.code === blockCode
|
|
8861
9248
|
? { ...block, fields: [...block.fields, updatedField] }
|
|
8862
9249
|
: block));
|
|
9250
|
+
this.selectedField.set(updatedField);
|
|
9251
|
+
this.focusNewFieldCode.set(updatedField.code);
|
|
9252
|
+
}
|
|
9253
|
+
selectField(field) {
|
|
9254
|
+
this.selectedField.set(field);
|
|
9255
|
+
this.focusNewFieldCode.set(null);
|
|
9256
|
+
}
|
|
9257
|
+
startPropertiesResize(event) {
|
|
9258
|
+
event.preventDefault();
|
|
9259
|
+
this.isResizingProperties = true;
|
|
9260
|
+
this.resizeStartX = event.clientX;
|
|
9261
|
+
this.resizeStartWidth = this.propertiesWidth();
|
|
9262
|
+
}
|
|
9263
|
+
onPropertiesResize(event) {
|
|
9264
|
+
if (!this.isResizingProperties)
|
|
9265
|
+
return;
|
|
9266
|
+
const nextWidth = this.resizeStartWidth + (this.resizeStartX - event.clientX);
|
|
9267
|
+
this.propertiesWidth.set(Math.min(Math.max(nextWidth, 250), 600));
|
|
9268
|
+
}
|
|
9269
|
+
stopPropertiesResize() {
|
|
9270
|
+
this.isResizingProperties = false;
|
|
8863
9271
|
}
|
|
8864
9272
|
printForm() {
|
|
8865
9273
|
this.modalService.openFloatingModal(FormPreviewComponent, {
|
|
@@ -8880,7 +9288,7 @@ class UicUserFormbuilderComponent {
|
|
|
8880
9288
|
fields: block.fields.map((field, index) => ({
|
|
8881
9289
|
...field,
|
|
8882
9290
|
order: index + 1,
|
|
8883
|
-
fieldData: this.
|
|
9291
|
+
fieldData: this.prepareFieldDataForSubmit(field.fieldData)
|
|
8884
9292
|
}))
|
|
8885
9293
|
}));
|
|
8886
9294
|
this.editableBlocks.set(blocksWithOrderedFields);
|
|
@@ -8921,6 +9329,7 @@ class UicUserFormbuilderComponent {
|
|
|
8921
9329
|
this.editableCols.set(snapshot.cols ?? 2);
|
|
8922
9330
|
this.editableBlocks.set(this.prepareBlocksForLocalState(snapshot.blocks ?? []));
|
|
8923
9331
|
this.selectedField.set(null);
|
|
9332
|
+
this.focusNewFieldCode.set(null);
|
|
8924
9333
|
this.editingSnapshot.set(null);
|
|
8925
9334
|
this.isReadOnly.set(true);
|
|
8926
9335
|
}
|
|
@@ -8969,20 +9378,52 @@ class UicUserFormbuilderComponent {
|
|
|
8969
9378
|
}
|
|
8970
9379
|
hydrateBlocks(blocks) {
|
|
8971
9380
|
let changed = false;
|
|
9381
|
+
const dependencyLabelByName = new Map(blocks
|
|
9382
|
+
.flatMap(block => block.fields)
|
|
9383
|
+
.map(field => [
|
|
9384
|
+
field.fieldData.name,
|
|
9385
|
+
field.fieldData.label || field.fieldData.name
|
|
9386
|
+
]));
|
|
8972
9387
|
const hydratedBlocks = blocks.map(block => {
|
|
8973
9388
|
let blockChanged = false;
|
|
8974
9389
|
const hydratedFields = block.fields.map(field => {
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
9390
|
+
let hydratedField = field;
|
|
9391
|
+
if (!field.field && field.type) {
|
|
9392
|
+
const fieldConfig = FIELDS_CONFIG.find(config => config.value === field.type);
|
|
9393
|
+
if (fieldConfig) {
|
|
9394
|
+
changed = true;
|
|
9395
|
+
blockChanged = true;
|
|
9396
|
+
hydratedField = {
|
|
9397
|
+
...hydratedField,
|
|
9398
|
+
field: fieldConfig
|
|
9399
|
+
};
|
|
9400
|
+
}
|
|
9401
|
+
}
|
|
9402
|
+
const visibilityRules = hydratedField.fieldData.visibilityRules;
|
|
9403
|
+
if (!visibilityRules?.length)
|
|
9404
|
+
return hydratedField;
|
|
9405
|
+
let rulesChanged = false;
|
|
9406
|
+
const hydratedRules = visibilityRules.map(rule => {
|
|
9407
|
+
const dependencyLabel = dependencyLabelByName.get(rule.fieldName) ?? rule.fieldName;
|
|
9408
|
+
if (rule.fieldLabel === dependencyLabel)
|
|
9409
|
+
return rule;
|
|
9410
|
+
changed = true;
|
|
9411
|
+
blockChanged = true;
|
|
9412
|
+
rulesChanged = true;
|
|
9413
|
+
return {
|
|
9414
|
+
...rule,
|
|
9415
|
+
fieldLabel: dependencyLabel
|
|
9416
|
+
};
|
|
9417
|
+
});
|
|
9418
|
+
return !rulesChanged
|
|
9419
|
+
? hydratedField
|
|
9420
|
+
: {
|
|
9421
|
+
...hydratedField,
|
|
9422
|
+
fieldData: {
|
|
9423
|
+
...hydratedField.fieldData,
|
|
9424
|
+
visibilityRules: hydratedRules
|
|
9425
|
+
}
|
|
9426
|
+
};
|
|
8986
9427
|
});
|
|
8987
9428
|
return blockChanged ? { ...block, fields: hydratedFields } : block;
|
|
8988
9429
|
});
|
|
@@ -9004,6 +9445,23 @@ class UicUserFormbuilderComponent {
|
|
|
9004
9445
|
}
|
|
9005
9446
|
return value;
|
|
9006
9447
|
}
|
|
9448
|
+
prepareFieldDataForSubmit(fieldData) {
|
|
9449
|
+
const cleanFieldData = this.removeNullProperties(fieldData);
|
|
9450
|
+
const optionsSource = cleanFieldData.optionsSource;
|
|
9451
|
+
if (!optionsSource) {
|
|
9452
|
+
return cleanFieldData;
|
|
9453
|
+
}
|
|
9454
|
+
const cleanOptionsSource = Object.fromEntries(Object.entries(optionsSource)
|
|
9455
|
+
.filter(([, value]) => value !== null && value !== undefined && value !== ''));
|
|
9456
|
+
if (!cleanOptionsSource['key']) {
|
|
9457
|
+
const { optionsSource: _optionsSource, ...restFieldData } = cleanFieldData;
|
|
9458
|
+
return restFieldData;
|
|
9459
|
+
}
|
|
9460
|
+
return {
|
|
9461
|
+
...cleanFieldData,
|
|
9462
|
+
optionsSource: cleanOptionsSource
|
|
9463
|
+
};
|
|
9464
|
+
}
|
|
9007
9465
|
deepClone(value) {
|
|
9008
9466
|
if (Array.isArray(value)) {
|
|
9009
9467
|
return value.map(item => this.deepClone(item));
|
|
@@ -9014,7 +9472,7 @@ class UicUserFormbuilderComponent {
|
|
|
9014
9472
|
return value;
|
|
9015
9473
|
}
|
|
9016
9474
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicUserFormbuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9017
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: UicUserFormbuilderComponent, isStandalone: true, selector: "ui-user-formbuilder", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null }, formTitle: { classPropertyName: "formTitle", publicName: "formTitle", isSignal: false, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, editableFormInput: { classPropertyName: "editableFormInput", publicName: "editableForm", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { submitFormRequest: "submitFormRequest" }, ngImport: i0, template: "<div class=\"formeditor\" [class.focused]=\"!isReadOnly()\">\r\n <div class=\"formeditor-header\">\r\n <div style=\"flex: 1 1;\">\r\n {{formTitle}} \r\n \r\n <div class=\"cols-selector\"> \r\n @if (isReadOnly()) {\r\n {{editableCols()}}\r\n }@else {\r\n <ui-select [options]=\"[{id: 1, text: '1'}, {id: 2, text: '2'}, {id: 3, text: '3'}, {id: 4, text: '4'}]\" [ngModel]=\"editableCols()\" (ngModelChange)=\"editableCols.set($event)\"></ui-select> \r\n }\r\n col(s)</div>\r\n </div>\r\n @if (isReadOnly()) {\r\n @if (!disabled) {\r\n <ui-button color=\"black\" icon=\"ri-edit-line\" text=\"Editar\" (click)=\"enableEditMode()\"></ui-button>\r\n }\r\n } @else {\r\n <ui-button color=\"black\" type=\"bordered\" icon=\"ri-eye-line\" [text]=\"'form_builder.preview_form' | uicTranslate\" (click)=\"printForm()\"></ui-button>\r\n <ui-button color=\"black\" type=\"bordered\" icon=\"ri-close-line\" text=\"Descartar cambios\" (click)=\"discardChanges()\"></ui-button>\r\n <ui-button color=\"black\" icon=\"ri-check-line\" [text]=\"'form_builder.submit_form' | uicTranslate\" (click)=\"submitForm()\"></ui-button>\r\n }\r\n </div>\r\n @if (!isReadOnly()) {\r\n <div class=\"formeditor-body\">\r\n \r\n <!-- BLOCKS -->\r\n <div class=\"formeditor-overflow\">\r\n <div class=\"formeditor-workarea\">\r\n @for (block of editableBlocks(); track block.code; let i = $index) {\r\n <lib-block-editor \r\n [block]=\"block\"\r\n [selectedFieldId]=\"selectedField()?.code ?? null\"\
|
|
9475
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: UicUserFormbuilderComponent, isStandalone: true, selector: "ui-user-formbuilder", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null }, formTitle: { classPropertyName: "formTitle", publicName: "formTitle", isSignal: false, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, editableFormInput: { classPropertyName: "editableFormInput", publicName: "editableForm", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { submitFormRequest: "submitFormRequest" }, host: { listeners: { "document:mousemove": "onPropertiesResize($event)", "document:mouseup": "stopPropertiesResize()" } }, ngImport: i0, template: "<div class=\"formeditor\" [class.focused]=\"!isReadOnly()\">\r\n <div class=\"formeditor-header\">\r\n <div style=\"flex: 1 1;\">\r\n {{formTitle}} \r\n \r\n <div class=\"cols-selector\"> \r\n @if (isReadOnly()) {\r\n {{editableCols()}}\r\n }@else {\r\n <ui-select [options]=\"[{id: 1, text: '1'}, {id: 2, text: '2'}, {id: 3, text: '3'}, {id: 4, text: '4'}]\" [ngModel]=\"editableCols()\" (ngModelChange)=\"editableCols.set($event)\"></ui-select> \r\n }\r\n col(s)</div>\r\n </div>\r\n @if (isReadOnly()) {\r\n @if (!disabled) {\r\n <ui-button color=\"black\" icon=\"ri-edit-line\" text=\"Editar\" (click)=\"enableEditMode()\"></ui-button>\r\n }\r\n } @else {\r\n <ui-button color=\"black\" type=\"bordered\" icon=\"ri-eye-line\" [text]=\"'form_builder.preview_form' | uicTranslate\" (click)=\"printForm()\"></ui-button>\r\n <ui-button color=\"black\" type=\"bordered\" icon=\"ri-close-line\" text=\"Descartar cambios\" (click)=\"discardChanges()\"></ui-button>\r\n <ui-button color=\"black\" icon=\"ri-check-line\" [text]=\"'form_builder.submit_form' | uicTranslate\" (click)=\"submitForm()\"></ui-button>\r\n }\r\n </div>\r\n @if (!isReadOnly()) {\r\n <div class=\"formeditor-body\">\r\n \r\n <!-- BLOCKS -->\r\n <div class=\"formeditor-overflow\">\r\n <div class=\"formeditor-workarea\">\r\n @for (block of editableBlocks(); track block.code; let i = $index) {\r\n <lib-block-editor \r\n [block]=\"block\"\r\n [selectedFieldId]=\"selectedField()?.code ?? null\"\n (blockChange)=\"onBlockChange(i, $event)\"\n (addFieldRequest)=\"addField(block.code, $event)\"\n (notifySelectedField)=\"selectField($event)\"\n (deleteBlock)=\"deleteBlock($event)\">\n </lib-block-editor>\n }\r\n <ui-button type=\"bordered\" icon=\"ri-add-line\" color=\"black\" [text]=\"'form_builder.add_block' | uicTranslate\" (click)=\"addBlock()\"></ui-button>\r\n </div>\r\n </div>\r\n <!-- PROPERTIES -->\r\n <div class=\"formeditor-properties\" [style.width.px]=\"propertiesWidth()\">\n <div\n class=\"formeditor-properties-resize\"\n (mousedown)=\"startPropertiesResize($event)\">\n </div>\n <h3>Propiedades</h3>\n <div class=\"formeditor-properties-form\">\n @if (selectedField() ) {\r\n <lib-field-editor \n [config]=\"selectedField()!\"\n [focusRequiredField]=\"focusNewFieldCode() === selectedField()?.code\"\n [options]=\"dependencyOptions()\"\n (fieldChange)=\"onFieldChange($event)\">\n </lib-field-editor>\n }@else{\r\n <div class=\"no-selected-field\">\r\n <i class=\"ri-edit-box-line\"></i>\r\n <p>{{'form_builder.select_field_to_edit' | uicTranslate}}</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n }@else {\r\n <div class=\"form-preview\">\r\n <ui-form-wrapper \r\n [schema]=\"previewSchema()\"\r\n [showButtons]=\"false\">\r\n </ui-form-wrapper>\r\n </div>\r\n }\r\n </div>\r\n\r\n", styles: [".formeditor{display:flex;flex-direction:column;overflow:hidden;background-color:var(--grey-100);border:solid 1px var(--grey-300);border-radius:5px;max-height:500px}.formeditor-header{background-color:#fff;padding:5px 10px;align-items:center;display:flex;gap:10px;border-bottom:solid 1px var(--grey-300)}.formeditor-body{display:flex;gap:10px;overflow:hidden;padding:10px;min-height:0}.formeditor-overflow{padding:5px;flex:1 1;overflow:auto;min-width:0}.formeditor-workarea{display:flex;flex-direction:column;gap:15px;height:fit-content}.formeditor-properties{width:250px;flex:0 0 auto;display:flex;flex-direction:column;position:relative;background-color:#fff;border:solid 1px var(--grey-300);border-radius:5px;min-height:0;min-width:250px;max-width:600px}.formeditor-properties-resize{position:absolute;top:0;bottom:0;left:-6px;width:10px;cursor:col-resize;z-index:1}.formeditor-properties>h3{padding:10px;border-bottom:solid 1px var(--grey-300)}.formeditor-properties-form{padding:10px;overflow:auto;flex:1 1 auto;min-height:0}.form-preview{padding:20px;overflow:auto;background-color:#fff}.focused{border:solid 1px var(--primary-400);border-radius:10px;box-shadow:0 0 0 3px var(--secondary-alpha)}.no-selected-field{width:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;padding:20px 0;font-size:13px;gap:15px;text-align:center;color:var(--grey-400)}.no-selected-field i{font-size:24px}.cols-selector{margin-left:8px;padding-left:8px;border-left:solid 1px var(--grey-400);display:inline-flex;align-items:center;gap:5px}\n"], dependencies: [{ kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "component", type: UicFormWrapperComponent, selector: "ui-form-wrapper", inputs: ["schema", "fields", "cols", "externalData", "selectOptionsResolver", "loading", "disabled", "showButtons", "fillSelects", "initialValues", "focusFieldName", "focusFieldTrigger", "fileUidResolverFn"], outputs: ["formSubmit", "formChange", "optionsSourceError"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }, { kind: "component", type: FieldEditorComponent, selector: "lib-field-editor", inputs: ["config", "focusRequiredField", "options"], outputs: ["fieldChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BlockEditorComponent, selector: "lib-block-editor", inputs: ["block", "selectedFieldId"], outputs: ["blockChange", "addFieldRequest", "deleteBlock", "notifySelectedField"] }, { kind: "component", type: UicSelectComponent, selector: "ui-select", inputs: ["icon", "iconColor", "internalIcon", "internalIconColor", "size", "label", "error", "tip", "showSubtitle", "disabled", "nonSelectedText", "noneText", "emptyText", "searcherEnabled", "loading", "nullable", "options"] }] });
|
|
9018
9476
|
}
|
|
9019
9477
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicUserFormbuilderComponent, decorators: [{
|
|
9020
9478
|
type: Component,
|
|
@@ -9026,11 +9484,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
9026
9484
|
FormsModule,
|
|
9027
9485
|
BlockEditorComponent,
|
|
9028
9486
|
UicSelectComponent
|
|
9029
|
-
], template: "<div class=\"formeditor\" [class.focused]=\"!isReadOnly()\">\r\n <div class=\"formeditor-header\">\r\n <div style=\"flex: 1 1;\">\r\n {{formTitle}} \r\n \r\n <div class=\"cols-selector\"> \r\n @if (isReadOnly()) {\r\n {{editableCols()}}\r\n }@else {\r\n <ui-select [options]=\"[{id: 1, text: '1'}, {id: 2, text: '2'}, {id: 3, text: '3'}, {id: 4, text: '4'}]\" [ngModel]=\"editableCols()\" (ngModelChange)=\"editableCols.set($event)\"></ui-select> \r\n }\r\n col(s)</div>\r\n </div>\r\n @if (isReadOnly()) {\r\n @if (!disabled) {\r\n <ui-button color=\"black\" icon=\"ri-edit-line\" text=\"Editar\" (click)=\"enableEditMode()\"></ui-button>\r\n }\r\n } @else {\r\n <ui-button color=\"black\" type=\"bordered\" icon=\"ri-eye-line\" [text]=\"'form_builder.preview_form' | uicTranslate\" (click)=\"printForm()\"></ui-button>\r\n <ui-button color=\"black\" type=\"bordered\" icon=\"ri-close-line\" text=\"Descartar cambios\" (click)=\"discardChanges()\"></ui-button>\r\n <ui-button color=\"black\" icon=\"ri-check-line\" [text]=\"'form_builder.submit_form' | uicTranslate\" (click)=\"submitForm()\"></ui-button>\r\n }\r\n </div>\r\n @if (!isReadOnly()) {\r\n <div class=\"formeditor-body\">\r\n \r\n <!-- BLOCKS -->\r\n <div class=\"formeditor-overflow\">\r\n <div class=\"formeditor-workarea\">\r\n @for (block of editableBlocks(); track block.code; let i = $index) {\r\n <lib-block-editor \r\n [block]=\"block\"\r\n [selectedFieldId]=\"selectedField()?.code ?? null\"\
|
|
9487
|
+
], template: "<div class=\"formeditor\" [class.focused]=\"!isReadOnly()\">\r\n <div class=\"formeditor-header\">\r\n <div style=\"flex: 1 1;\">\r\n {{formTitle}} \r\n \r\n <div class=\"cols-selector\"> \r\n @if (isReadOnly()) {\r\n {{editableCols()}}\r\n }@else {\r\n <ui-select [options]=\"[{id: 1, text: '1'}, {id: 2, text: '2'}, {id: 3, text: '3'}, {id: 4, text: '4'}]\" [ngModel]=\"editableCols()\" (ngModelChange)=\"editableCols.set($event)\"></ui-select> \r\n }\r\n col(s)</div>\r\n </div>\r\n @if (isReadOnly()) {\r\n @if (!disabled) {\r\n <ui-button color=\"black\" icon=\"ri-edit-line\" text=\"Editar\" (click)=\"enableEditMode()\"></ui-button>\r\n }\r\n } @else {\r\n <ui-button color=\"black\" type=\"bordered\" icon=\"ri-eye-line\" [text]=\"'form_builder.preview_form' | uicTranslate\" (click)=\"printForm()\"></ui-button>\r\n <ui-button color=\"black\" type=\"bordered\" icon=\"ri-close-line\" text=\"Descartar cambios\" (click)=\"discardChanges()\"></ui-button>\r\n <ui-button color=\"black\" icon=\"ri-check-line\" [text]=\"'form_builder.submit_form' | uicTranslate\" (click)=\"submitForm()\"></ui-button>\r\n }\r\n </div>\r\n @if (!isReadOnly()) {\r\n <div class=\"formeditor-body\">\r\n \r\n <!-- BLOCKS -->\r\n <div class=\"formeditor-overflow\">\r\n <div class=\"formeditor-workarea\">\r\n @for (block of editableBlocks(); track block.code; let i = $index) {\r\n <lib-block-editor \r\n [block]=\"block\"\r\n [selectedFieldId]=\"selectedField()?.code ?? null\"\n (blockChange)=\"onBlockChange(i, $event)\"\n (addFieldRequest)=\"addField(block.code, $event)\"\n (notifySelectedField)=\"selectField($event)\"\n (deleteBlock)=\"deleteBlock($event)\">\n </lib-block-editor>\n }\r\n <ui-button type=\"bordered\" icon=\"ri-add-line\" color=\"black\" [text]=\"'form_builder.add_block' | uicTranslate\" (click)=\"addBlock()\"></ui-button>\r\n </div>\r\n </div>\r\n <!-- PROPERTIES -->\r\n <div class=\"formeditor-properties\" [style.width.px]=\"propertiesWidth()\">\n <div\n class=\"formeditor-properties-resize\"\n (mousedown)=\"startPropertiesResize($event)\">\n </div>\n <h3>Propiedades</h3>\n <div class=\"formeditor-properties-form\">\n @if (selectedField() ) {\r\n <lib-field-editor \n [config]=\"selectedField()!\"\n [focusRequiredField]=\"focusNewFieldCode() === selectedField()?.code\"\n [options]=\"dependencyOptions()\"\n (fieldChange)=\"onFieldChange($event)\">\n </lib-field-editor>\n }@else{\r\n <div class=\"no-selected-field\">\r\n <i class=\"ri-edit-box-line\"></i>\r\n <p>{{'form_builder.select_field_to_edit' | uicTranslate}}</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n }@else {\r\n <div class=\"form-preview\">\r\n <ui-form-wrapper \r\n [schema]=\"previewSchema()\"\r\n [showButtons]=\"false\">\r\n </ui-form-wrapper>\r\n </div>\r\n }\r\n </div>\r\n\r\n", styles: [".formeditor{display:flex;flex-direction:column;overflow:hidden;background-color:var(--grey-100);border:solid 1px var(--grey-300);border-radius:5px;max-height:500px}.formeditor-header{background-color:#fff;padding:5px 10px;align-items:center;display:flex;gap:10px;border-bottom:solid 1px var(--grey-300)}.formeditor-body{display:flex;gap:10px;overflow:hidden;padding:10px;min-height:0}.formeditor-overflow{padding:5px;flex:1 1;overflow:auto;min-width:0}.formeditor-workarea{display:flex;flex-direction:column;gap:15px;height:fit-content}.formeditor-properties{width:250px;flex:0 0 auto;display:flex;flex-direction:column;position:relative;background-color:#fff;border:solid 1px var(--grey-300);border-radius:5px;min-height:0;min-width:250px;max-width:600px}.formeditor-properties-resize{position:absolute;top:0;bottom:0;left:-6px;width:10px;cursor:col-resize;z-index:1}.formeditor-properties>h3{padding:10px;border-bottom:solid 1px var(--grey-300)}.formeditor-properties-form{padding:10px;overflow:auto;flex:1 1 auto;min-height:0}.form-preview{padding:20px;overflow:auto;background-color:#fff}.focused{border:solid 1px var(--primary-400);border-radius:10px;box-shadow:0 0 0 3px var(--secondary-alpha)}.no-selected-field{width:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;padding:20px 0;font-size:13px;gap:15px;text-align:center;color:var(--grey-400)}.no-selected-field i{font-size:24px}.cols-selector{margin-left:8px;padding-left:8px;border-left:solid 1px var(--grey-400);display:inline-flex;align-items:center;gap:5px}\n"] }]
|
|
9030
9488
|
}], ctorParameters: () => [], propDecorators: { disabled: [{
|
|
9031
9489
|
type: Input
|
|
9032
9490
|
}], formTitle: [{
|
|
9033
9491
|
type: Input
|
|
9492
|
+
}], onPropertiesResize: [{
|
|
9493
|
+
type: HostListener,
|
|
9494
|
+
args: ['document:mousemove', ['$event']]
|
|
9495
|
+
}], stopPropertiesResize: [{
|
|
9496
|
+
type: HostListener,
|
|
9497
|
+
args: ['document:mouseup']
|
|
9034
9498
|
}] } });
|
|
9035
9499
|
|
|
9036
9500
|
class RuleDefinirionComponent {
|
|
@@ -9216,7 +9680,7 @@ class RuleDefinirionComponent {
|
|
|
9216
9680
|
return condition.id === 0 ? (condition.temporalId ?? '') : condition.id;
|
|
9217
9681
|
}
|
|
9218
9682
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: RuleDefinirionComponent, deps: [{ token: MODAL_DATA }], target: i0.ɵɵFactoryTarget.Component });
|
|
9219
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: RuleDefinirionComponent, isStandalone: true, selector: "lib-rule-definirion", ngImport: i0, template: "\n@if (newRule) {\n <ui-form-wrapper #formWrapper \n (formChange)=\"updateFormNewRule($event)\"\n (formSubmit)=\"createAndSelectRule($event)\" \n [initialValues]=\"initialValues\"\n [fields]=\"fields\" \n [cols]=\"2\"></ui-form-wrapper>\n <div class=\"condition-btns\">\n <ui-button icon=\"ri-arrow-left-line\" (click)=\"newRule = false\" color=\"black\" type=\"bordered\">{{ 'rule_builder.definition.cancel_and_back' | uicTranslate }}</ui-button>\n <ui-button (click)=\"formWrapper.submit()\" icon=\"ri-check-line\" color=\"black\">{{ 'rule_builder.definition.create_and_select' | uicTranslate }}</ui-button>\n </div>\n} @else {\n <div class=\"condition-searcher\">\n <ui-input>\n <input [(ngModel)]=\"searchTerm\" (ngModelChange)=\"onSearchTermChange()\" [placeholder]=\"'rule_builder.definition.search_placeholder' | uicTranslate\" type=\"text\">\n </ui-input>\n <ui-button (click)=\"newRule = true\" color=\"black\">{{ 'rule_builder.definition.new_rule' | uicTranslate }}</ui-button>\n </div>\n\n @if (paginatedConditions.length > 0) {\n @for (condition of paginatedConditions; track $index) {\n <div class=\"condition\" [class.condition-selected]=\"isSelected(condition)\">\n <i class=\"ri-align-item-horizontal-center-line\"></i>\n <div style=\"flex: 1 1;\">\n <div class=\"condition-title\"><span [innerHTML]=\"highlightSearch(condition.description)\"></span></div>\n @if (customNamesEnabled) {\n <div class=\"condition-body\">\n <span class=\"condition-field\" [innerHTML]=\"highlightSearch(condition.fieldName)\"></span>\n <span class=\"condition-operator\" [innerHTML]=\"highlightSearch(condition.operatorName)\"></span>\n <span class=\"condition-value\" [innerHTML]=\"highlightSearch(condition.value)\"></span>\n </div>\n }\n </div>\n @if (!isSelected(condition)) {\n <ui-button (click)=\"select(condition)\" color=\"primary\" size=\"s\" type=\"bordered\">{{ 'common.select' | uicTranslate }}</ui-button>\n }\n </div>\n }\n } @else {\n <div class=\"condition\">\n <div class=\"condition-emptytext\">\n {{ 'rule_builder.definition.no_results' | uicTranslate }}\n </div>\n </div>\n }\n\n <div class=\"condition-pagination\">\n <ui-button [disabled]=\"!canGoToPreviousPage\" (click)=\"goToPreviousPage()\" color=\"black\" size=\"s\" type=\"bordered\">{{ 'rule_builder.definition.previous' | uicTranslate }}</ui-button>\n <div><b>{{ currentPage }}</b> / {{ totalPages }}</div>\n <ui-button [disabled]=\"!canGoToNextPage\" (click)=\"goToNextPage()\" color=\"black\" size=\"s\" type=\"bordered\">{{ 'rule_builder.definition.next' | uicTranslate }}</ui-button>\n </div>\n}\n", styles: [".condition{border:solid 1px var(--grey-300);border-radius:10px;background-color:var(--grey-50);padding:6px;margin-bottom:4px;display:flex;align-items:center;gap:10px}.condition-emptytext{font-size:12px;text-align:center;color:var(--grey-400);padding:10px;width:100%}.condition i{color:var(--blue-600)}.condition-selected{border-color:var(--blue-500);background:linear-gradient(135deg,var(--blue-50) 0%,#eef6ff 100%);box-shadow:inset 0 0 0 1px #2563eb1f}.condition-selected .condition-title{color:var(--blue-800)}.condition-selected .condition-body,.condition-selected i{color:var(--blue-700)}.condition-title{font-size:14px;font-weight:500;line-height:16px}.condition-body{color:var(--grey-500);display:flex;gap:5px;font-size:12px}.condition-searcher{display:flex;gap:25px;margin-bottom:10px}.condition-pagination{margin-top:15px;display:flex;font-size:14px;align-items:center;justify-content:space-between}.condition-btns{padding-top:10px;border-top:solid 1px var(--grey-200);display:flex;justify-content:space-between}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: UicFormWrapperComponent, selector: "ui-form-wrapper", inputs: ["schema", "fields", "cols", "externalData", "loading", "disabled", "showButtons", "fillSelects", "initialValues", "fileUidResolverFn"], outputs: ["formSubmit", "formChange"] }, { kind: "component", type: UicInputComponent, selector: "ui-input", inputs: ["icon", "iconColor", "internalIcon", "internalIconColor", "size", "label", "error", "tip", "disabled", "loading"], outputs: ["clickButton"] }, { kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }] });
|
|
9683
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: RuleDefinirionComponent, isStandalone: true, selector: "lib-rule-definirion", ngImport: i0, template: "\n@if (newRule) {\n <ui-form-wrapper #formWrapper \n (formChange)=\"updateFormNewRule($event)\"\n (formSubmit)=\"createAndSelectRule($event)\" \n [initialValues]=\"initialValues\"\n [fields]=\"fields\" \n [cols]=\"2\"></ui-form-wrapper>\n <div class=\"condition-btns\">\n <ui-button icon=\"ri-arrow-left-line\" (click)=\"newRule = false\" color=\"black\" type=\"bordered\">{{ 'rule_builder.definition.cancel_and_back' | uicTranslate }}</ui-button>\n <ui-button (click)=\"formWrapper.submit()\" icon=\"ri-check-line\" color=\"black\">{{ 'rule_builder.definition.create_and_select' | uicTranslate }}</ui-button>\n </div>\n} @else {\n <div class=\"condition-searcher\">\n <ui-input>\n <input [(ngModel)]=\"searchTerm\" (ngModelChange)=\"onSearchTermChange()\" [placeholder]=\"'rule_builder.definition.search_placeholder' | uicTranslate\" type=\"text\">\n </ui-input>\n <ui-button (click)=\"newRule = true\" color=\"black\">{{ 'rule_builder.definition.new_rule' | uicTranslate }}</ui-button>\n </div>\n\n @if (paginatedConditions.length > 0) {\n @for (condition of paginatedConditions; track $index) {\n <div class=\"condition\" [class.condition-selected]=\"isSelected(condition)\">\n <i class=\"ri-align-item-horizontal-center-line\"></i>\n <div style=\"flex: 1 1;\">\n <div class=\"condition-title\"><span [innerHTML]=\"highlightSearch(condition.description)\"></span></div>\n @if (customNamesEnabled) {\n <div class=\"condition-body\">\n <span class=\"condition-field\" [innerHTML]=\"highlightSearch(condition.fieldName)\"></span>\n <span class=\"condition-operator\" [innerHTML]=\"highlightSearch(condition.operatorName)\"></span>\n <span class=\"condition-value\" [innerHTML]=\"highlightSearch(condition.value)\"></span>\n </div>\n }\n </div>\n @if (!isSelected(condition)) {\n <ui-button (click)=\"select(condition)\" color=\"primary\" size=\"s\" type=\"bordered\">{{ 'common.select' | uicTranslate }}</ui-button>\n }\n </div>\n }\n } @else {\n <div class=\"condition\">\n <div class=\"condition-emptytext\">\n {{ 'rule_builder.definition.no_results' | uicTranslate }}\n </div>\n </div>\n }\n\n <div class=\"condition-pagination\">\n <ui-button [disabled]=\"!canGoToPreviousPage\" (click)=\"goToPreviousPage()\" color=\"black\" size=\"s\" type=\"bordered\">{{ 'rule_builder.definition.previous' | uicTranslate }}</ui-button>\n <div><b>{{ currentPage }}</b> / {{ totalPages }}</div>\n <ui-button [disabled]=\"!canGoToNextPage\" (click)=\"goToNextPage()\" color=\"black\" size=\"s\" type=\"bordered\">{{ 'rule_builder.definition.next' | uicTranslate }}</ui-button>\n </div>\n}\n", styles: [".condition{border:solid 1px var(--grey-300);border-radius:10px;background-color:var(--grey-50);padding:6px;margin-bottom:4px;display:flex;align-items:center;gap:10px}.condition-emptytext{font-size:12px;text-align:center;color:var(--grey-400);padding:10px;width:100%}.condition i{color:var(--blue-600)}.condition-selected{border-color:var(--blue-500);background:linear-gradient(135deg,var(--blue-50) 0%,#eef6ff 100%);box-shadow:inset 0 0 0 1px #2563eb1f}.condition-selected .condition-title{color:var(--blue-800)}.condition-selected .condition-body,.condition-selected i{color:var(--blue-700)}.condition-title{font-size:14px;font-weight:500;line-height:16px}.condition-body{color:var(--grey-500);display:flex;gap:5px;font-size:12px}.condition-searcher{display:flex;gap:25px;margin-bottom:10px}.condition-pagination{margin-top:15px;display:flex;font-size:14px;align-items:center;justify-content:space-between}.condition-btns{padding-top:10px;border-top:solid 1px var(--grey-200);display:flex;justify-content:space-between}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: UicFormWrapperComponent, selector: "ui-form-wrapper", inputs: ["schema", "fields", "cols", "externalData", "selectOptionsResolver", "loading", "disabled", "showButtons", "fillSelects", "initialValues", "focusFieldName", "focusFieldTrigger", "fileUidResolverFn"], outputs: ["formSubmit", "formChange", "optionsSourceError"] }, { kind: "component", type: UicInputComponent, selector: "ui-input", inputs: ["icon", "iconColor", "internalIcon", "internalIconColor", "size", "label", "error", "tip", "disabled", "loading"], outputs: ["clickButton"] }, { kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }] });
|
|
9220
9684
|
}
|
|
9221
9685
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: RuleDefinirionComponent, decorators: [{
|
|
9222
9686
|
type: Component,
|