ui-core-abv 0.6.41 → 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.
@@ -8789,6 +8789,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
8789
8789
  class UicRuleBuilderComponent {
8790
8790
  conditionsInitialized = false;
8791
8791
  emitConditionsOnInit = false;
8792
+ emitRuleDefinitionOnInit = false;
8793
+ conditionsEmitScheduled = false;
8794
+ ruleDefinitionEmitScheduled = false;
8792
8795
  _conditions = [
8793
8796
  {
8794
8797
  id: 1,
@@ -8857,16 +8860,19 @@ class UicRuleBuilderComponent {
8857
8860
  set conditions(value) {
8858
8861
  this._conditions = Array.isArray(value) ? value.map(condition => ({ ...condition })) : [];
8859
8862
  const conditionsNormalized = this.refreshAvailableConditions();
8860
- const referencesUpdated = this.syncConditionReferencesWithPersistedConditions();
8863
+ const syncResult = this.syncConditionsWithPersistedConditions();
8861
8864
  this.syncNextTemporalConditionId();
8862
- if (this.conditionsInitialized && conditionsNormalized) {
8863
- this.emitConditionsState();
8865
+ if (this.conditionsInitialized && (conditionsNormalized || syncResult.conditionsCleaned)) {
8866
+ this.scheduleConditionsStateEmit();
8864
8867
  }
8865
- if (!this.conditionsInitialized && conditionsNormalized) {
8868
+ if (!this.conditionsInitialized && (conditionsNormalized || syncResult.conditionsCleaned)) {
8866
8869
  this.emitConditionsOnInit = true;
8867
8870
  }
8868
- if (this.conditionsInitialized && referencesUpdated) {
8869
- this.emitRuleDefinitionState();
8871
+ if (this.conditionsInitialized && syncResult.referencesUpdated) {
8872
+ this.scheduleRuleDefinitionStateEmit();
8873
+ }
8874
+ if (!this.conditionsInitialized && syncResult.referencesUpdated) {
8875
+ this.emitRuleDefinitionOnInit = true;
8870
8876
  }
8871
8877
  this.conditionsInitialized = true;
8872
8878
  }
@@ -8887,7 +8893,20 @@ class UicRuleBuilderComponent {
8887
8893
  }
8888
8894
  this.externalRuleDefinition = normalizedValue;
8889
8895
  this.editorRules = this.getRulesFromDefinition(normalizedValue.definition);
8896
+ const syncResult = this.syncConditionsWithPersistedConditions();
8890
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
+ }
8891
8910
  }
8892
8911
  get ruleDefinition() {
8893
8912
  return this.externalRuleDefinition;
@@ -8907,11 +8926,22 @@ class UicRuleBuilderComponent {
8907
8926
  this.conditionsInitialized = true;
8908
8927
  }
8909
8928
  this.editorRules = this.getRulesFromDefinition(this.ruleDefinition.definition);
8929
+ const syncResult = this.syncConditionsWithPersistedConditions();
8910
8930
  this.syncNextTemporalConditionId();
8931
+ if (syncResult.conditionsCleaned) {
8932
+ this.emitConditionsOnInit = true;
8933
+ }
8934
+ if (syncResult.referencesUpdated) {
8935
+ this.emitRuleDefinitionOnInit = true;
8936
+ }
8911
8937
  if (this.emitConditionsOnInit) {
8912
- this.emitConditionsState();
8938
+ this.scheduleConditionsStateEmit();
8913
8939
  this.emitConditionsOnInit = false;
8914
8940
  }
8941
+ if (this.emitRuleDefinitionOnInit) {
8942
+ this.scheduleRuleDefinitionStateEmit();
8943
+ this.emitRuleDefinitionOnInit = false;
8944
+ }
8915
8945
  }
8916
8946
  addRule(rules = this.editorRules) {
8917
8947
  this.appendExpression(rules, this.createConditionRule());
@@ -8981,6 +9011,17 @@ class UicRuleBuilderComponent {
8981
9011
  getConditionLabel(value) {
8982
9012
  return this.resolveConditionLabel(value);
8983
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
+ }
8984
9025
  getOperatorLabel(value) {
8985
9026
  const normalizedValue = value === 'OR' ? 'OR' : 'AND';
8986
9027
  const translationKey = normalizedValue === 'AND'
@@ -9184,7 +9225,7 @@ class UicRuleBuilderComponent {
9184
9225
  this._conditions = [...this._conditions, normalizedCondition];
9185
9226
  }
9186
9227
  this.refreshAvailableConditions();
9187
- this.emitConditionsState();
9228
+ this.scheduleConditionsStateEmit();
9188
9229
  return conditionReference;
9189
9230
  }
9190
9231
  buildRuleOutput() {
@@ -9212,6 +9253,26 @@ class UicRuleBuilderComponent {
9212
9253
  emitConditionsState() {
9213
9254
  this.conditionsChange.emit(this._conditions.map(condition => ({ ...condition })));
9214
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
+ }
9215
9276
  normalizeRuleBuilderValue(value) {
9216
9277
  if (!value) {
9217
9278
  return this.createEmptyRuleBuilderValue();
@@ -9251,14 +9312,27 @@ class UicRuleBuilderComponent {
9251
9312
  }, {});
9252
9313
  return changed;
9253
9314
  }
9254
- syncConditionReferencesWithPersistedConditions() {
9315
+ syncConditionsWithPersistedConditions() {
9255
9316
  const persistedConditionsByTemporalId = new Map(this._conditions
9256
9317
  .filter(condition => condition.id !== 0 && !!condition.temporalId)
9257
9318
  .map(condition => [String(condition.temporalId), condition]));
9258
9319
  if (persistedConditionsByTemporalId.size === 0) {
9259
- return false;
9320
+ return {
9321
+ referencesUpdated: false,
9322
+ conditionsCleaned: false
9323
+ };
9260
9324
  }
9261
- return this.replaceConditionReferences(this.editorRules, persistedConditionsByTemporalId);
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
+ };
9262
9336
  }
9263
9337
  replaceConditionReferences(rules, persistedConditionsByTemporalId) {
9264
9338
  let updated = false;
@@ -9287,7 +9361,9 @@ class UicRuleBuilderComponent {
9287
9361
  }
9288
9362
  syncNextTemporalConditionId() {
9289
9363
  const references = [
9290
- ...this.conditions.map(condition => String(this.getConditionReference(condition))),
9364
+ ...this.conditions
9365
+ .flatMap(condition => [String(this.getConditionReference(condition)), String(condition.temporalId ?? '')])
9366
+ .filter(reference => reference !== ''),
9291
9367
  ...this.collectConditionValues(this.editorRules)
9292
9368
  ];
9293
9369
  const nextId = references.reduce((maxId, reference) => {
@@ -9300,7 +9376,7 @@ class UicRuleBuilderComponent {
9300
9376
  this.nextTemporalConditionId = nextId + 1;
9301
9377
  }
9302
9378
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicRuleBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9303
- 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: "<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) {\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)}.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" }] });
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" }] });
9304
9380
  }
9305
9381
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UicRuleBuilderComponent, decorators: [{
9306
9382
  type: Component,
@@ -9310,7 +9386,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
9310
9386
  FormsModule,
9311
9387
  UicToolTipDirective,
9312
9388
  UicTranslatePipe
9313
- ], 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: 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) {\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)}.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"] }]
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"] }]
9314
9390
  }], propDecorators: { conditions: [{
9315
9391
  type: Input
9316
9392
  }], conditionOperators: [{