ui-core-abv 0.6.38 → 0.6.42

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.
@@ -307,21 +307,21 @@ const DICTIONARY_EN = {
307
307
  column_name_must_be_unique: 'Column name must be unique',
308
308
  },
309
309
  rule_builder: {
310
- title: 'Condition',
311
- add_rule: 'Rule',
312
- add_rule_tip: 'Add rule',
310
+ title: 'Rule',
311
+ add_rule: 'Condition',
312
+ add_rule_tip: 'Add condition',
313
313
  add_group: 'Group',
314
314
  add_group_tip: 'Add group',
315
315
  reset: 'Reset',
316
316
  reset_tip: 'Discard unsaved changes',
317
- save: 'Save',
317
+ save: 'Save rule',
318
318
  save_tip: 'Save built rule',
319
- delete_rule_tip: 'Delete rule',
319
+ delete_rule_tip: 'Delete condition',
320
320
  delete_group_tip: 'Delete group',
321
321
  toggle_operator_tip: 'Click to change operator',
322
- no_rules: 'No rules defined',
323
- rules_management: 'Select rule',
324
- edit: 'Edit',
322
+ no_rules: 'No conditions added',
323
+ rules_management: 'Select condition',
324
+ edit: 'Edit rule',
325
325
  edit_tip: 'Edit rule',
326
326
  edit_condition_tip: 'Click to edit condition',
327
327
  select_condition: '- select condition -',
@@ -334,9 +334,9 @@ const DICTIONARY_EN = {
334
334
  },
335
335
  definition: {
336
336
  cancel_and_back: 'Cancel and go back',
337
- create_and_select: 'Create and select',
337
+ create_and_select: 'Create and select condition',
338
338
  search_placeholder: 'Search condition',
339
- new_rule: 'New rule',
339
+ new_rule: 'New condition',
340
340
  no_results: 'No conditions found',
341
341
  previous: 'Previous',
342
342
  next: 'Next',
@@ -594,20 +594,20 @@ const DICTIONARY_ES = {
594
594
  column_name_must_be_unique: 'El nombre de la columna debe ser único',
595
595
  },
596
596
  rule_builder: {
597
- title: 'Condición',
598
- add_rule: 'Regla',
599
- add_rule_tip: 'Agregar regla',
597
+ title: 'Regla',
598
+ add_rule: 'Condición',
599
+ add_rule_tip: 'Agregar condición',
600
600
  add_group: 'Grupo',
601
601
  add_group_tip: 'Agregar grupo',
602
- reset: 'Reiniciar',
602
+ reset: 'Descartar',
603
603
  reset_tip: 'Descartar cambios no guardados',
604
604
  save: 'Guardar regla',
605
605
  save_tip: 'Guardar regla construida',
606
- delete_rule_tip: 'Eliminar regla',
606
+ delete_rule_tip: 'Eliminar condición',
607
607
  delete_group_tip: 'Eliminar grupo',
608
608
  toggle_operator_tip: 'Click para cambiar de operador',
609
- no_rules: 'No hay reglas definidas',
610
- rules_management: 'Seleccionar reglas',
609
+ no_rules: 'No hay condiciones agregadas',
610
+ rules_management: 'Seleccionar condición',
611
611
  edit: 'Editar regla',
612
612
  edit_tip: 'Editar regla',
613
613
  edit_condition_tip: 'Click para editar la condición',
@@ -621,9 +621,9 @@ const DICTIONARY_ES = {
621
621
  },
622
622
  definition: {
623
623
  cancel_and_back: 'Cancelar y volver',
624
- create_and_select: 'Crear y seleccionar',
624
+ create_and_select: 'Crear y seleccionar condición',
625
625
  search_placeholder: 'Buscar condición',
626
- new_rule: 'Nueva regla',
626
+ new_rule: 'Nueva condición',
627
627
  no_results: 'No se encontraron condiciones',
628
628
  previous: 'Anterior',
629
629
  next: 'Siguiente',
@@ -8623,6 +8623,7 @@ class RuleDefinirionComponent {
8623
8623
  newRule = false;
8624
8624
  fields;
8625
8625
  conditions = [];
8626
+ selectedConditionReference = null;
8626
8627
  searchTerm = '';
8627
8628
  currentPage = 1;
8628
8629
  pageSize = 5;
@@ -8632,6 +8633,9 @@ class RuleDefinirionComponent {
8632
8633
  constructor(data) {
8633
8634
  this.data = data;
8634
8635
  this.conditions = data.conditions;
8636
+ this.selectedConditionReference = data.selectedConditionReference == null
8637
+ ? null
8638
+ : String(data.selectedConditionReference);
8635
8639
  this.fields = this.buildFields();
8636
8640
  this.languageSubscription = this.translate.language$.subscribe(() => {
8637
8641
  this.fields = this.buildFields();
@@ -8642,15 +8646,19 @@ class RuleDefinirionComponent {
8642
8646
  }
8643
8647
  get filteredConditions() {
8644
8648
  const normalizedSearch = this.normalizeText(this.searchTerm);
8645
- if (!normalizedSearch) {
8646
- return this.conditions;
8647
- }
8648
- return this.conditions.filter(condition => this.normalizeText(condition.description).includes(normalizedSearch) ||
8649
- this.normalizeText(condition.fieldName).includes(normalizedSearch) ||
8650
- this.normalizeText(condition.fieldCode).includes(normalizedSearch) ||
8651
- this.normalizeText(condition.operatorName).includes(normalizedSearch) ||
8652
- this.normalizeText(condition.operatorCode).includes(normalizedSearch) ||
8653
- this.normalizeText(condition.value).includes(normalizedSearch));
8649
+ const conditions = !normalizedSearch
8650
+ ? this.conditions
8651
+ : this.conditions.filter(condition => this.normalizeText(condition.description).includes(normalizedSearch) ||
8652
+ this.normalizeText(condition.fieldName).includes(normalizedSearch) ||
8653
+ this.normalizeText(condition.fieldCode).includes(normalizedSearch) ||
8654
+ this.normalizeText(condition.operatorName).includes(normalizedSearch) ||
8655
+ this.normalizeText(condition.operatorCode).includes(normalizedSearch) ||
8656
+ this.normalizeText(condition.value).includes(normalizedSearch));
8657
+ return [...conditions].sort((left, right) => {
8658
+ const leftSelected = this.isSelected(left) ? 1 : 0;
8659
+ const rightSelected = this.isSelected(right) ? 1 : 0;
8660
+ return rightSelected - leftSelected;
8661
+ });
8654
8662
  }
8655
8663
  get paginatedConditions() {
8656
8664
  const start = (this.currentPage - 1) * this.pageSize;
@@ -8699,6 +8707,9 @@ class RuleDefinirionComponent {
8699
8707
  select(condition) {
8700
8708
  this.ref.closeFloating(condition);
8701
8709
  }
8710
+ isSelected(condition) {
8711
+ return this.selectedConditionReference === String(this.getConditionReference(condition));
8712
+ }
8702
8713
  highlightSearch(value) {
8703
8714
  const text = String(value ?? '');
8704
8715
  const query = this.searchTerm.trim();
@@ -8755,8 +8766,11 @@ class RuleDefinirionComponent {
8755
8766
  .replace(/"/g, '"')
8756
8767
  .replace(/'/g, ''');
8757
8768
  }
8769
+ getConditionReference(condition) {
8770
+ return condition.id === 0 ? (condition.temporalId ?? '') : condition.id;
8771
+ }
8758
8772
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: RuleDefinirionComponent, deps: [{ token: MODAL_DATA }], target: i0.ɵɵFactoryTarget.Component });
8759
- 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 (formSubmit)=\"createAndSelectRule($event)\" [fields]=\"fields\" [cols]=\"3\"></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\">\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 <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 </div>\n <ui-button (click)=\"select(condition)\" color=\"primary\" size=\"s\" type=\"bordered\">{{ 'common.select' | uicTranslate }}</ui-button>\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-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"], 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" }] });
8773
+ 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 (formSubmit)=\"createAndSelectRule($event)\" [fields]=\"fields\" [cols]=\"3\"></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 <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 </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"], 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" }] });
8760
8774
  }
8761
8775
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: RuleDefinirionComponent, decorators: [{
8762
8776
  type: Component,
@@ -8766,14 +8780,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
8766
8780
  UicInputComponent,
8767
8781
  UicButtonComponent,
8768
8782
  UicTranslatePipe
8769
- ], template: "\n@if (newRule) {\n <ui-form-wrapper #formWrapper (formSubmit)=\"createAndSelectRule($event)\" [fields]=\"fields\" [cols]=\"3\"></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\">\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 <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 </div>\n <ui-button (click)=\"select(condition)\" color=\"primary\" size=\"s\" type=\"bordered\">{{ 'common.select' | uicTranslate }}</ui-button>\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-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"] }]
8783
+ ], template: "\n@if (newRule) {\n <ui-form-wrapper #formWrapper (formSubmit)=\"createAndSelectRule($event)\" [fields]=\"fields\" [cols]=\"3\"></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 <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 </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"] }]
8770
8784
  }], ctorParameters: () => [{ type: undefined, decorators: [{
8771
8785
  type: Inject,
8772
8786
  args: [MODAL_DATA]
8773
8787
  }] }] });
8774
8788
 
8775
8789
  class UicRuleBuilderComponent {
8776
- conditions = [
8790
+ conditionsInitialized = false;
8791
+ emitConditionsOnInit = false;
8792
+ emitRuleDefinitionOnInit = false;
8793
+ conditionsEmitScheduled = false;
8794
+ ruleDefinitionEmitScheduled = false;
8795
+ _conditions = [
8777
8796
  {
8778
8797
  id: 1,
8779
8798
  description: 'Mayores de edad',
@@ -8838,25 +8857,63 @@ class UicRuleBuilderComponent {
8838
8857
  value: '18',
8839
8858
  }
8840
8859
  ];
8841
- conditionOperators = [
8842
- { id: 'equal', text: 'Igual que' },
8843
- { id: 'not_equal', text: 'Distinto de' },
8844
- { id: 'greater_than', text: 'Mayor que' },
8845
- { id: 'less_than', text: 'Menor que' },
8846
- ];
8847
- conditionFields = [
8848
- { id: 'name', text: 'Nombre' },
8849
- { id: 'age', text: 'Edad' },
8850
- { id: 'country', text: 'Pais' },
8851
- ];
8852
- availableConditions = [];
8860
+ set conditions(value) {
8861
+ this._conditions = Array.isArray(value) ? value.map(condition => ({ ...condition })) : [];
8862
+ const conditionsNormalized = this.refreshAvailableConditions();
8863
+ const syncResult = this.syncConditionsWithPersistedConditions();
8864
+ this.syncNextTemporalConditionId();
8865
+ if (this.conditionsInitialized && (conditionsNormalized || syncResult.conditionsCleaned)) {
8866
+ this.scheduleConditionsStateEmit();
8867
+ }
8868
+ if (!this.conditionsInitialized && (conditionsNormalized || syncResult.conditionsCleaned)) {
8869
+ this.emitConditionsOnInit = true;
8870
+ }
8871
+ if (this.conditionsInitialized && syncResult.referencesUpdated) {
8872
+ this.scheduleRuleDefinitionStateEmit();
8873
+ }
8874
+ if (!this.conditionsInitialized && syncResult.referencesUpdated) {
8875
+ this.emitRuleDefinitionOnInit = true;
8876
+ }
8877
+ this.conditionsInitialized = true;
8878
+ }
8879
+ get conditions() {
8880
+ return this._conditions;
8881
+ }
8882
+ conditionOperators = [];
8883
+ conditionFields = [];
8853
8884
  conditionLabels = {};
8854
8885
  editing = false;
8855
8886
  nextTemporalConditionId = 1;
8887
+ externalRuleDefinition = this.createEmptyRuleBuilderValue();
8856
8888
  title = '';
8857
- initValue = '';
8889
+ set ruleDefinition(value) {
8890
+ const normalizedValue = this.normalizeRuleBuilderValue(value);
8891
+ if (this.areRuleBuilderValuesEqual(normalizedValue, this.externalRuleDefinition)) {
8892
+ return;
8893
+ }
8894
+ this.externalRuleDefinition = normalizedValue;
8895
+ this.editorRules = this.getRulesFromDefinition(normalizedValue.definition);
8896
+ const syncResult = this.syncConditionsWithPersistedConditions();
8897
+ this.syncNextTemporalConditionId();
8898
+ if (this.conditionsInitialized && syncResult.conditionsCleaned) {
8899
+ this.scheduleConditionsStateEmit();
8900
+ }
8901
+ if (this.conditionsInitialized && syncResult.referencesUpdated) {
8902
+ this.scheduleRuleDefinitionStateEmit();
8903
+ }
8904
+ if (!this.conditionsInitialized && syncResult.conditionsCleaned) {
8905
+ this.emitConditionsOnInit = true;
8906
+ }
8907
+ if (!this.conditionsInitialized && syncResult.referencesUpdated) {
8908
+ this.emitRuleDefinitionOnInit = true;
8909
+ }
8910
+ }
8911
+ get ruleDefinition() {
8912
+ return this.externalRuleDefinition;
8913
+ }
8858
8914
  ruleDefinitionChange = new EventEmitter();
8859
- ruleDefinition = [];
8915
+ conditionsChange = new EventEmitter();
8916
+ editorRules = [];
8860
8917
  translate = inject(UicTranslateService);
8861
8918
  modal = inject(UicModalService);
8862
8919
  tinyAlert = inject(UicTinyAlertService);
@@ -8864,15 +8921,33 @@ class UicRuleBuilderComponent {
8864
8921
  return this.title || this.translate.translate('rule_builder.title');
8865
8922
  }
8866
8923
  ngOnInit() {
8867
- this.refreshAvailableConditions();
8868
- this.ruleDefinition = this.getRulesFromInitialValue();
8924
+ if (!this.conditionsInitialized) {
8925
+ this.emitConditionsOnInit = this.refreshAvailableConditions();
8926
+ this.conditionsInitialized = true;
8927
+ }
8928
+ this.editorRules = this.getRulesFromDefinition(this.ruleDefinition.definition);
8929
+ const syncResult = this.syncConditionsWithPersistedConditions();
8869
8930
  this.syncNextTemporalConditionId();
8931
+ if (syncResult.conditionsCleaned) {
8932
+ this.emitConditionsOnInit = true;
8933
+ }
8934
+ if (syncResult.referencesUpdated) {
8935
+ this.emitRuleDefinitionOnInit = true;
8936
+ }
8937
+ if (this.emitConditionsOnInit) {
8938
+ this.scheduleConditionsStateEmit();
8939
+ this.emitConditionsOnInit = false;
8940
+ }
8941
+ if (this.emitRuleDefinitionOnInit) {
8942
+ this.scheduleRuleDefinitionStateEmit();
8943
+ this.emitRuleDefinitionOnInit = false;
8944
+ }
8870
8945
  }
8871
- addRule(rules = this.ruleDefinition) {
8946
+ addRule(rules = this.editorRules) {
8872
8947
  this.appendExpression(rules, this.createConditionRule());
8873
8948
  this.syncRuleDefinition();
8874
8949
  }
8875
- addGroup(rules = this.ruleDefinition) {
8950
+ addGroup(rules = this.editorRules) {
8876
8951
  this.appendExpression(rules, this.createGroupRule());
8877
8952
  this.syncRuleDefinition();
8878
8953
  }
@@ -8902,6 +8977,7 @@ class UicRuleBuilderComponent {
8902
8977
  conditions: this.conditions,
8903
8978
  conditionOperators: this.conditionOperators,
8904
8979
  conditionFields: this.conditionFields,
8980
+ selectedConditionReference: targetRule.value ?? null,
8905
8981
  },
8906
8982
  size: 'medium'
8907
8983
  }).afterClosed().subscribe(r => {
@@ -8914,29 +8990,38 @@ class UicRuleBuilderComponent {
8914
8990
  });
8915
8991
  }
8916
8992
  print() {
8917
- const normalizedRules = this.normalizeRules(this.cloneRules(this.ruleDefinition));
8993
+ const normalizedRules = this.normalizeRules(this.cloneRules(this.editorRules));
8918
8994
  if (!this.hasOperators(normalizedRules)) {
8919
8995
  this.tinyAlert.warning('rule_builder.validation.single_condition_not_allowed');
8920
8996
  return;
8921
8997
  }
8922
- this.ruleDefinition = normalizedRules;
8923
- this.markRulesAsSaved(this.ruleDefinition);
8924
- const output = this.buildRuleOutput();
8925
- this.initValue = output.definition;
8926
- this.ruleDefinitionChange.emit(output);
8998
+ this.editorRules = normalizedRules;
8999
+ this.markRulesAsSaved(this.editorRules);
9000
+ this.emitRuleDefinitionState();
8927
9001
  this.editing = false;
8928
9002
  }
8929
9003
  reset() {
8930
- this.ruleDefinition = this.getRulesFromInitialValue();
9004
+ this.editorRules = this.getRulesFromDefinition(this.ruleDefinition.definition);
8931
9005
  this.editing = false;
8932
9006
  }
8933
9007
  getOutput() {
8934
- this.ruleDefinition = this.normalizeRules(this.cloneRules(this.ruleDefinition));
9008
+ this.editorRules = this.normalizeRules(this.cloneRules(this.editorRules));
8935
9009
  return this.buildRuleOutput();
8936
9010
  }
8937
9011
  getConditionLabel(value) {
8938
9012
  return this.resolveConditionLabel(value);
8939
9013
  }
9014
+ getConditionDetailTip(value) {
9015
+ const matchedCondition = this.conditions.find(condition => String(this.getConditionReference(condition)) === String(value));
9016
+ if (!matchedCondition) {
9017
+ return '';
9018
+ }
9019
+ return [
9020
+ matchedCondition.fieldName,
9021
+ matchedCondition.operatorName,
9022
+ matchedCondition.value
9023
+ ].filter(Boolean).join(' ');
9024
+ }
8940
9025
  getOperatorLabel(value) {
8941
9026
  const normalizedValue = value === 'OR' ? 'OR' : 'AND';
8942
9027
  const translationKey = normalizedValue === 'AND'
@@ -8954,12 +9039,12 @@ class UicRuleBuilderComponent {
8954
9039
  rules.push(expression);
8955
9040
  }
8956
9041
  syncRuleDefinition() {
8957
- this.ruleDefinition = this.normalizeRules(this.ruleDefinition, true);
9042
+ this.editorRules = this.normalizeRules(this.editorRules, true);
8958
9043
  }
8959
9044
  createConditionRule() {
8960
9045
  return {
8961
9046
  type: 'condition',
8962
- value: this.getNextConditionValue(),
9047
+ value: null,
8963
9048
  unsaved: true
8964
9049
  };
8965
9050
  }
@@ -8970,11 +9055,6 @@ class UicRuleBuilderComponent {
8970
9055
  unsaved: true
8971
9056
  };
8972
9057
  }
8973
- getNextConditionValue() {
8974
- const usedConditions = new Set(this.collectConditionValues(this.ruleDefinition));
8975
- const nextOption = this.availableConditions.find(option => option.id != null && !usedConditions.has(String(option.id)));
8976
- return nextOption?.id ?? this.availableConditions[0]?.id ?? null;
8977
- }
8978
9058
  collectConditionValues(rules) {
8979
9059
  return rules.flatMap(rule => {
8980
9060
  if (rule.type === 'condition' && rule.value) {
@@ -9075,9 +9155,9 @@ class UicRuleBuilderComponent {
9075
9155
  const { rules } = this.parseTokens(tokens);
9076
9156
  return this.normalizeRules(rules);
9077
9157
  }
9078
- getRulesFromInitialValue() {
9079
- const rules = this.initValue.trim()
9080
- ? this.parseExpression(this.initValue)
9158
+ getRulesFromDefinition(definition) {
9159
+ const rules = definition.trim()
9160
+ ? this.parseExpression(definition)
9081
9161
  : this.normalizeRules([]);
9082
9162
  this.markRulesAsSaved(rules);
9083
9163
  return rules;
@@ -9139,17 +9219,18 @@ class UicRuleBuilderComponent {
9139
9219
  const conditionReference = this.getConditionReference(normalizedCondition);
9140
9220
  const existingIndex = this.conditions.findIndex(item => String(this.getConditionReference(item)) === String(conditionReference));
9141
9221
  if (existingIndex >= 0) {
9142
- this.conditions[existingIndex] = normalizedCondition;
9222
+ this._conditions[existingIndex] = normalizedCondition;
9143
9223
  }
9144
9224
  else {
9145
- this.conditions = [...this.conditions, normalizedCondition];
9225
+ this._conditions = [...this._conditions, normalizedCondition];
9146
9226
  }
9147
9227
  this.refreshAvailableConditions();
9228
+ this.scheduleConditionsStateEmit();
9148
9229
  return conditionReference;
9149
9230
  }
9150
9231
  buildRuleOutput() {
9151
- const definition = this.buildExpression(this.ruleDefinition);
9152
- const usedConditionReferences = new Set(this.collectConditionValues(this.ruleDefinition));
9232
+ const definition = this.buildExpression(this.editorRules);
9233
+ const usedConditionReferences = new Set(this.collectConditionValues(this.editorRules));
9153
9234
  const rulesToCreate = this.conditions
9154
9235
  .filter(condition => condition.id === 0 && !!condition.temporalId && usedConditionReferences.has(String(this.getConditionReference(condition))))
9155
9236
  .map(condition => ({
@@ -9164,24 +9245,111 @@ class UicRuleBuilderComponent {
9164
9245
  rulesToCreate
9165
9246
  };
9166
9247
  }
9248
+ emitRuleDefinitionState() {
9249
+ const output = this.buildRuleOutput();
9250
+ this.externalRuleDefinition = output;
9251
+ this.ruleDefinitionChange.emit(output);
9252
+ }
9253
+ emitConditionsState() {
9254
+ this.conditionsChange.emit(this._conditions.map(condition => ({ ...condition })));
9255
+ }
9256
+ scheduleRuleDefinitionStateEmit() {
9257
+ if (this.ruleDefinitionEmitScheduled) {
9258
+ return;
9259
+ }
9260
+ this.ruleDefinitionEmitScheduled = true;
9261
+ queueMicrotask(() => {
9262
+ this.ruleDefinitionEmitScheduled = false;
9263
+ this.emitRuleDefinitionState();
9264
+ });
9265
+ }
9266
+ scheduleConditionsStateEmit() {
9267
+ if (this.conditionsEmitScheduled) {
9268
+ return;
9269
+ }
9270
+ this.conditionsEmitScheduled = true;
9271
+ queueMicrotask(() => {
9272
+ this.conditionsEmitScheduled = false;
9273
+ this.emitConditionsState();
9274
+ });
9275
+ }
9276
+ normalizeRuleBuilderValue(value) {
9277
+ if (!value) {
9278
+ return this.createEmptyRuleBuilderValue();
9279
+ }
9280
+ return {
9281
+ definition: String(value.definition ?? ''),
9282
+ rulesToCreate: Array.isArray(value.rulesToCreate)
9283
+ ? value.rulesToCreate.map(rule => ({ ...rule }))
9284
+ : []
9285
+ };
9286
+ }
9287
+ createEmptyRuleBuilderValue() {
9288
+ return {
9289
+ definition: '',
9290
+ rulesToCreate: []
9291
+ };
9292
+ }
9293
+ areRuleBuilderValuesEqual(left, right) {
9294
+ return left.definition === right.definition
9295
+ && JSON.stringify(left.rulesToCreate) === JSON.stringify(right.rulesToCreate);
9296
+ }
9167
9297
  refreshAvailableConditions() {
9168
- this.conditions = this.conditions.map(condition => {
9298
+ let changed = false;
9299
+ this._conditions = this._conditions.map(condition => {
9169
9300
  if (condition.id !== 0 || condition.temporalId) {
9170
9301
  return condition;
9171
9302
  }
9303
+ changed = true;
9172
9304
  return {
9173
9305
  ...condition,
9174
9306
  temporalId: this.getNextTemporalConditionId()
9175
9307
  };
9176
9308
  });
9177
- this.availableConditions = this.conditions.map(condition => ({
9178
- id: this.getConditionReference(condition),
9179
- text: condition.description
9180
- }));
9181
- this.conditionLabels = this.conditions.reduce((labels, condition) => {
9309
+ this.conditionLabels = this._conditions.reduce((labels, condition) => {
9182
9310
  labels[String(this.getConditionReference(condition))] = condition.description;
9183
9311
  return labels;
9184
9312
  }, {});
9313
+ return changed;
9314
+ }
9315
+ syncConditionsWithPersistedConditions() {
9316
+ const persistedConditionsByTemporalId = new Map(this._conditions
9317
+ .filter(condition => condition.id !== 0 && !!condition.temporalId)
9318
+ .map(condition => [String(condition.temporalId), condition]));
9319
+ if (persistedConditionsByTemporalId.size === 0) {
9320
+ return {
9321
+ referencesUpdated: false,
9322
+ conditionsCleaned: false
9323
+ };
9324
+ }
9325
+ const referencesUpdated = this.replaceConditionReferences(this.editorRules, persistedConditionsByTemporalId);
9326
+ const previousLength = this._conditions.length;
9327
+ this._conditions = this._conditions.filter(condition => {
9328
+ return condition.id !== 0
9329
+ || !condition.temporalId
9330
+ || !persistedConditionsByTemporalId.has(String(condition.temporalId));
9331
+ });
9332
+ return {
9333
+ referencesUpdated,
9334
+ conditionsCleaned: previousLength !== this._conditions.length
9335
+ };
9336
+ }
9337
+ replaceConditionReferences(rules, persistedConditionsByTemporalId) {
9338
+ let updated = false;
9339
+ for (const rule of rules) {
9340
+ if (rule.type === 'condition' && typeof rule.value === 'string') {
9341
+ const persistedCondition = persistedConditionsByTemporalId.get(rule.value);
9342
+ if (persistedCondition) {
9343
+ rule.value = persistedCondition.id;
9344
+ rule.unsaved = false;
9345
+ updated = true;
9346
+ }
9347
+ }
9348
+ if (rule.type === 'group' && rule.rules) {
9349
+ updated = this.replaceConditionReferences(rule.rules, persistedConditionsByTemporalId) || updated;
9350
+ }
9351
+ }
9352
+ return updated;
9185
9353
  }
9186
9354
  getConditionReference(condition) {
9187
9355
  return condition.id === 0 ? (condition.temporalId ?? '') : condition.id;
@@ -9193,8 +9361,10 @@ class UicRuleBuilderComponent {
9193
9361
  }
9194
9362
  syncNextTemporalConditionId() {
9195
9363
  const references = [
9196
- ...this.conditions.map(condition => String(this.getConditionReference(condition))),
9197
- ...this.collectConditionValues(this.ruleDefinition)
9364
+ ...this.conditions
9365
+ .flatMap(condition => [String(this.getConditionReference(condition)), String(condition.temporalId ?? '')])
9366
+ .filter(reference => reference !== ''),
9367
+ ...this.collectConditionValues(this.editorRules)
9198
9368
  ];
9199
9369
  const nextId = references.reduce((maxId, reference) => {
9200
9370
  const match = reference.match(/^temp_(\d+)$/);
@@ -9206,18 +9376,17 @@ class UicRuleBuilderComponent {
9206
9376
  this.nextTemporalConditionId = nextId + 1;
9207
9377
  }
9208
9378
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicRuleBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9209
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: UicRuleBuilderComponent, isStandalone: true, selector: "ui-rule-builder", inputs: { conditions: "conditions", conditionOperators: "conditionOperators", conditionFields: "conditionFields", title: "title", initValue: "initValue" }, outputs: { ruleDefinitionChange: "ruleDefinitionChange" }, ngImport: i0, template: "<div class=\"rule-tools\">\r\n <h3>\r\n {{resolvedTitle}}\r\n </h3>\r\n @if (editing) {\r\n <ui-button [tip]=\"'rule_builder.add_rule_tip' | uicTranslate\" (click)=\"addRule()\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_rule' | uicTranslate}}</ui-button>\r\n <ui-button [tip]=\"'rule_builder.add_group_tip' | uicTranslate\" (click)=\"addGroup()\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_group' | uicTranslate}}</ui-button>\r\n }@else {\r\n <ui-button [tip]=\"'rule_builder.edit_tip' | uicTranslate\" (click)=\"editing=true\" size=\"s\" type=\"bordered\" icon=\"ri-edit-line\">{{'rule_builder.edit' | uicTranslate}}</ui-button>\r\n }\r\n</div>\r\n<div class=\"rule-container\" [class.focused-box]=\"editing\">\r\n <div class=\"rule-container-workspace\">\r\n @if (editing) {\r\n <ng-container\r\n *ngTemplateOutlet=\"rulesTemplate; context: { rules: ruleDefinition, isGroup: false }\">\r\n </ng-container>\r\n } @else {\r\n <ng-container *ngTemplateOutlet=\"readOnlyTemplate\"></ng-container>\r\n }\r\n @if (ruleDefinition.length==0) {\r\n <div class=\"empty-rule-msg\">{{'rule_builder.no_rules' | uicTranslate}}</div>\r\n }\r\n </div>\r\n @if (editing) {\r\n <div class=\"rule-btns\">\r\n <ui-button color=\"black\" type=\"bordered\" [tip]=\"'rule_builder.reset_tip' | uicTranslate\" (click)=\"reset()\" >{{'rule_builder.reset' | uicTranslate}}</ui-button>\r\n <ui-button color=\"black\" [tip]=\"'rule_builder.save_tip' | uicTranslate\" (click)=\"print()\">{{'rule_builder.save' | uicTranslate}}</ui-button>\r\n </div>\r\n }\r\n</div>\r\n\r\n<ng-template #rulesTemplate let-rules=\"rules\" let-isGroup=\"isGroup\">\r\n @for (rule of rules; track $index; let i = $index) {\r\n @if (rule.type === 'condition') {\r\n <div class=\"rule-condition\" [class.rule-unsaved]=\"rule.unsaved\">\r\n <div [tip]=\"'rule_builder.edit_condition_tip' | uicTranslate\" (click)=\"manageRules(rules, i)\">\r\n <div class=\"condition-box\">{{ rule.value == null || rule.value === '' ? ('rule_builder.select_condition' | uicTranslate) : (conditionLabels[rule.value] || rule.value) }}</div>\r\n </div>\r\n <ui-button [tip]=\"'rule_builder.delete_rule_tip' | uicTranslate\" (click)=\"removeRule(rules, i)\" [iconOnly]=\"true\" size=\"s\" type=\"ghost\" icon=\"ri-delete-bin-line\" color=\"red\"></ui-button>\r\n </div>\r\n }\r\n @if (rule.type === 'operator') {\r\n <div [tip]=\"'rule_builder.toggle_operator_tip' | uicTranslate\"\r\n (click)=\"changeOperator(rules, i)\"\r\n class=\"rule-operator {{rule.value === 'AND' ? 'op-and' : 'op-or'}}\">\r\n {{ getOperatorLabel(rule.value) }}\r\n </div>\r\n }\r\n @if (rule.type === 'group') {\r\n <div class=\"rule-groups\" [class.rule-unsaved]=\"rule.unsaved\">\r\n <div class=\"rule-groups-tools\">\r\n <ui-button [tip]=\"'rule_builder.add_rule_tip' | uicTranslate\" (click)=\"addRule(rule.rules ?? [])\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_rule' | uicTranslate}}</ui-button>\r\n <ui-button [tip]=\"'rule_builder.add_group_tip' | uicTranslate\" (click)=\"addGroup(rule.rules ?? [])\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_group' | uicTranslate}}</ui-button>\r\n <ui-button [tip]=\"'rule_builder.delete_group_tip' | uicTranslate\" (click)=\"removeRule(rules, i)\" [iconOnly]=\"true\" size=\"s\" type=\"ghost\" icon=\"ri-delete-bin-line\" color=\"red\"></ui-button>\r\n </div>\r\n <div class=\"rule-groups-items\">\r\n <ng-container\r\n *ngTemplateOutlet=\"rulesTemplate; context: { rules: rule.rules ?? [], isGroup: true }\">\r\n </ng-container>\r\n </div>\r\n </div>\r\n }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #readOnlyTemplate>\r\n @if (ruleDefinition.length > 0) {\r\n <div class=\"rule-friendly-output\">\r\n <ng-container\r\n *ngTemplateOutlet=\"readOnlyRulesTemplate; context: { rules: ruleDefinition, isGroup: false }\">\r\n </ng-container>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #readOnlyRulesTemplate let-rules=\"rules\" let-isGroup=\"isGroup\">\r\n <div class=\"readonly\">\r\n @if (isGroup) {\r\n <div class=\"readonly-group\">(</div>\r\n }\r\n \r\n @for (rule of rules; track $index) {\r\n @if (rule.type === 'condition') {\r\n <div class=\"readonly-condition\">{{ getConditionLabel(rule.value) }}</div>\r\n }\r\n \r\n @if (rule.type === 'operator') {\r\n <div class=\"readonly-operator\">{{ getOperatorLabel(rule.value) }}</div>\r\n }\r\n \r\n @if (rule.type === 'group') {\r\n <div class=\"readonly-group\">\r\n <ng-container\r\n *ngTemplateOutlet=\"readOnlyRulesTemplate; context: { rules: rule.rules ?? [], isGroup: true }\">\r\n </ng-container>\r\n </div>\r\n }\r\n }\r\n \r\n @if (isGroup) {\r\n <div class=\"readonly-group\">)</div>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: [".rule-tools{display:flex;gap:5px;align-items:center;padding:5px;margin-bottom:5px;justify-content:flex-end}.rule-tools>h3{flex:1 1}.rule-container{padding:5px;border-top:solid 1px var(--grey-300)}.rule-container-workspace{display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:10px;margin-bottom:10px}.rule-groups{background-color:var(--grey-50);border:solid 1px var(--grey-300);overflow:hidden;border-radius:10px}.rule-groups-tools{display:flex;border-bottom:solid 1px var(--grey-300);background-color:var(--grey-200);gap:5px;padding:5px;justify-content:flex-end}.rule-groups-items{display:flex;padding:5px;align-items:center;gap:10px;flex-wrap:wrap}.rule-condition{padding:5px;border:solid 1px var(--grey-300);border-radius:10px;background-color:#fff;font-size:14px;display:flex;gap:5px;align-items:center}.rule-condition ui-select{min-width:100px}.rule-operator{padding:5px;border-radius:10px;font-size:13px;cursor:pointer;-webkit-user-select:none;user-select:none}.op-or{background-color:var(--red-100);color:var(--red-600)}.op-or:hover{background-color:var(--red-200)}.op-and{background-color:var(--green-100);color:var(--green-700)}.op-and:hover{background-color:var(--green-200)}.rule-btns{border-top:solid 1px var(--grey-300);display:flex;justify-content:flex-end;gap:10px;padding:5px;margin-top:5px}.empty-rule-msg{padding:10px;font-size:13px;text-align:center;width:100%;color:var(--grey-400)}.focused-box{border:solid 1px var(--primary-400);border-radius:10px;box-shadow:0 0 0 3px var(--secondary-alpha)}.rule-unsaved{border-color:var(--yellow-300)!important}.condition-box{font-size:14px;padding:5px 15px;color:var(--blue-700);border:solid 1px var(--blue-500);background-color:var(--blue-100);transition:background-color ease .2s;border-radius:10px;cursor:pointer}.condition-box:hover{background-color:var(--blue-200)}.readonly{display:flex;gap:5px;align-items:center}.readonly-condition{font-size:13px;background-color:var(--blue-100);padding:4px 8px;color:var(--blue-800);border-radius:5px;font-weight:400}.readonly-operator{font-size:12px;font-weight:500;color:var(--grey-500)}.readonly-group{font-weight:600;color:var(--red-500)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: UicToolTipDirective, selector: "[tip]", inputs: ["tip"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }] });
9379
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: UicRuleBuilderComponent, isStandalone: true, selector: "ui-rule-builder", inputs: { conditions: "conditions", conditionOperators: "conditionOperators", conditionFields: "conditionFields", title: "title", ruleDefinition: "ruleDefinition" }, outputs: { ruleDefinitionChange: "ruleDefinitionChange", conditionsChange: "conditionsChange" }, ngImport: i0, template: "\r\n<div class=\"rule-tools\">\r\n <h3>\r\n {{resolvedTitle}}\r\n </h3>\r\n @if (editing) {\r\n <ui-button [tip]=\"'rule_builder.add_rule_tip' | uicTranslate\" (click)=\"addRule()\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_rule' | uicTranslate}}</ui-button>\r\n <ui-button [tip]=\"'rule_builder.add_group_tip' | uicTranslate\" (click)=\"addGroup()\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_group' | uicTranslate}}</ui-button>\r\n }@else {\r\n <ui-button [tip]=\"'rule_builder.edit_tip' | uicTranslate\" (click)=\"editing=true\" size=\"s\" type=\"bordered\" icon=\"ri-edit-line\">{{'rule_builder.edit' | uicTranslate}}</ui-button>\r\n }\r\n</div>\r\n<div class=\"rule-container\" [class.focused-box]=\"editing\">\r\n <div class=\"rule-container-workspace\">\r\n @if (editing) {\r\n <ng-container\r\n *ngTemplateOutlet=\"rulesTemplate; context: { rules: editorRules, isGroup: false }\">\r\n </ng-container>\r\n } @else {\r\n <ng-container *ngTemplateOutlet=\"readOnlyTemplate\"></ng-container>\r\n }\r\n @if (editorRules.length==0) {\r\n <div class=\"empty-rule-msg\">{{'rule_builder.no_rules' | uicTranslate}}</div>\r\n }\r\n </div>\r\n @if (editing) {\r\n <div class=\"rule-btns\">\r\n <ui-button color=\"black\" type=\"bordered\" [tip]=\"'rule_builder.reset_tip' | uicTranslate\" (click)=\"reset()\" >{{'rule_builder.reset' | uicTranslate}}</ui-button>\r\n <ui-button color=\"black\" [tip]=\"'rule_builder.save_tip' | uicTranslate\" (click)=\"print()\">{{'rule_builder.save' | uicTranslate}}</ui-button>\r\n </div>\r\n }\r\n</div>\r\n\r\n<ng-template #rulesTemplate let-rules=\"rules\" let-isGroup=\"isGroup\">\r\n @for (rule of rules; track $index; let i = $index) {\r\n @if (rule.type === 'condition') {\r\n <div class=\"rule-condition\" [class.rule-unsaved]=\"rule.unsaved\">\r\n <div [tip]=\"'rule_builder.edit_condition_tip' | uicTranslate\" (click)=\"manageRules(rules, i)\">\r\n <div class=\"condition-box\" [class.condition-box-empty]=\"rule.value == null || rule.value === ''\">{{ rule.value == null || rule.value === '' ? ('rule_builder.select_condition' | uicTranslate) : (conditionLabels[rule.value] || rule.value) }}</div>\r\n </div>\r\n <ui-button [tip]=\"'rule_builder.delete_rule_tip' | uicTranslate\" (click)=\"removeRule(rules, i)\" [iconOnly]=\"true\" size=\"s\" type=\"ghost\" icon=\"ri-delete-bin-line\" color=\"red\"></ui-button>\r\n </div>\r\n }\r\n @if (rule.type === 'operator') {\r\n <div [tip]=\"'rule_builder.toggle_operator_tip' | uicTranslate\"\r\n (click)=\"changeOperator(rules, i)\"\r\n class=\"rule-operator {{rule.value === 'AND' ? 'op-and' : 'op-or'}}\">\r\n {{ getOperatorLabel(rule.value) }}\r\n </div>\r\n }\r\n @if (rule.type === 'group') {\r\n <div class=\"rule-groups\" [class.rule-unsaved]=\"rule.unsaved\">\r\n <div class=\"rule-groups-tools\">\r\n <ui-button [tip]=\"'rule_builder.add_rule_tip' | uicTranslate\" (click)=\"addRule(rule.rules ?? [])\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_rule' | uicTranslate}}</ui-button>\r\n <ui-button [tip]=\"'rule_builder.add_group_tip' | uicTranslate\" (click)=\"addGroup(rule.rules ?? [])\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_group' | uicTranslate}}</ui-button>\r\n <ui-button [tip]=\"'rule_builder.delete_group_tip' | uicTranslate\" (click)=\"removeRule(rules, i)\" [iconOnly]=\"true\" size=\"s\" type=\"ghost\" icon=\"ri-delete-bin-line\" color=\"red\"></ui-button>\r\n </div>\r\n <div class=\"rule-groups-items\">\r\n <ng-container\r\n *ngTemplateOutlet=\"rulesTemplate; context: { rules: rule.rules ?? [], isGroup: true }\">\r\n </ng-container>\r\n </div>\r\n </div>\r\n }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #readOnlyTemplate>\r\n @if (editorRules.length > 0) {\r\n <div class=\"rule-friendly-output\">\r\n <ng-container\r\n *ngTemplateOutlet=\"readOnlyRulesTemplate; context: { rules: editorRules, isGroup: false }\">\r\n </ng-container>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #readOnlyRulesTemplate let-rules=\"rules\" let-isGroup=\"isGroup\">\r\n <div class=\"readonly\">\r\n @if (isGroup) {\r\n <div class=\"readonly-group\">(</div>\r\n }\r\n \r\n @for (rule of rules; track $index) {\n @if (rule.type === 'condition') {\n <div class=\"readonly-condition\" [tip]=\"getConditionDetailTip(rule.value)\">{{ getConditionLabel(rule.value) }}</div>\n }\n \r\n @if (rule.type === 'operator') {\r\n <div class=\"readonly-operator\">{{ getOperatorLabel(rule.value) }}</div>\r\n }\r\n \r\n @if (rule.type === 'group') {\r\n <div class=\"readonly-group\">\r\n <ng-container\r\n *ngTemplateOutlet=\"readOnlyRulesTemplate; context: { rules: rule.rules ?? [], isGroup: true }\">\r\n </ng-container>\r\n </div>\r\n }\r\n }\r\n \r\n @if (isGroup) {\r\n <div class=\"readonly-group\">)</div>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: [".rule-tools{display:flex;gap:5px;align-items:center;padding:5px;margin-bottom:5px;justify-content:flex-end}.rule-tools>h3{flex:1 1}.rule-container{padding:5px;border-top:solid 1px var(--grey-300)}.rule-container-workspace{display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:10px;margin-bottom:10px}.rule-groups{background-color:var(--grey-50);border:solid 1px var(--grey-300);overflow:hidden;border-radius:10px}.rule-groups-tools{display:flex;border-bottom:solid 1px var(--grey-300);background-color:var(--grey-200);gap:5px;padding:5px;justify-content:flex-end}.rule-groups-items{display:flex;padding:5px;align-items:center;gap:10px;flex-wrap:wrap}.rule-condition{padding:5px;border:solid 1px var(--grey-300);border-radius:10px;background-color:#fff;font-size:14px;display:flex;gap:5px;align-items:center}.rule-condition ui-select{min-width:100px}.rule-operator{padding:5px;border-radius:10px;font-size:13px;cursor:pointer;-webkit-user-select:none;user-select:none}.op-or{background-color:var(--red-100);color:var(--red-600)}.op-or:hover{background-color:var(--red-200)}.op-and{background-color:var(--green-100);color:var(--green-700)}.op-and:hover{background-color:var(--green-200)}.rule-btns{border-top:solid 1px var(--grey-300);display:flex;justify-content:flex-end;gap:10px;padding:5px;margin-top:5px}.empty-rule-msg{padding:10px;font-size:13px;text-align:center;width:100%;color:var(--grey-400)}.focused-box{border:solid 1px var(--primary-400);border-radius:10px;box-shadow:0 0 0 3px var(--secondary-alpha)}.rule-unsaved{border-color:var(--yellow-300)!important}.condition-box{font-size:14px;padding:5px 15px;color:var(--blue-700);border:solid 1px var(--blue-500);background-color:var(--blue-100);transition:background-color ease .2s;border-radius:10px;cursor:pointer}.condition-box:hover{background-color:var(--blue-200)}.condition-box-empty{color:var(--red-800);border-color:var(--red-400);background:linear-gradient(135deg,var(--red-100) 0%,#ffdede 100%);box-shadow:inset 0 0 0 1px #b91c1c14}.condition-box-empty:hover{background:linear-gradient(135deg,var(--red-200) 0%,#ffcaca 100%)}.readonly{display:flex;gap:5px;align-items:center}.readonly-condition{font-size:13px;background-color:var(--blue-100);padding:4px 8px;color:var(--blue-800);border-radius:5px;font-weight:400}.readonly-operator{font-size:12px;font-weight:500;color:var(--grey-500)}.readonly-group{font-weight:600;color:var(--red-500)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: UicButtonComponent, selector: "ui-button", inputs: ["text", "icon", "rightIcon", "iconOnly", "disabled", "loading", "size", "type", "color"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: UicToolTipDirective, selector: "[tip]", inputs: ["tip"] }, { kind: "pipe", type: UicTranslatePipe, name: "uicTranslate" }] });
9210
9380
  }
9211
9381
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicRuleBuilderComponent, decorators: [{
9212
9382
  type: Component,
9213
9383
  args: [{ selector: 'ui-rule-builder', imports: [
9214
9384
  CommonModule,
9215
9385
  UicButtonComponent,
9216
- UicSelectComponent,
9217
9386
  FormsModule,
9218
9387
  UicToolTipDirective,
9219
9388
  UicTranslatePipe
9220
- ], template: "<div class=\"rule-tools\">\r\n <h3>\r\n {{resolvedTitle}}\r\n </h3>\r\n @if (editing) {\r\n <ui-button [tip]=\"'rule_builder.add_rule_tip' | uicTranslate\" (click)=\"addRule()\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_rule' | uicTranslate}}</ui-button>\r\n <ui-button [tip]=\"'rule_builder.add_group_tip' | uicTranslate\" (click)=\"addGroup()\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_group' | uicTranslate}}</ui-button>\r\n }@else {\r\n <ui-button [tip]=\"'rule_builder.edit_tip' | uicTranslate\" (click)=\"editing=true\" size=\"s\" type=\"bordered\" icon=\"ri-edit-line\">{{'rule_builder.edit' | uicTranslate}}</ui-button>\r\n }\r\n</div>\r\n<div class=\"rule-container\" [class.focused-box]=\"editing\">\r\n <div class=\"rule-container-workspace\">\r\n @if (editing) {\r\n <ng-container\r\n *ngTemplateOutlet=\"rulesTemplate; context: { rules: ruleDefinition, isGroup: false }\">\r\n </ng-container>\r\n } @else {\r\n <ng-container *ngTemplateOutlet=\"readOnlyTemplate\"></ng-container>\r\n }\r\n @if (ruleDefinition.length==0) {\r\n <div class=\"empty-rule-msg\">{{'rule_builder.no_rules' | uicTranslate}}</div>\r\n }\r\n </div>\r\n @if (editing) {\r\n <div class=\"rule-btns\">\r\n <ui-button color=\"black\" type=\"bordered\" [tip]=\"'rule_builder.reset_tip' | uicTranslate\" (click)=\"reset()\" >{{'rule_builder.reset' | uicTranslate}}</ui-button>\r\n <ui-button color=\"black\" [tip]=\"'rule_builder.save_tip' | uicTranslate\" (click)=\"print()\">{{'rule_builder.save' | uicTranslate}}</ui-button>\r\n </div>\r\n }\r\n</div>\r\n\r\n<ng-template #rulesTemplate let-rules=\"rules\" let-isGroup=\"isGroup\">\r\n @for (rule of rules; track $index; let i = $index) {\r\n @if (rule.type === 'condition') {\r\n <div class=\"rule-condition\" [class.rule-unsaved]=\"rule.unsaved\">\r\n <div [tip]=\"'rule_builder.edit_condition_tip' | uicTranslate\" (click)=\"manageRules(rules, i)\">\r\n <div class=\"condition-box\">{{ rule.value == null || rule.value === '' ? ('rule_builder.select_condition' | uicTranslate) : (conditionLabels[rule.value] || rule.value) }}</div>\r\n </div>\r\n <ui-button [tip]=\"'rule_builder.delete_rule_tip' | uicTranslate\" (click)=\"removeRule(rules, i)\" [iconOnly]=\"true\" size=\"s\" type=\"ghost\" icon=\"ri-delete-bin-line\" color=\"red\"></ui-button>\r\n </div>\r\n }\r\n @if (rule.type === 'operator') {\r\n <div [tip]=\"'rule_builder.toggle_operator_tip' | uicTranslate\"\r\n (click)=\"changeOperator(rules, i)\"\r\n class=\"rule-operator {{rule.value === 'AND' ? 'op-and' : 'op-or'}}\">\r\n {{ getOperatorLabel(rule.value) }}\r\n </div>\r\n }\r\n @if (rule.type === 'group') {\r\n <div class=\"rule-groups\" [class.rule-unsaved]=\"rule.unsaved\">\r\n <div class=\"rule-groups-tools\">\r\n <ui-button [tip]=\"'rule_builder.add_rule_tip' | uicTranslate\" (click)=\"addRule(rule.rules ?? [])\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_rule' | uicTranslate}}</ui-button>\r\n <ui-button [tip]=\"'rule_builder.add_group_tip' | uicTranslate\" (click)=\"addGroup(rule.rules ?? [])\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_group' | uicTranslate}}</ui-button>\r\n <ui-button [tip]=\"'rule_builder.delete_group_tip' | uicTranslate\" (click)=\"removeRule(rules, i)\" [iconOnly]=\"true\" size=\"s\" type=\"ghost\" icon=\"ri-delete-bin-line\" color=\"red\"></ui-button>\r\n </div>\r\n <div class=\"rule-groups-items\">\r\n <ng-container\r\n *ngTemplateOutlet=\"rulesTemplate; context: { rules: rule.rules ?? [], isGroup: true }\">\r\n </ng-container>\r\n </div>\r\n </div>\r\n }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #readOnlyTemplate>\r\n @if (ruleDefinition.length > 0) {\r\n <div class=\"rule-friendly-output\">\r\n <ng-container\r\n *ngTemplateOutlet=\"readOnlyRulesTemplate; context: { rules: ruleDefinition, isGroup: false }\">\r\n </ng-container>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #readOnlyRulesTemplate let-rules=\"rules\" let-isGroup=\"isGroup\">\r\n <div class=\"readonly\">\r\n @if (isGroup) {\r\n <div class=\"readonly-group\">(</div>\r\n }\r\n \r\n @for (rule of rules; track $index) {\r\n @if (rule.type === 'condition') {\r\n <div class=\"readonly-condition\">{{ getConditionLabel(rule.value) }}</div>\r\n }\r\n \r\n @if (rule.type === 'operator') {\r\n <div class=\"readonly-operator\">{{ getOperatorLabel(rule.value) }}</div>\r\n }\r\n \r\n @if (rule.type === 'group') {\r\n <div class=\"readonly-group\">\r\n <ng-container\r\n *ngTemplateOutlet=\"readOnlyRulesTemplate; context: { rules: rule.rules ?? [], isGroup: true }\">\r\n </ng-container>\r\n </div>\r\n }\r\n }\r\n \r\n @if (isGroup) {\r\n <div class=\"readonly-group\">)</div>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: [".rule-tools{display:flex;gap:5px;align-items:center;padding:5px;margin-bottom:5px;justify-content:flex-end}.rule-tools>h3{flex:1 1}.rule-container{padding:5px;border-top:solid 1px var(--grey-300)}.rule-container-workspace{display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:10px;margin-bottom:10px}.rule-groups{background-color:var(--grey-50);border:solid 1px var(--grey-300);overflow:hidden;border-radius:10px}.rule-groups-tools{display:flex;border-bottom:solid 1px var(--grey-300);background-color:var(--grey-200);gap:5px;padding:5px;justify-content:flex-end}.rule-groups-items{display:flex;padding:5px;align-items:center;gap:10px;flex-wrap:wrap}.rule-condition{padding:5px;border:solid 1px var(--grey-300);border-radius:10px;background-color:#fff;font-size:14px;display:flex;gap:5px;align-items:center}.rule-condition ui-select{min-width:100px}.rule-operator{padding:5px;border-radius:10px;font-size:13px;cursor:pointer;-webkit-user-select:none;user-select:none}.op-or{background-color:var(--red-100);color:var(--red-600)}.op-or:hover{background-color:var(--red-200)}.op-and{background-color:var(--green-100);color:var(--green-700)}.op-and:hover{background-color:var(--green-200)}.rule-btns{border-top:solid 1px var(--grey-300);display:flex;justify-content:flex-end;gap:10px;padding:5px;margin-top:5px}.empty-rule-msg{padding:10px;font-size:13px;text-align:center;width:100%;color:var(--grey-400)}.focused-box{border:solid 1px var(--primary-400);border-radius:10px;box-shadow:0 0 0 3px var(--secondary-alpha)}.rule-unsaved{border-color:var(--yellow-300)!important}.condition-box{font-size:14px;padding:5px 15px;color:var(--blue-700);border:solid 1px var(--blue-500);background-color:var(--blue-100);transition:background-color ease .2s;border-radius:10px;cursor:pointer}.condition-box:hover{background-color:var(--blue-200)}.readonly{display:flex;gap:5px;align-items:center}.readonly-condition{font-size:13px;background-color:var(--blue-100);padding:4px 8px;color:var(--blue-800);border-radius:5px;font-weight:400}.readonly-operator{font-size:12px;font-weight:500;color:var(--grey-500)}.readonly-group{font-weight:600;color:var(--red-500)}\n"] }]
9389
+ ], template: "\r\n<div class=\"rule-tools\">\r\n <h3>\r\n {{resolvedTitle}}\r\n </h3>\r\n @if (editing) {\r\n <ui-button [tip]=\"'rule_builder.add_rule_tip' | uicTranslate\" (click)=\"addRule()\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_rule' | uicTranslate}}</ui-button>\r\n <ui-button [tip]=\"'rule_builder.add_group_tip' | uicTranslate\" (click)=\"addGroup()\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_group' | uicTranslate}}</ui-button>\r\n }@else {\r\n <ui-button [tip]=\"'rule_builder.edit_tip' | uicTranslate\" (click)=\"editing=true\" size=\"s\" type=\"bordered\" icon=\"ri-edit-line\">{{'rule_builder.edit' | uicTranslate}}</ui-button>\r\n }\r\n</div>\r\n<div class=\"rule-container\" [class.focused-box]=\"editing\">\r\n <div class=\"rule-container-workspace\">\r\n @if (editing) {\r\n <ng-container\r\n *ngTemplateOutlet=\"rulesTemplate; context: { rules: editorRules, isGroup: false }\">\r\n </ng-container>\r\n } @else {\r\n <ng-container *ngTemplateOutlet=\"readOnlyTemplate\"></ng-container>\r\n }\r\n @if (editorRules.length==0) {\r\n <div class=\"empty-rule-msg\">{{'rule_builder.no_rules' | uicTranslate}}</div>\r\n }\r\n </div>\r\n @if (editing) {\r\n <div class=\"rule-btns\">\r\n <ui-button color=\"black\" type=\"bordered\" [tip]=\"'rule_builder.reset_tip' | uicTranslate\" (click)=\"reset()\" >{{'rule_builder.reset' | uicTranslate}}</ui-button>\r\n <ui-button color=\"black\" [tip]=\"'rule_builder.save_tip' | uicTranslate\" (click)=\"print()\">{{'rule_builder.save' | uicTranslate}}</ui-button>\r\n </div>\r\n }\r\n</div>\r\n\r\n<ng-template #rulesTemplate let-rules=\"rules\" let-isGroup=\"isGroup\">\r\n @for (rule of rules; track $index; let i = $index) {\r\n @if (rule.type === 'condition') {\r\n <div class=\"rule-condition\" [class.rule-unsaved]=\"rule.unsaved\">\r\n <div [tip]=\"'rule_builder.edit_condition_tip' | uicTranslate\" (click)=\"manageRules(rules, i)\">\r\n <div class=\"condition-box\" [class.condition-box-empty]=\"rule.value == null || rule.value === ''\">{{ rule.value == null || rule.value === '' ? ('rule_builder.select_condition' | uicTranslate) : (conditionLabels[rule.value] || rule.value) }}</div>\r\n </div>\r\n <ui-button [tip]=\"'rule_builder.delete_rule_tip' | uicTranslate\" (click)=\"removeRule(rules, i)\" [iconOnly]=\"true\" size=\"s\" type=\"ghost\" icon=\"ri-delete-bin-line\" color=\"red\"></ui-button>\r\n </div>\r\n }\r\n @if (rule.type === 'operator') {\r\n <div [tip]=\"'rule_builder.toggle_operator_tip' | uicTranslate\"\r\n (click)=\"changeOperator(rules, i)\"\r\n class=\"rule-operator {{rule.value === 'AND' ? 'op-and' : 'op-or'}}\">\r\n {{ getOperatorLabel(rule.value) }}\r\n </div>\r\n }\r\n @if (rule.type === 'group') {\r\n <div class=\"rule-groups\" [class.rule-unsaved]=\"rule.unsaved\">\r\n <div class=\"rule-groups-tools\">\r\n <ui-button [tip]=\"'rule_builder.add_rule_tip' | uicTranslate\" (click)=\"addRule(rule.rules ?? [])\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_rule' | uicTranslate}}</ui-button>\r\n <ui-button [tip]=\"'rule_builder.add_group_tip' | uicTranslate\" (click)=\"addGroup(rule.rules ?? [])\" size=\"s\" type=\"bordered\" icon=\"ri-add-line\">{{'rule_builder.add_group' | uicTranslate}}</ui-button>\r\n <ui-button [tip]=\"'rule_builder.delete_group_tip' | uicTranslate\" (click)=\"removeRule(rules, i)\" [iconOnly]=\"true\" size=\"s\" type=\"ghost\" icon=\"ri-delete-bin-line\" color=\"red\"></ui-button>\r\n </div>\r\n <div class=\"rule-groups-items\">\r\n <ng-container\r\n *ngTemplateOutlet=\"rulesTemplate; context: { rules: rule.rules ?? [], isGroup: true }\">\r\n </ng-container>\r\n </div>\r\n </div>\r\n }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #readOnlyTemplate>\r\n @if (editorRules.length > 0) {\r\n <div class=\"rule-friendly-output\">\r\n <ng-container\r\n *ngTemplateOutlet=\"readOnlyRulesTemplate; context: { rules: editorRules, isGroup: false }\">\r\n </ng-container>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #readOnlyRulesTemplate let-rules=\"rules\" let-isGroup=\"isGroup\">\r\n <div class=\"readonly\">\r\n @if (isGroup) {\r\n <div class=\"readonly-group\">(</div>\r\n }\r\n \r\n @for (rule of rules; track $index) {\n @if (rule.type === 'condition') {\n <div class=\"readonly-condition\" [tip]=\"getConditionDetailTip(rule.value)\">{{ getConditionLabel(rule.value) }}</div>\n }\n \r\n @if (rule.type === 'operator') {\r\n <div class=\"readonly-operator\">{{ getOperatorLabel(rule.value) }}</div>\r\n }\r\n \r\n @if (rule.type === 'group') {\r\n <div class=\"readonly-group\">\r\n <ng-container\r\n *ngTemplateOutlet=\"readOnlyRulesTemplate; context: { rules: rule.rules ?? [], isGroup: true }\">\r\n </ng-container>\r\n </div>\r\n }\r\n }\r\n \r\n @if (isGroup) {\r\n <div class=\"readonly-group\">)</div>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: [".rule-tools{display:flex;gap:5px;align-items:center;padding:5px;margin-bottom:5px;justify-content:flex-end}.rule-tools>h3{flex:1 1}.rule-container{padding:5px;border-top:solid 1px var(--grey-300)}.rule-container-workspace{display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:10px;margin-bottom:10px}.rule-groups{background-color:var(--grey-50);border:solid 1px var(--grey-300);overflow:hidden;border-radius:10px}.rule-groups-tools{display:flex;border-bottom:solid 1px var(--grey-300);background-color:var(--grey-200);gap:5px;padding:5px;justify-content:flex-end}.rule-groups-items{display:flex;padding:5px;align-items:center;gap:10px;flex-wrap:wrap}.rule-condition{padding:5px;border:solid 1px var(--grey-300);border-radius:10px;background-color:#fff;font-size:14px;display:flex;gap:5px;align-items:center}.rule-condition ui-select{min-width:100px}.rule-operator{padding:5px;border-radius:10px;font-size:13px;cursor:pointer;-webkit-user-select:none;user-select:none}.op-or{background-color:var(--red-100);color:var(--red-600)}.op-or:hover{background-color:var(--red-200)}.op-and{background-color:var(--green-100);color:var(--green-700)}.op-and:hover{background-color:var(--green-200)}.rule-btns{border-top:solid 1px var(--grey-300);display:flex;justify-content:flex-end;gap:10px;padding:5px;margin-top:5px}.empty-rule-msg{padding:10px;font-size:13px;text-align:center;width:100%;color:var(--grey-400)}.focused-box{border:solid 1px var(--primary-400);border-radius:10px;box-shadow:0 0 0 3px var(--secondary-alpha)}.rule-unsaved{border-color:var(--yellow-300)!important}.condition-box{font-size:14px;padding:5px 15px;color:var(--blue-700);border:solid 1px var(--blue-500);background-color:var(--blue-100);transition:background-color ease .2s;border-radius:10px;cursor:pointer}.condition-box:hover{background-color:var(--blue-200)}.condition-box-empty{color:var(--red-800);border-color:var(--red-400);background:linear-gradient(135deg,var(--red-100) 0%,#ffdede 100%);box-shadow:inset 0 0 0 1px #b91c1c14}.condition-box-empty:hover{background:linear-gradient(135deg,var(--red-200) 0%,#ffcaca 100%)}.readonly{display:flex;gap:5px;align-items:center}.readonly-condition{font-size:13px;background-color:var(--blue-100);padding:4px 8px;color:var(--blue-800);border-radius:5px;font-weight:400}.readonly-operator{font-size:12px;font-weight:500;color:var(--grey-500)}.readonly-group{font-weight:600;color:var(--red-500)}\n"] }]
9221
9390
  }], propDecorators: { conditions: [{
9222
9391
  type: Input
9223
9392
  }], conditionOperators: [{
@@ -9226,10 +9395,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
9226
9395
  type: Input
9227
9396
  }], title: [{
9228
9397
  type: Input
9229
- }], initValue: [{
9398
+ }], ruleDefinition: [{
9230
9399
  type: Input
9231
9400
  }], ruleDefinitionChange: [{
9232
9401
  type: Output
9402
+ }], conditionsChange: [{
9403
+ type: Output
9233
9404
  }] } });
9234
9405
 
9235
9406
  class FirstCapitalPipe {