@o3r/rules-engine 11.6.0-prerelease.2 → 11.6.0-prerelease.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/builders/rules-engine-extractor/helpers/rules-engine.extractor.d.ts +1 -10
- package/builders/rules-engine-extractor/helpers/rules-engine.extractor.d.ts.map +1 -1
- package/builders/rules-engine-extractor/helpers/rules-engine.extractor.interfaces.d.ts +1 -2
- package/builders/rules-engine-extractor/helpers/rules-engine.extractor.interfaces.d.ts.map +1 -1
- package/builders/rules-engine-extractor/helpers/rules-engine.extractor.js +27 -36
- package/builders/rules-engine-extractor/index.d.ts.map +1 -1
- package/builders/rules-engine-extractor/index.js +15 -20
- package/builders/rules-engine-extractor/schema.d.ts.map +1 -1
- package/components/rules-engine/index.d.ts +1 -1
- package/components/rules-engine/index.d.ts.map +1 -1
- package/components/rules-engine/rule-actions/rule-actions-pres.component.d.ts.map +1 -1
- package/components/rules-engine/rule-condition/rule-condition-pres.component.d.ts.map +1 -1
- package/components/rules-engine/rule-key-value/rule-key-value-pres.component.d.ts.map +1 -1
- package/components/rules-engine/rule-tree/rule-tree-pres.component.d.ts.map +1 -1
- package/components/rules-engine/ruleset-history/ruleset-history-pres.component.d.ts.map +1 -1
- package/components/rules-engine/ruleset-history/ruleset-history-pres.module.d.ts.map +1 -1
- package/components/rules-engine/shared/fallback-to.pipe.d.ts.map +1 -1
- package/components/rules-engine/shared/index.d.ts +1 -1
- package/components/rules-engine/shared/index.d.ts.map +1 -1
- package/components/rules-engine/shared/json-or-string.pipe.d.ts.map +1 -1
- package/components/rules-engine/shared/ruleset-history.helper.d.ts.map +1 -1
- package/devkit/rules-engine-devkit.interface.d.ts.map +1 -1
- package/devkit/rules-engine-devtools.console.service.d.ts.map +1 -1
- package/devkit/rules-engine-devtools.message.service.d.ts +1 -1
- package/devkit/rules-engine-devtools.message.service.d.ts.map +1 -1
- package/devkit/rules-engine-devtools.module.d.ts.map +1 -1
- package/devkit/rules-engine-devtools.service.d.ts.map +1 -1
- package/devkit/rules-engine-devtools.token.d.ts +1 -1
- package/devkit/rules-engine-devtools.token.d.ts.map +1 -1
- package/engine/debug/engine.debug.d.ts +0 -2
- package/engine/debug/engine.debug.d.ts.map +1 -1
- package/engine/debug/helpers.d.ts.map +1 -1
- package/engine/engine.d.ts +1 -4
- package/engine/engine.d.ts.map +1 -1
- package/engine/engine.interface.d.ts.map +1 -1
- package/engine/fact/fact.interfaces.d.ts.map +1 -1
- package/engine/helpers/filter-ruleset-event.operator.d.ts.map +1 -1
- package/engine/operator/operator.helpers.d.ts +1 -3
- package/engine/operator/operator.helpers.d.ts.map +1 -1
- package/engine/operator/operator.interface.d.ts.map +1 -1
- package/engine/operator/operators/array-based.operators.d.ts.map +1 -1
- package/engine/operator/operators/basic.operators.d.ts.map +1 -1
- package/engine/operator/operators/date-based.operators.d.ts.map +1 -1
- package/engine/operator/operators/index.d.ts +2 -2
- package/engine/operator/operators/index.d.ts.map +1 -1
- package/engine/operator/operators/number-based.operators.d.ts.map +1 -1
- package/engine/ruleset-executor.d.ts +7 -2
- package/engine/ruleset-executor.d.ts.map +1 -1
- package/engine/structure.d.ts.map +1 -1
- package/esm2022/components/rules-engine/index.mjs +2 -2
- package/esm2022/components/rules-engine/rule-actions/rule-actions-pres.component.mjs +5 -5
- package/esm2022/components/rules-engine/rule-condition/rule-condition-pres.component.mjs +6 -7
- package/esm2022/components/rules-engine/rule-key-value/rule-key-value-pres.component.mjs +8 -8
- package/esm2022/components/rules-engine/rule-tree/rule-tree-pres.component.mjs +5 -5
- package/esm2022/components/rules-engine/ruleset-history/ruleset-history-pres.component.mjs +9 -9
- package/esm2022/components/rules-engine/ruleset-history/ruleset-history-pres.module.mjs +13 -13
- package/esm2022/components/rules-engine/shared/fallback-to.pipe.mjs +9 -9
- package/esm2022/components/rules-engine/shared/index.mjs +2 -2
- package/esm2022/components/rules-engine/shared/json-or-string.pipe.mjs +5 -5
- package/esm2022/components/rules-engine/shared/ruleset-history.helper.mjs +5 -5
- package/esm2022/devkit/index.mjs +1 -1
- package/esm2022/devkit/rules-engine-devkit.interface.mjs +4 -4
- package/esm2022/devkit/rules-engine-devtools.console.service.mjs +8 -10
- package/esm2022/devkit/rules-engine-devtools.message.service.mjs +15 -15
- package/esm2022/devkit/rules-engine-devtools.module.mjs +11 -11
- package/esm2022/devkit/rules-engine-devtools.service.mjs +19 -19
- package/esm2022/devkit/rules-engine-devtools.token.mjs +2 -2
- package/esm2022/engine/debug/engine.debug.mjs +16 -18
- package/esm2022/engine/debug/helpers.mjs +11 -11
- package/esm2022/engine/engine.interface.mjs +1 -1
- package/esm2022/engine/engine.mjs +12 -15
- package/esm2022/engine/fact/fact.interfaces.mjs +1 -1
- package/esm2022/engine/helpers/filter-ruleset-event.operator.mjs +6 -6
- package/esm2022/engine/operator/operator.helpers.mjs +15 -17
- package/esm2022/engine/operator/operator.interface.mjs +1 -1
- package/esm2022/engine/operator/operators/array-based.operators.mjs +11 -11
- package/esm2022/engine/operator/operators/basic.operators.mjs +8 -8
- package/esm2022/engine/operator/operators/date-based.operators.mjs +3 -3
- package/esm2022/engine/operator/operators/index.mjs +6 -6
- package/esm2022/engine/operator/operators/number-based.operators.mjs +2 -2
- package/esm2022/engine/rule/index.mjs +1 -1
- package/esm2022/engine/rule/rule.helpers.mjs +1 -1
- package/esm2022/engine/ruleset-executor.mjs +27 -23
- package/esm2022/engine/structure.mjs +1 -1
- package/esm2022/fact/fact.abstract-service.mjs +1 -1
- package/esm2022/fact/reserved.facts.mjs +1 -1
- package/esm2022/fixtures/jasmine/rules-engine.runner.service.fixture.jasmine.mjs +1 -1
- package/esm2022/fixtures/jest/rules-engine.runner.service.fixture.jest.mjs +1 -1
- package/esm2022/inner-facts/current-time/current-time-fact.service.mjs +8 -8
- package/esm2022/inner-facts/current-time/current-time.facts.mjs +1 -1
- package/esm2022/inner-facts/current-time/index.mjs +2 -2
- package/esm2022/interfaces/action.interfaces.mjs +1 -1
- package/esm2022/interfaces/index.mjs +1 -1
- package/esm2022/public_api.mjs +1 -2
- package/esm2022/services/index.mjs +2 -2
- package/esm2022/services/rules-engine.token.mjs +2 -2
- package/esm2022/services/runner/rules-engine.runner.module.mjs +11 -11
- package/esm2022/services/runner/rules-engine.runner.service.mjs +34 -17
- package/esm2022/stores/rulesets/rulesets.actions.mjs +3 -3
- package/esm2022/stores/rulesets/rulesets.effect.mjs +10 -10
- package/esm2022/stores/rulesets/rulesets.module.mjs +11 -11
- package/esm2022/stores/rulesets/rulesets.reducer.mjs +4 -4
- package/esm2022/stores/rulesets/rulesets.selectors.mjs +10 -10
- package/esm2022/stores/rulesets/rulesets.state.mjs +1 -1
- package/esm2022/stores/rulesets/rulesets.sync.mjs +3 -3
- package/fact/fact.abstract-service.d.ts.map +1 -1
- package/fact/reserved.facts.d.ts.map +1 -1
- package/fesm2022/o3r-rules-engine-fixtures-jasmine.mjs.map +1 -1
- package/fesm2022/o3r-rules-engine-fixtures-jest.mjs.map +1 -1
- package/fesm2022/o3r-rules-engine.mjs +322 -311
- package/fesm2022/o3r-rules-engine.mjs.map +1 -1
- package/fixtures/jasmine/rules-engine.runner.service.fixture.jasmine.d.ts.map +1 -1
- package/fixtures/jest/rules-engine.runner.service.fixture.jest.d.ts.map +1 -1
- package/fixtures/jest/rules-engine.runner.service.fixture.jest.js.map +1 -1
- package/inner-facts/current-time/current-time-fact.service.d.ts +1 -1
- package/inner-facts/current-time/current-time-fact.service.d.ts.map +1 -1
- package/inner-facts/current-time/current-time.facts.d.ts.map +1 -1
- package/inner-facts/current-time/index.d.ts +1 -1
- package/inner-facts/current-time/index.d.ts.map +1 -1
- package/interfaces/action.interfaces.d.ts.map +1 -1
- package/migration.json +5 -0
- package/package.json +5 -5
- package/public_api.d.ts +0 -1
- package/public_api.d.ts.map +1 -1
- package/schemas/rulesets.schema.json +20 -0
- package/schematics/cms-adapter/index.d.ts.map +1 -1
- package/schematics/cms-adapter/index.js +1 -3
- package/schematics/facts-service/index.d.ts.map +1 -1
- package/schematics/facts-service/index.js +2 -2
- package/schematics/facts-service/schema.d.ts.map +1 -1
- package/schematics/ng-add/helpers/devtools-registration.d.ts +0 -2
- package/schematics/ng-add/helpers/devtools-registration.d.ts.map +1 -1
- package/schematics/ng-add/helpers/devtools-registration.js +2 -4
- package/schematics/ng-add/index.d.ts.map +1 -1
- package/schematics/ng-add/index.js +8 -11
- package/schematics/ng-add/schema.d.ts.map +1 -1
- package/schematics/ng-update/index.d.ts +5 -1
- package/schematics/ng-update/index.d.ts.map +1 -1
- package/schematics/ng-update/index.js +17 -5
- package/schematics/ng-update/v10.0/action-module-split.d.ts.map +1 -1
- package/schematics/ng-update/v10.0/action-module-split.js +0 -2
- package/schematics/ng-update/v11.6/use-register-action-handlers.d.ts +7 -0
- package/schematics/ng-update/v11.6/use-register-action-handlers.d.ts.map +1 -0
- package/schematics/ng-update/v11.6/use-register-action-handlers.js +20 -0
- package/schematics/operator/index.d.ts.map +1 -1
- package/schematics/operator/index.js +2 -2
- package/schematics/operator/schema.d.ts.map +1 -1
- package/schematics/rules-engine-to-component/index.d.ts.map +1 -1
- package/schematics/rules-engine-to-component/schema.d.ts.map +1 -1
- package/services/index.d.ts +1 -1
- package/services/index.d.ts.map +1 -1
- package/services/rules-engine.token.d.ts +1 -1
- package/services/rules-engine.token.d.ts.map +1 -1
- package/services/runner/rules-engine.runner.module.d.ts.map +1 -1
- package/services/runner/rules-engine.runner.service.d.ts +19 -6
- package/services/runner/rules-engine.runner.service.d.ts.map +1 -1
- package/stores/rulesets/rulesets.actions.d.ts.map +1 -1
- package/stores/rulesets/rulesets.effect.d.ts.map +1 -1
- package/stores/rulesets/rulesets.module.d.ts.map +1 -1
- package/stores/rulesets/rulesets.reducer.d.ts.map +1 -1
- package/stores/rulesets/rulesets.selectors.d.ts.map +1 -1
- package/stores/rulesets/rulesets.state.d.ts.map +1 -1
- package/stores/rulesets/rulesets.sync.d.ts.map +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Component, ChangeDetectionStrategy, ViewEncapsulation, Input, Pipe, NgModule, InjectionToken, Injectable, Optional, Inject } from '@angular/core';
|
|
1
3
|
import * as i1 from '@angular/common';
|
|
2
4
|
import { CommonModule, JsonPipe } from '@angular/common';
|
|
3
|
-
import * as i0 from '@angular/core';
|
|
4
|
-
import { Component, ChangeDetectionStrategy, ViewEncapsulation, Input, Pipe, NgModule, Injectable, InjectionToken, Optional, Inject } from '@angular/core';
|
|
5
5
|
import { Subject, of, from, ReplaySubject, Observable, combineLatest, BehaviorSubject, merge, firstValueFrom, Subscription, fromEvent } from 'rxjs';
|
|
6
6
|
import { switchMap, delay, startWith, mergeMap, map, catchError, withLatestFrom, concatMap, tap, share, shareReplay, pairwise, distinctUntilChanged, takeUntil, filter, scan } from 'rxjs/operators';
|
|
7
7
|
import * as i1$2 from '@ngrx/store';
|
|
@@ -14,6 +14,39 @@ import { createEffect, ofType, EffectsModule } from '@ngrx/effects';
|
|
|
14
14
|
import { createEntityAdapter } from '@ngrx/entity';
|
|
15
15
|
import { JSONPath } from 'jsonpath-plus';
|
|
16
16
|
|
|
17
|
+
class RuleConditionPresComponent {
|
|
18
|
+
constructor() {
|
|
19
|
+
/**
|
|
20
|
+
* Left hand operator as it will be displayed in the template.
|
|
21
|
+
* In the case of a fact with a json path, will resolve the whole fact path, else will only display the value
|
|
22
|
+
*/
|
|
23
|
+
this.lhs = 'undefined';
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Rule condition that will be flattened by the component setter
|
|
27
|
+
*/
|
|
28
|
+
set condition(condition) {
|
|
29
|
+
this._condition = condition;
|
|
30
|
+
this.lhs = condition?.lhs ? this.getOperandName(condition.lhs) : 'undefined';
|
|
31
|
+
this.rhs = condition?.rhs ? this.getOperandName(condition.rhs) : undefined;
|
|
32
|
+
}
|
|
33
|
+
get condition() {
|
|
34
|
+
return this._condition;
|
|
35
|
+
}
|
|
36
|
+
getOperandName(operand) {
|
|
37
|
+
const value = `${operand.value ?? 'MISSING_VALUE'}`;
|
|
38
|
+
return operand.path ? operand.path.replace(/^\$/, value) : value;
|
|
39
|
+
}
|
|
40
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleConditionPresComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
41
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RuleConditionPresComponent, selector: "o3r-rule-condition-pres", inputs: { condition: "condition" }, ngImport: i0, template: "<ng-container *ngIf=\"!condition; else displayConditions\">\n <span class=\"input-value\">true</span>\n</ng-container>\n<ng-template #displayConditions>\n <ng-container *ngIf=\"!$any(condition).all && !$any(condition).any && !$any(condition).not\">\n <span class=\"input-key\">{{ lhs }}</span> {{ $any(condition).operator }} <span class=\"input-value\" *ngIf=\"rhs !== undefined\">{{ rhs }}</span>\n </ng-container>\n <ng-container *ngIf=\"$any(condition).all || $any(condition).any || $any(condition).not\">\n <span *ngIf=\"$any(condition).all\">ALL</span>\n <span *ngIf=\"$any(condition).any\">ANY</span>\n <span *ngIf=\"$any(condition).not\">NOT</span>\n <span>(\n <ng-container *ngFor=\"let cond of $any(condition).all || $any(condition).any || [$any(condition).not]; let last = last;\">\n <o3r-rule-condition-pres [condition]=\"cond\"></o3r-rule-condition-pres>\n <span *ngIf=\"!last\">, </span>\n </ng-container>\n )</span>\n </ng-container>\n</ng-template>\n", styles: ["o3r-rule-condition-pres{word-break:break-word}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: RuleConditionPresComponent, selector: "o3r-rule-condition-pres", inputs: ["condition"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
42
|
+
}
|
|
43
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleConditionPresComponent, decorators: [{
|
|
44
|
+
type: Component,
|
|
45
|
+
args: [{ selector: 'o3r-rule-condition-pres', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"!condition; else displayConditions\">\n <span class=\"input-value\">true</span>\n</ng-container>\n<ng-template #displayConditions>\n <ng-container *ngIf=\"!$any(condition).all && !$any(condition).any && !$any(condition).not\">\n <span class=\"input-key\">{{ lhs }}</span> {{ $any(condition).operator }} <span class=\"input-value\" *ngIf=\"rhs !== undefined\">{{ rhs }}</span>\n </ng-container>\n <ng-container *ngIf=\"$any(condition).all || $any(condition).any || $any(condition).not\">\n <span *ngIf=\"$any(condition).all\">ALL</span>\n <span *ngIf=\"$any(condition).any\">ANY</span>\n <span *ngIf=\"$any(condition).not\">NOT</span>\n <span>(\n <ng-container *ngFor=\"let cond of $any(condition).all || $any(condition).any || [$any(condition).not]; let last = last;\">\n <o3r-rule-condition-pres [condition]=\"cond\"></o3r-rule-condition-pres>\n <span *ngIf=\"!last\">, </span>\n </ng-container>\n )</span>\n </ng-container>\n</ng-template>\n", styles: ["o3r-rule-condition-pres{word-break:break-word}\n"] }]
|
|
46
|
+
}], propDecorators: { condition: [{
|
|
47
|
+
type: Input
|
|
48
|
+
}] } });
|
|
49
|
+
|
|
17
50
|
/**
|
|
18
51
|
* Duration of the notification for clipboard feature (in milliseconds)
|
|
19
52
|
*/
|
|
@@ -56,12 +89,12 @@ class RuleKeyValuePresComponent {
|
|
|
56
89
|
await navigator.clipboard.writeText(content);
|
|
57
90
|
this.triggerNotification.next();
|
|
58
91
|
}
|
|
59
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
60
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.
|
|
92
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleKeyValuePresComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
93
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RuleKeyValuePresComponent, selector: "o3r-rule-key-value-pres", inputs: { key: "key", value: "value", oldValue: "oldValue", type: "type" }, usesOnChanges: true, ngImport: i0, template: "<span *ngIf=\"key\" class=\"input-key\">{{key}}<ng-container *ngIf=\"type === 'state'\">: </ng-container></span>\n<ng-container *ngIf=\"type === 'assignment'\"> = </ng-container>\n<ng-container *ngIf=\"oldValue\">\n <pre class=\"input-value\"\n [class.limit-characters]=\"shouldLimitCharactersForOldValue\"\n (click)=\"shouldLimitCharactersForOldValue = !shouldLimitCharactersForOldValue\"\n (keyup.enter)=\"shouldLimitCharactersForOldValue = !shouldLimitCharactersForOldValue\"\n tabindex=\"0\"\n >\n {{isOldValuePrimitiveType ? oldValue : (oldValue | json)}}\n </pre>\n <button (click)=\"copyToClipBoard(oldValue)\" *ngIf=\"isClipBoardFeatureAvailableForOldValue\" title=\"Copy to clipboard\">\uD83D\uDCCB</button>\n \u2192\n</ng-container>\n<pre class=\"input-value\"\n [class.limit-characters]=\"shouldLimitCharactersForValue\"\n (click)=\"shouldLimitCharactersForValue = !shouldLimitCharactersForValue\"\n (keyup.enter)=\"shouldLimitCharactersForValue = !shouldLimitCharactersForValue\"\n tabindex=\"0\"\n>\n {{isValuePrimitiveType ? value : (value | json)}}\n</pre>\n<button (click)=\"copyToClipBoard(value)\" *ngIf=\"isClipBoardFeatureAvailableForValue\" title=\"Copy to clipboard\">\uD83D\uDCCB</button>\n<div role=\"alert\" class=\"notification\" *ngIf=\"showNotification$ | async\">Copied to clipboard</div>\n", styles: ["o3r-rule-key-value-pres{position:relative}o3r-rule-key-value-pres .ruleset-panel-title,o3r-rule-key-value-pres .ruleset-panel-category-title{display:flex;justify-content:space-between;align-items:center}o3r-rule-key-value-pres .ruleset-panel-title{font-size:1rem;padding:.5rem 0 .1rem}o3r-rule-key-value-pres .ruleset-expansion-action,o3r-rule-key-value-pres .icon-caret-down,o3r-rule-key-value-pres .icon-caret-up{cursor:pointer}o3r-rule-key-value-pres .ruleset-panel-subtitle{font-size:.75rem}o3r-rule-key-value-pres .ruleset-panel-title-aside{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;min-width:fit-content}o3r-rule-key-value-pres .ruleset-panel-category-title{font-size:.95rem;background:#eee;padding:.5rem;margin-bottom:.5rem;margin-top:1rem}o3r-rule-key-value-pres .rule-description .ruleset-panel-category-title{font-size:.893rem;cursor:default}o3r-rule-key-value-pres .rule-description .ruleset-panel-title{font-size:.94rem}o3r-rule-key-value-pres .rule-description .ruleset-panel-category-body{padding-bottom:.5rem;padding-left:1.5rem}o3r-rule-key-value-pres .rule-description .ruleset-panel-category-body:empty{margin:0;padding:0 0 0 1.5rem}o3r-rule-key-value-pres .limit-characters{display:inline-block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;max-width:38rem;vertical-align:bottom}o3r-rule-key-value-pres .input-value{margin-top:0;margin-bottom:0}o3r-rule-key-value-pres button{background:none;border:0;appearance:none}o3r-rule-key-value-pres .notification{position:absolute;padding:1rem 1.5rem;border-radius:5px;background:#444;color:#eee;right:0;z-index:1}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
61
94
|
}
|
|
62
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
95
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleKeyValuePresComponent, decorators: [{
|
|
63
96
|
type: Component,
|
|
64
|
-
args: [{ selector: 'o3r-rule-key-value-pres', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<span *ngIf=\"key\" class=\"input-key\">{{key}}<ng-container *ngIf=\"type === 'state'\">: </ng-container></span>\n<ng-container *ngIf=\"type === 'assignment'\"> = </ng-container>\n<ng-container *ngIf=\"oldValue\">\n <pre class=\"input-value\"\n [class.limit-characters]=\"shouldLimitCharactersForOldValue\"\n (click)=\"shouldLimitCharactersForOldValue = !shouldLimitCharactersForOldValue\"
|
|
97
|
+
args: [{ selector: 'o3r-rule-key-value-pres', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<span *ngIf=\"key\" class=\"input-key\">{{key}}<ng-container *ngIf=\"type === 'state'\">: </ng-container></span>\n<ng-container *ngIf=\"type === 'assignment'\"> = </ng-container>\n<ng-container *ngIf=\"oldValue\">\n <pre class=\"input-value\"\n [class.limit-characters]=\"shouldLimitCharactersForOldValue\"\n (click)=\"shouldLimitCharactersForOldValue = !shouldLimitCharactersForOldValue\"\n (keyup.enter)=\"shouldLimitCharactersForOldValue = !shouldLimitCharactersForOldValue\"\n tabindex=\"0\"\n >\n {{isOldValuePrimitiveType ? oldValue : (oldValue | json)}}\n </pre>\n <button (click)=\"copyToClipBoard(oldValue)\" *ngIf=\"isClipBoardFeatureAvailableForOldValue\" title=\"Copy to clipboard\">\uD83D\uDCCB</button>\n \u2192\n</ng-container>\n<pre class=\"input-value\"\n [class.limit-characters]=\"shouldLimitCharactersForValue\"\n (click)=\"shouldLimitCharactersForValue = !shouldLimitCharactersForValue\"\n (keyup.enter)=\"shouldLimitCharactersForValue = !shouldLimitCharactersForValue\"\n tabindex=\"0\"\n>\n {{isValuePrimitiveType ? value : (value | json)}}\n</pre>\n<button (click)=\"copyToClipBoard(value)\" *ngIf=\"isClipBoardFeatureAvailableForValue\" title=\"Copy to clipboard\">\uD83D\uDCCB</button>\n<div role=\"alert\" class=\"notification\" *ngIf=\"showNotification$ | async\">Copied to clipboard</div>\n", styles: ["o3r-rule-key-value-pres{position:relative}o3r-rule-key-value-pres .ruleset-panel-title,o3r-rule-key-value-pres .ruleset-panel-category-title{display:flex;justify-content:space-between;align-items:center}o3r-rule-key-value-pres .ruleset-panel-title{font-size:1rem;padding:.5rem 0 .1rem}o3r-rule-key-value-pres .ruleset-expansion-action,o3r-rule-key-value-pres .icon-caret-down,o3r-rule-key-value-pres .icon-caret-up{cursor:pointer}o3r-rule-key-value-pres .ruleset-panel-subtitle{font-size:.75rem}o3r-rule-key-value-pres .ruleset-panel-title-aside{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;min-width:fit-content}o3r-rule-key-value-pres .ruleset-panel-category-title{font-size:.95rem;background:#eee;padding:.5rem;margin-bottom:.5rem;margin-top:1rem}o3r-rule-key-value-pres .rule-description .ruleset-panel-category-title{font-size:.893rem;cursor:default}o3r-rule-key-value-pres .rule-description .ruleset-panel-title{font-size:.94rem}o3r-rule-key-value-pres .rule-description .ruleset-panel-category-body{padding-bottom:.5rem;padding-left:1.5rem}o3r-rule-key-value-pres .rule-description .ruleset-panel-category-body:empty{margin:0;padding:0 0 0 1.5rem}o3r-rule-key-value-pres .limit-characters{display:inline-block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;max-width:38rem;vertical-align:bottom}o3r-rule-key-value-pres .input-value{margin-top:0;margin-bottom:0}o3r-rule-key-value-pres button{background:none;border:0;appearance:none}o3r-rule-key-value-pres .notification{position:absolute;padding:1rem 1.5rem;border-radius:5px;background:#444;color:#eee;right:0;z-index:1}\n"] }]
|
|
65
98
|
}], propDecorators: { key: [{
|
|
66
99
|
type: Input
|
|
67
100
|
}], value: [{
|
|
@@ -74,12 +107,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
74
107
|
|
|
75
108
|
class O3rFallbackToPipe {
|
|
76
109
|
transform(value, fallback = 'undefined') {
|
|
77
|
-
return value
|
|
110
|
+
return value === undefined ? fallback : value;
|
|
78
111
|
}
|
|
79
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
80
|
-
/** @nocollapse */ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.
|
|
112
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: O3rFallbackToPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
113
|
+
/** @nocollapse */ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: O3rFallbackToPipe, isStandalone: true, name: "o3rFallbackTo" }); }
|
|
81
114
|
}
|
|
82
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
115
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: O3rFallbackToPipe, decorators: [{
|
|
83
116
|
type: Pipe,
|
|
84
117
|
args: [{ name: 'o3rFallbackTo', standalone: true }]
|
|
85
118
|
}] });
|
|
@@ -87,10 +120,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
87
120
|
* @deprecated please use O3rFallbackToPipe, will be removed in v12.
|
|
88
121
|
*/
|
|
89
122
|
class FallbackToPipe extends O3rFallbackToPipe {
|
|
90
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
91
|
-
/** @nocollapse */ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.
|
|
123
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FallbackToPipe, deps: null, target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
124
|
+
/** @nocollapse */ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: FallbackToPipe, name: "fallbackTo" }); }
|
|
92
125
|
}
|
|
93
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
126
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FallbackToPipe, decorators: [{
|
|
94
127
|
type: Pipe,
|
|
95
128
|
args: [{ name: 'fallbackTo' }]
|
|
96
129
|
}] });
|
|
@@ -111,10 +144,10 @@ class RuleActionsPresComponent {
|
|
|
111
144
|
*/
|
|
112
145
|
this.runtimeOutputs = [];
|
|
113
146
|
}
|
|
114
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
115
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.
|
|
147
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleActionsPresComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
148
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RuleActionsPresComponent, selector: "o3r-rule-actions-pres", inputs: { actions: "actions", temporaryFacts: "temporaryFacts", runtimeOutputs: "runtimeOutputs" }, ngImport: i0, template: "<div class=\"ruleset-panel-category-title\">Output Actions</div>\n<div *ngIf=\"actions.length === 0 && runtimeOutputs.length === 0\" class=\"ruleset-panel-category-body empty\">\n No action\n</div>\n<ul class=\"ruleset-panel-category-body\">\n <li *ngFor=\"let action of actions\">\n <ng-container *ngIf=\"action.actionType\">\n <ng-container [ngSwitch]=\"action.actionType\">\n <div *ngSwitchCase=\"'SET_FACT'\">\n <div>Set Fact</div>\n <div>\n <o3r-rule-key-value-pres\n [key]=\"action.fact | o3rFallbackTo: 'Missing \\'fact\\''\"\n [value]=\"action.value | o3rFallbackTo\"\n [type]=\"'assignment'\"></o3r-rule-key-value-pres>\n </div>\n </div>\n <div *ngSwitchCase=\"'UPDATE_CONFIG'\">\n <div>Update Config {{action.component}} {{action.library}}</div>\n <div>\n <o3r-rule-key-value-pres\n [key]=\"action.property | o3rFallbackTo: 'Missing \\'property\\''\"\n [value]=\"action.value | o3rFallbackTo\"\n [type]=\"'assignment'\"></o3r-rule-key-value-pres>\n </div>\n </div>\n <div *ngSwitchCase=\"'UPDATE_ASSET'\">\n <div>Update Asset:</div>\n <div>\n <o3r-rule-key-value-pres\n [oldValue]=\"action.asset | o3rFallbackTo: 'Missing \\'asset\\''\"\n [value]=\"action.value | o3rFallbackTo\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </div>\n </div>\n <div *ngSwitchCase=\"'UPDATE_LOCALISATION'\">\n <div>Update localization:</div>\n <div>\n <o3r-rule-key-value-pres\n [oldValue]=\"action.key | o3rFallbackTo: 'Missing \\'key\\''\"\n [value]=\"action.value | o3rFallbackTo\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </div>\n </div>\n <div\n *ngSwitchCase=\"'UPDATE_PLACEHOLDER'\"\n [class.error]=\"!action.placeholderId\">\n <div>Update placeholder in {{action.component}} {{action.library}}</div>\n <div>\n <o3r-rule-key-value-pres\n [oldValue]=\"action.placeholderId | o3rFallbackTo: 'Missing \\'placeholderId\\''\"\n [value]=\"action.value\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </div>\n </div>\n <div *ngSwitchDefault class=\"error\">\n <div>Unrecognized action</div>\n <div>{{action | json}}</div>\n </div>\n </ng-container>\n </ng-container>\n </li>\n <li *ngFor=\"let runtimeOutput of runtimeOutputs\">\n <div>Set temporary fact</div>\n <div>\n <o3r-rule-key-value-pres\n [key]=\"runtimeOutput | o3rFallbackTo: 'Missing \\'fact\\''\"\n [value]=\"temporaryFacts[runtimeOutput] | o3rFallbackTo\"\n [type]=\"'assignment'\"></o3r-rule-key-value-pres>\n </div>\n </li>\n</ul>\n", styles: ["o3r-rule-actions-pres .ruleset-panel-title,o3r-rule-actions-pres .ruleset-panel-category-title{display:flex;justify-content:space-between;align-items:center}o3r-rule-actions-pres .ruleset-panel-title{font-size:1rem;padding:.5rem 0 .1rem}o3r-rule-actions-pres .ruleset-expansion-action,o3r-rule-actions-pres .icon-caret-down,o3r-rule-actions-pres .icon-caret-up{cursor:pointer}o3r-rule-actions-pres .ruleset-panel-subtitle{font-size:.75rem}o3r-rule-actions-pres .ruleset-panel-title-aside{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;min-width:fit-content}o3r-rule-actions-pres .ruleset-panel-category-title{font-size:.95rem;background:#eee;padding:.5rem;margin-bottom:.5rem;margin-top:1rem}o3r-rule-actions-pres .rule-description .ruleset-panel-category-title{font-size:.893rem;cursor:default}o3r-rule-actions-pres .rule-description .ruleset-panel-title{font-size:.94rem}o3r-rule-actions-pres .rule-description .ruleset-panel-category-body{padding-bottom:.5rem;padding-left:1.5rem}o3r-rule-actions-pres .rule-description .ruleset-panel-category-body:empty{margin:0;padding:0 0 0 1.5rem}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: RuleKeyValuePresComponent, selector: "o3r-rule-key-value-pres", inputs: ["key", "value", "oldValue", "type"] }, { kind: "pipe", type: O3rFallbackToPipe, name: "o3rFallbackTo" }, { kind: "pipe", type: i1.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
116
149
|
}
|
|
117
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
150
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleActionsPresComponent, decorators: [{
|
|
118
151
|
type: Component,
|
|
119
152
|
args: [{ selector: 'o3r-rule-actions-pres', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"ruleset-panel-category-title\">Output Actions</div>\n<div *ngIf=\"actions.length === 0 && runtimeOutputs.length === 0\" class=\"ruleset-panel-category-body empty\">\n No action\n</div>\n<ul class=\"ruleset-panel-category-body\">\n <li *ngFor=\"let action of actions\">\n <ng-container *ngIf=\"action.actionType\">\n <ng-container [ngSwitch]=\"action.actionType\">\n <div *ngSwitchCase=\"'SET_FACT'\">\n <div>Set Fact</div>\n <div>\n <o3r-rule-key-value-pres\n [key]=\"action.fact | o3rFallbackTo: 'Missing \\'fact\\''\"\n [value]=\"action.value | o3rFallbackTo\"\n [type]=\"'assignment'\"></o3r-rule-key-value-pres>\n </div>\n </div>\n <div *ngSwitchCase=\"'UPDATE_CONFIG'\">\n <div>Update Config {{action.component}} {{action.library}}</div>\n <div>\n <o3r-rule-key-value-pres\n [key]=\"action.property | o3rFallbackTo: 'Missing \\'property\\''\"\n [value]=\"action.value | o3rFallbackTo\"\n [type]=\"'assignment'\"></o3r-rule-key-value-pres>\n </div>\n </div>\n <div *ngSwitchCase=\"'UPDATE_ASSET'\">\n <div>Update Asset:</div>\n <div>\n <o3r-rule-key-value-pres\n [oldValue]=\"action.asset | o3rFallbackTo: 'Missing \\'asset\\''\"\n [value]=\"action.value | o3rFallbackTo\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </div>\n </div>\n <div *ngSwitchCase=\"'UPDATE_LOCALISATION'\">\n <div>Update localization:</div>\n <div>\n <o3r-rule-key-value-pres\n [oldValue]=\"action.key | o3rFallbackTo: 'Missing \\'key\\''\"\n [value]=\"action.value | o3rFallbackTo\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </div>\n </div>\n <div\n *ngSwitchCase=\"'UPDATE_PLACEHOLDER'\"\n [class.error]=\"!action.placeholderId\">\n <div>Update placeholder in {{action.component}} {{action.library}}</div>\n <div>\n <o3r-rule-key-value-pres\n [oldValue]=\"action.placeholderId | o3rFallbackTo: 'Missing \\'placeholderId\\''\"\n [value]=\"action.value\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </div>\n </div>\n <div *ngSwitchDefault class=\"error\">\n <div>Unrecognized action</div>\n <div>{{action | json}}</div>\n </div>\n </ng-container>\n </ng-container>\n </li>\n <li *ngFor=\"let runtimeOutput of runtimeOutputs\">\n <div>Set temporary fact</div>\n <div>\n <o3r-rule-key-value-pres\n [key]=\"runtimeOutput | o3rFallbackTo: 'Missing \\'fact\\''\"\n [value]=\"temporaryFacts[runtimeOutput] | o3rFallbackTo\"\n [type]=\"'assignment'\"></o3r-rule-key-value-pres>\n </div>\n </li>\n</ul>\n", styles: ["o3r-rule-actions-pres .ruleset-panel-title,o3r-rule-actions-pres .ruleset-panel-category-title{display:flex;justify-content:space-between;align-items:center}o3r-rule-actions-pres .ruleset-panel-title{font-size:1rem;padding:.5rem 0 .1rem}o3r-rule-actions-pres .ruleset-expansion-action,o3r-rule-actions-pres .icon-caret-down,o3r-rule-actions-pres .icon-caret-up{cursor:pointer}o3r-rule-actions-pres .ruleset-panel-subtitle{font-size:.75rem}o3r-rule-actions-pres .ruleset-panel-title-aside{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;min-width:fit-content}o3r-rule-actions-pres .ruleset-panel-category-title{font-size:.95rem;background:#eee;padding:.5rem;margin-bottom:.5rem;margin-top:1rem}o3r-rule-actions-pres .rule-description .ruleset-panel-category-title{font-size:.893rem;cursor:default}o3r-rule-actions-pres .rule-description .ruleset-panel-title{font-size:.94rem}o3r-rule-actions-pres .rule-description .ruleset-panel-category-body{padding-bottom:.5rem;padding-left:1.5rem}o3r-rule-actions-pres .rule-description .ruleset-panel-category-body:empty{margin:0;padding:0 0 0 1.5rem}\n"] }]
|
|
120
153
|
}], propDecorators: { actions: [{
|
|
@@ -125,40 +158,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
125
158
|
type: Input
|
|
126
159
|
}] } });
|
|
127
160
|
|
|
128
|
-
class RuleConditionPresComponent {
|
|
129
|
-
constructor() {
|
|
130
|
-
/**
|
|
131
|
-
* Left hand operator as it will be displayed in the template.
|
|
132
|
-
* In the case of a fact with a json path, will resolve the whole fact path, else will only display the value
|
|
133
|
-
*/
|
|
134
|
-
this.lhs = 'undefined';
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Rule condition that will be flattened by the component setter
|
|
138
|
-
*/
|
|
139
|
-
set condition(condition) {
|
|
140
|
-
this._condition = condition;
|
|
141
|
-
this.lhs = condition?.lhs ? this.getOperandName(condition.lhs) : 'undefined';
|
|
142
|
-
this.rhs = condition?.rhs ? this.getOperandName(condition.rhs) : undefined;
|
|
143
|
-
}
|
|
144
|
-
get condition() {
|
|
145
|
-
return this._condition;
|
|
146
|
-
}
|
|
147
|
-
getOperandName(operand) {
|
|
148
|
-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
149
|
-
const value = `${operand.value ?? 'MISSING_VALUE'}`;
|
|
150
|
-
return operand.path ? operand.path.replace(/^[$]/, value) : value;
|
|
151
|
-
}
|
|
152
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: RuleConditionPresComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
153
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: RuleConditionPresComponent, selector: "o3r-rule-condition-pres", inputs: { condition: "condition" }, ngImport: i0, template: "<ng-container *ngIf=\"!condition; else displayConditions\">\n <span class=\"input-value\">true</span>\n</ng-container>\n<ng-template #displayConditions>\n <ng-container *ngIf=\"!$any(condition).all && !$any(condition).any && !$any(condition).not\">\n <span class=\"input-key\">{{ lhs }}</span> {{ $any(condition).operator }} <span class=\"input-value\" *ngIf=\"rhs !== undefined\">{{ rhs }}</span>\n </ng-container>\n <ng-container *ngIf=\"$any(condition).all || $any(condition).any || $any(condition).not\">\n <span *ngIf=\"$any(condition).all\">ALL</span>\n <span *ngIf=\"$any(condition).any\">ANY</span>\n <span *ngIf=\"$any(condition).not\">NOT</span>\n <span>(\n <ng-container *ngFor=\"let cond of $any(condition).all || $any(condition).any || [$any(condition).not]; let last = last;\">\n <o3r-rule-condition-pres [condition]=\"cond\"></o3r-rule-condition-pres>\n <span *ngIf=\"!last\">, </span>\n </ng-container>\n )</span>\n </ng-container>\n</ng-template>\n", styles: ["o3r-rule-condition-pres{word-break:break-word}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: RuleConditionPresComponent, selector: "o3r-rule-condition-pres", inputs: ["condition"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
154
|
-
}
|
|
155
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: RuleConditionPresComponent, decorators: [{
|
|
156
|
-
type: Component,
|
|
157
|
-
args: [{ selector: 'o3r-rule-condition-pres', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"!condition; else displayConditions\">\n <span class=\"input-value\">true</span>\n</ng-container>\n<ng-template #displayConditions>\n <ng-container *ngIf=\"!$any(condition).all && !$any(condition).any && !$any(condition).not\">\n <span class=\"input-key\">{{ lhs }}</span> {{ $any(condition).operator }} <span class=\"input-value\" *ngIf=\"rhs !== undefined\">{{ rhs }}</span>\n </ng-container>\n <ng-container *ngIf=\"$any(condition).all || $any(condition).any || $any(condition).not\">\n <span *ngIf=\"$any(condition).all\">ALL</span>\n <span *ngIf=\"$any(condition).any\">ANY</span>\n <span *ngIf=\"$any(condition).not\">NOT</span>\n <span>(\n <ng-container *ngFor=\"let cond of $any(condition).all || $any(condition).any || [$any(condition).not]; let last = last;\">\n <o3r-rule-condition-pres [condition]=\"cond\"></o3r-rule-condition-pres>\n <span *ngIf=\"!last\">, </span>\n </ng-container>\n )</span>\n </ng-container>\n</ng-template>\n", styles: ["o3r-rule-condition-pres{word-break:break-word}\n"] }]
|
|
158
|
-
}], propDecorators: { condition: [{
|
|
159
|
-
type: Input
|
|
160
|
-
}] } });
|
|
161
|
-
|
|
162
161
|
class RuleTreePresComponent {
|
|
163
162
|
constructor() {
|
|
164
163
|
/**
|
|
@@ -184,10 +183,10 @@ class RuleTreePresComponent {
|
|
|
184
183
|
*/
|
|
185
184
|
this.successActionsExpanded = false;
|
|
186
185
|
}
|
|
187
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
188
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.
|
|
186
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleTreePresComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
187
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RuleTreePresComponent, selector: "o3r-rule-tree-pres", inputs: { name: "name", blockType: "blockType", condition: "condition", successElements: "successElements", failureElements: "failureElements" }, ngImport: i0, template: "<span *ngIf=\"name\">{{name | titlecase}}:</span>\n<div class=\"rule-wrapper tree\">\n <ng-container *ngIf=\"blockType === 'IF_ELSE'; else noCondition\">\n <div class=\"tree-root\" *ngIf=\"!name\" [attr.aria-hidden]=\"true\">\n <div></div>\n <div></div>\n </div>\n <div class=\"rule-conditions\">\n <div class=\"rule-conditions-title\">If\n <o3r-rule-condition-pres [condition]=\"condition\"></o3r-rule-condition-pres>\n </div>\n <div class=\"tree-root\" [attr.aria-hidden]=\"true\">\n <div></div>\n <div></div>\n </div>\n </div>\n <div class=\"rule-actions-wrapper tree-node\">\n <div class=\"rule-actions tree-branch\">\n <div class=\"tree-leaf\" [attr.aria-hidden]=\"true\">\n <div></div>\n <div></div>\n </div>\n <div class=\"rule-action-title success-actions\"\n tabindex=\"0\"\n (click)=\"successActionsExpanded = !successActionsExpanded\"\n (keyup.enter)=\"successActionsExpanded = !successActionsExpanded\">\n <i class=\"icon refx-icon-validate\"></i>\n <span>Then</span>\n <i class=\"icon\"\n [class.icon-caret-down]=\"!successActionsExpanded\"\n [class.icon-caret-up]=\"successActionsExpanded\">\n </i>\n </div>\n <o3r-rule-actions-pres class=\"rule-tree-actions\" *ngIf=\"successActionsExpanded\"\n [actions]=\"successElements\">\n </o3r-rule-actions-pres>\n <ng-container [ngTemplateOutlet]=\"subTree\" [ngTemplateOutletContext]=\"{blocks: successElements}\"></ng-container>\n </div>\n <div class=\"rule-actions tree-branch\">\n <div class=\"tree-leaf\" [attr.aria-hidden]=\"true\">\n <div></div>\n <div></div>\n </div>\n <div class=\"rule-action-title error-actions\"\n tabindex=\"0\"\n (click)=\"failureActionsExpanded = !failureActionsExpanded\"\n (keyup.enter)=\"failureActionsExpanded = !failureActionsExpanded\">\n <i class=\"icon refx-icon-cross\"></i>\n <span>Else</span>\n <i class=\"icon\"\n [class.icon-caret-down]=\"!failureActionsExpanded\"\n [class.icon-caret-up]=\"failureActionsExpanded\">\n </i>\n </div>\n <o3r-rule-actions-pres class=\"rule-tree-actions\"\n *ngIf=\"failureActionsExpanded\"\n [actions]=\"failureElements\">\n </o3r-rule-actions-pres>\n <ng-container [ngTemplateOutlet]=\"subTree\" [ngTemplateOutletContext]=\"{blocks: failureElements}\"></ng-container>\n </div>\n </div>\n </ng-container>\n</div>\n<ng-template #noCondition>\n <div class=\"rule-conditions\">\n <div class=\"rule-conditions-title\">If <span class=\"input-value\">true</span></div>\n <div class=\"tree-root\" [attr.aria-hidden]=\"true\">\n <div></div>\n <div></div>\n </div>\n </div>\n <div class=\"rule-actions-wrapper\">\n <div class=\"rule-actions\">\n <div class=\"rule-action-title success-actions\" tabindex=\"0\"\n (keyup.enter)=\"successActionsExpanded = !successActionsExpanded\"\n (click)=\"successActionsExpanded = !successActionsExpanded\">\n <i class=\"icon refx-icon-validate\">\n </i>\n <span>Then</span>\n <i class=\"icon\"\n [class.icon-caret-down]=\"!successActionsExpanded\"\n [class.icon-caret-up]=\"successActionsExpanded\">\n </i>\n </div>\n <o3r-rule-actions-pres class=\"rule-tree-actions\"\n *ngIf=\"successActionsExpanded\"\n [actions]=\"successElements\">\n </o3r-rule-actions-pres>\n <ng-container [ngTemplateOutlet]=\"subTree\" [ngTemplateOutletContext]=\"{blocks: successElements}\"></ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #subTree let-blocks=\"blocks\">\n <div class=\"rule-sub-trees\">\n <ng-container *ngFor=\"let block of blocks\">\n <div *ngIf=\"block.blockType === 'IF_ELSE'\" class=\"tree-branch\">\n <o3r-rule-tree-pres\n [blockType]=\"'IF_ELSE'\"\n [condition]=\"block.condition\"\n [failureElements]=\"block.failureElements\"\n [successElements]=\"block.successElements\"></o3r-rule-tree-pres>\n </div>\n </ng-container>\n </div>\n</ng-template>\n", styles: ["o3r-rule-tree-pres{display:block;padding-bottom:1rem}o3r-rule-tree-pres .rule-sub-trees{display:flex}o3r-rule-tree-pres .rule-conditions-title,o3r-rule-tree-pres .rule-action-title{text-align:center}o3r-rule-tree-pres .rule-conditions-title{border:1px solid #999999;background:#fff;color:#000;padding:.2rem}o3r-rule-tree-pres .rule-action-title{background:#fff;border-radius:0;border:1px solid #999999;cursor:pointer;display:flex;justify-content:center;align-items:center;gap:.5rem}o3r-rule-tree-pres .rule-tree-actions{display:block;padding:.5rem}o3r-rule-tree-pres .rule-actions:first-child>.rule-action-title{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}o3r-rule-tree-pres .rule-actions:last-child>.rule-action-title{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}o3r-rule-tree-pres .rule-actions-wrapper{display:flex}o3r-rule-tree-pres .rule-actions-wrapper .rule-actions{flex:1 1 100%}o3r-rule-tree-pres .success-actions{border-color:#16aa32}o3r-rule-tree-pres .success-actions.rule-action-title{background:#16aa32;color:#fff}o3r-rule-tree-pres .error-actions{border-color:#c02020}o3r-rule-tree-pres .error-actions.rule-action-title{background:#c02020;color:#fff}o3r-rule-tree-pres .tree .tree-leaf,o3r-rule-tree-pres .tree .tree-root{display:flex;width:100%}o3r-rule-tree-pres .tree .tree-leaf>div,o3r-rule-tree-pres .tree .tree-root>div{height:1rem;width:50%}o3r-rule-tree-pres .tree .tree-root div:first-child{border-right:1px dashed}o3r-rule-tree-pres .tree .tree-root{margin-top:.2rem}o3r-rule-tree-pres .tree .tree-node>.tree-branch:last-child>.tree-leaf>div:first-child{border-right:1px dashed;border-top:1px dashed;border-top-right-radius:.2rem}o3r-rule-tree-pres .tree .tree-node>.tree-branch:first-child>.tree-leaf>div:last-child{border-left:1px dashed;border-top:1px dashed;border-top-left-radius:.2rem}o3r-rule-tree-pres .icon{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: RuleConditionPresComponent, selector: "o3r-rule-condition-pres", inputs: ["condition"] }, { kind: "component", type: RuleTreePresComponent, selector: "o3r-rule-tree-pres", inputs: ["name", "blockType", "condition", "successElements", "failureElements"] }, { kind: "component", type: RuleActionsPresComponent, selector: "o3r-rule-actions-pres", inputs: ["actions", "temporaryFacts", "runtimeOutputs"] }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
189
188
|
}
|
|
190
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
189
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleTreePresComponent, decorators: [{
|
|
191
190
|
type: Component,
|
|
192
191
|
args: [{ selector: 'o3r-rule-tree-pres', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<span *ngIf=\"name\">{{name | titlecase}}:</span>\n<div class=\"rule-wrapper tree\">\n <ng-container *ngIf=\"blockType === 'IF_ELSE'; else noCondition\">\n <div class=\"tree-root\" *ngIf=\"!name\" [attr.aria-hidden]=\"true\">\n <div></div>\n <div></div>\n </div>\n <div class=\"rule-conditions\">\n <div class=\"rule-conditions-title\">If\n <o3r-rule-condition-pres [condition]=\"condition\"></o3r-rule-condition-pres>\n </div>\n <div class=\"tree-root\" [attr.aria-hidden]=\"true\">\n <div></div>\n <div></div>\n </div>\n </div>\n <div class=\"rule-actions-wrapper tree-node\">\n <div class=\"rule-actions tree-branch\">\n <div class=\"tree-leaf\" [attr.aria-hidden]=\"true\">\n <div></div>\n <div></div>\n </div>\n <div class=\"rule-action-title success-actions\"\n tabindex=\"0\"\n (click)=\"successActionsExpanded = !successActionsExpanded\"\n (keyup.enter)=\"successActionsExpanded = !successActionsExpanded\">\n <i class=\"icon refx-icon-validate\"></i>\n <span>Then</span>\n <i class=\"icon\"\n [class.icon-caret-down]=\"!successActionsExpanded\"\n [class.icon-caret-up]=\"successActionsExpanded\">\n </i>\n </div>\n <o3r-rule-actions-pres class=\"rule-tree-actions\" *ngIf=\"successActionsExpanded\"\n [actions]=\"successElements\">\n </o3r-rule-actions-pres>\n <ng-container [ngTemplateOutlet]=\"subTree\" [ngTemplateOutletContext]=\"{blocks: successElements}\"></ng-container>\n </div>\n <div class=\"rule-actions tree-branch\">\n <div class=\"tree-leaf\" [attr.aria-hidden]=\"true\">\n <div></div>\n <div></div>\n </div>\n <div class=\"rule-action-title error-actions\"\n tabindex=\"0\"\n (click)=\"failureActionsExpanded = !failureActionsExpanded\"\n (keyup.enter)=\"failureActionsExpanded = !failureActionsExpanded\">\n <i class=\"icon refx-icon-cross\"></i>\n <span>Else</span>\n <i class=\"icon\"\n [class.icon-caret-down]=\"!failureActionsExpanded\"\n [class.icon-caret-up]=\"failureActionsExpanded\">\n </i>\n </div>\n <o3r-rule-actions-pres class=\"rule-tree-actions\"\n *ngIf=\"failureActionsExpanded\"\n [actions]=\"failureElements\">\n </o3r-rule-actions-pres>\n <ng-container [ngTemplateOutlet]=\"subTree\" [ngTemplateOutletContext]=\"{blocks: failureElements}\"></ng-container>\n </div>\n </div>\n </ng-container>\n</div>\n<ng-template #noCondition>\n <div class=\"rule-conditions\">\n <div class=\"rule-conditions-title\">If <span class=\"input-value\">true</span></div>\n <div class=\"tree-root\" [attr.aria-hidden]=\"true\">\n <div></div>\n <div></div>\n </div>\n </div>\n <div class=\"rule-actions-wrapper\">\n <div class=\"rule-actions\">\n <div class=\"rule-action-title success-actions\" tabindex=\"0\"\n (keyup.enter)=\"successActionsExpanded = !successActionsExpanded\"\n (click)=\"successActionsExpanded = !successActionsExpanded\">\n <i class=\"icon refx-icon-validate\">\n </i>\n <span>Then</span>\n <i class=\"icon\"\n [class.icon-caret-down]=\"!successActionsExpanded\"\n [class.icon-caret-up]=\"successActionsExpanded\">\n </i>\n </div>\n <o3r-rule-actions-pres class=\"rule-tree-actions\"\n *ngIf=\"successActionsExpanded\"\n [actions]=\"successElements\">\n </o3r-rule-actions-pres>\n <ng-container [ngTemplateOutlet]=\"subTree\" [ngTemplateOutletContext]=\"{blocks: successElements}\"></ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #subTree let-blocks=\"blocks\">\n <div class=\"rule-sub-trees\">\n <ng-container *ngFor=\"let block of blocks\">\n <div *ngIf=\"block.blockType === 'IF_ELSE'\" class=\"tree-branch\">\n <o3r-rule-tree-pres\n [blockType]=\"'IF_ELSE'\"\n [condition]=\"block.condition\"\n [failureElements]=\"block.failureElements\"\n [successElements]=\"block.successElements\"></o3r-rule-tree-pres>\n </div>\n </ng-container>\n </div>\n</ng-template>\n", styles: ["o3r-rule-tree-pres{display:block;padding-bottom:1rem}o3r-rule-tree-pres .rule-sub-trees{display:flex}o3r-rule-tree-pres .rule-conditions-title,o3r-rule-tree-pres .rule-action-title{text-align:center}o3r-rule-tree-pres .rule-conditions-title{border:1px solid #999999;background:#fff;color:#000;padding:.2rem}o3r-rule-tree-pres .rule-action-title{background:#fff;border-radius:0;border:1px solid #999999;cursor:pointer;display:flex;justify-content:center;align-items:center;gap:.5rem}o3r-rule-tree-pres .rule-tree-actions{display:block;padding:.5rem}o3r-rule-tree-pres .rule-actions:first-child>.rule-action-title{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}o3r-rule-tree-pres .rule-actions:last-child>.rule-action-title{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}o3r-rule-tree-pres .rule-actions-wrapper{display:flex}o3r-rule-tree-pres .rule-actions-wrapper .rule-actions{flex:1 1 100%}o3r-rule-tree-pres .success-actions{border-color:#16aa32}o3r-rule-tree-pres .success-actions.rule-action-title{background:#16aa32;color:#fff}o3r-rule-tree-pres .error-actions{border-color:#c02020}o3r-rule-tree-pres .error-actions.rule-action-title{background:#c02020;color:#fff}o3r-rule-tree-pres .tree .tree-leaf,o3r-rule-tree-pres .tree .tree-root{display:flex;width:100%}o3r-rule-tree-pres .tree .tree-leaf>div,o3r-rule-tree-pres .tree .tree-root>div{height:1rem;width:50%}o3r-rule-tree-pres .tree .tree-root div:first-child{border-right:1px dashed}o3r-rule-tree-pres .tree .tree-root{margin-top:.2rem}o3r-rule-tree-pres .tree .tree-node>.tree-branch:last-child>.tree-leaf>div:first-child{border-right:1px dashed;border-top:1px dashed;border-top-right-radius:.2rem}o3r-rule-tree-pres .tree .tree-node>.tree-branch:first-child>.tree-leaf>div:last-child{border-left:1px dashed;border-top:1px dashed;border-top-left-radius:.2rem}o3r-rule-tree-pres .icon{cursor:pointer}\n"] }]
|
|
193
192
|
}], propDecorators: { name: [{
|
|
@@ -202,57 +201,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
202
201
|
type: Input
|
|
203
202
|
}] } });
|
|
204
203
|
|
|
205
|
-
/**
|
|
206
|
-
* Compute the status of the execution depending on its execution event type, the output and whether the execution
|
|
207
|
-
* is still active
|
|
208
|
-
* @param rulesetExecution
|
|
209
|
-
* @param isActive
|
|
210
|
-
*/
|
|
211
|
-
const getStatus = (rulesetExecution, isActive) => {
|
|
212
|
-
if (rulesetExecution.type === 'RulesetExecutionError') {
|
|
213
|
-
return 'Error';
|
|
214
|
-
}
|
|
215
|
-
else if (rulesetExecution.outputActions?.length === 0) {
|
|
216
|
-
return 'NoEffect';
|
|
217
|
-
}
|
|
218
|
-
else if (isActive) {
|
|
219
|
-
return 'Active';
|
|
220
|
-
}
|
|
221
|
-
return 'Deactivated';
|
|
222
|
-
};
|
|
223
|
-
/**
|
|
224
|
-
* Transform the output of the debug reports into the model for the ruleset history debug panel
|
|
225
|
-
* @param events
|
|
226
|
-
* @param rulesetMap
|
|
227
|
-
*/
|
|
228
|
-
const rulesetReportToHistory = (events, rulesetMap) => {
|
|
229
|
-
const availableRulesets = (events.filter(e => e.type === 'AvailableRulesets').reverse()[0])?.availableRulesets || [];
|
|
230
|
-
const lastActiveRulesets = (events.filter(e => e.type === 'ActiveRulesets').reverse()[0])?.rulesets || [];
|
|
231
|
-
return availableRulesets
|
|
232
|
-
.filter((ruleset) => !!ruleset)
|
|
233
|
-
.reduce((acc, ruleset) => {
|
|
234
|
-
const rulesetExecutions = events
|
|
235
|
-
.filter((e) => ((e.type === 'RulesetExecutionError' || e.type === 'RulesetExecution') && e.rulesetId === ruleset.id));
|
|
236
|
-
if (rulesetExecutions) {
|
|
237
|
-
acc.push(...rulesetExecutions);
|
|
238
|
-
}
|
|
239
|
-
return acc;
|
|
240
|
-
}, [])
|
|
241
|
-
.sort((execA, execB) => execB.timestamp - execA.timestamp)
|
|
242
|
-
.map((rulesetExecution) => {
|
|
243
|
-
const rulesetInformation = rulesetMap[rulesetExecution.rulesetId];
|
|
244
|
-
const isActive = lastActiveRulesets.find((r) => r.id === rulesetExecution.rulesetId);
|
|
245
|
-
return {
|
|
246
|
-
...rulesetExecution,
|
|
247
|
-
status: getStatus(rulesetExecution, !!isActive),
|
|
248
|
-
isActive: !!isActive,
|
|
249
|
-
rulesetInformation,
|
|
250
|
-
rulesEvaluations: (rulesetExecution.rulesEvaluations || []).sort((evalA, evalB) => (rulesetInformation?.rules.findIndex(r => r.id === evalA.rule.id) || -1) -
|
|
251
|
-
(rulesetInformation?.rules.findIndex(r => r.id === evalB.rule.id) || -1))
|
|
252
|
-
};
|
|
253
|
-
});
|
|
254
|
-
};
|
|
255
|
-
|
|
256
204
|
class O3rJsonOrStringPipe {
|
|
257
205
|
/**
|
|
258
206
|
* @inheritDoc
|
|
@@ -263,10 +211,10 @@ class O3rJsonOrStringPipe {
|
|
|
263
211
|
}
|
|
264
212
|
return JSON.stringify(value, null, 2);
|
|
265
213
|
}
|
|
266
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
267
|
-
/** @nocollapse */ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.
|
|
214
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: O3rJsonOrStringPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
215
|
+
/** @nocollapse */ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: O3rJsonOrStringPipe, isStandalone: true, name: "o3rJsonOrString" }); }
|
|
268
216
|
}
|
|
269
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
217
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: O3rJsonOrStringPipe, decorators: [{
|
|
270
218
|
type: Pipe,
|
|
271
219
|
args: [{
|
|
272
220
|
name: 'o3rJsonOrString',
|
|
@@ -296,32 +244,83 @@ class RulesetHistoryPresComponent {
|
|
|
296
244
|
* @param subpanel element to collapse. 'ruleset' will toggle the whole panel but won't reset the subpanels states.
|
|
297
245
|
*/
|
|
298
246
|
toggleExpansion(ruleId, subpanel) {
|
|
299
|
-
if (
|
|
300
|
-
this.expansionStatus[ruleId] =
|
|
247
|
+
if (this.expansionStatus[ruleId]) {
|
|
248
|
+
this.expansionStatus[ruleId][subpanel] = !this.expansionStatus[ruleId][subpanel];
|
|
301
249
|
}
|
|
302
250
|
else {
|
|
303
|
-
this.expansionStatus[ruleId]
|
|
251
|
+
this.expansionStatus[ruleId] = { [subpanel]: true };
|
|
304
252
|
}
|
|
305
253
|
this.cd.detectChanges();
|
|
306
254
|
}
|
|
307
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
308
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: RulesetHistoryPresComponent, selector: "o3r-ruleset-history-pres", inputs: { rulesetExecutions: "rulesetExecutions", executionDurationFormat: "executionDurationFormat" }, ngImport: i0, template: "<section>\n <h4 class=\"mb-4\">Ruleset Execution History</h4>\n <ng-template #noRulesEngine>\n <div class=\"alert alert-danger m-2\" role=\"alert\">\n The Rules Engine is not configured on this page.\n </div>\n </ng-template>\n <ul *ngIf=\"rulesetExecutions; else noRulesEngine\" class=\"rulesets\">\n <li *ngFor=\"let execution of rulesetExecutions\" class=\"ruleset\">\n <div class=\"ruleset-panel-title ruleset-expansion-action\"\n [class.error]=\"execution.type === 'RulesetExecutionError'\"\n (click)=\"toggleExpansion(execution.executionId, 'ruleset')\">\n <div><span [title]=\"'This ruleset has been evaluated ' + execution.executionCounter + ' time(s)'\">{{execution.executionCounter}}</span> - {{execution.rulesetName | titlecase }}\n <div class=\"ruleset-panel-subtitle\" *ngIf=\"execution.rulesetInformation?.linkedComponents?.or || execution.rulesetInformation?.linkedComponent\">\n <ng-container *ngFor=\"let lc of (execution.rulesetInformation?.linkedComponents?.or || [execution.rulesetInformation.linkedComponent]); last as isLast\">\n <div>{{lc.name}} {{lc.library}} <span *ngIf=\"!isLast\"> OR </span></div>\n </ng-container>\n </div>\n <div class=\"ruleset-panel-subtitle\" *ngIf=\"execution.rulesetInformation?.validityRange as validityRange\">\n Date range: {{validityRange.from}} - {{validityRange.to}}\n </div>\n </div>\n <div class=\"ruleset-panel-title-aside\">\n <span class=\"error capsule\" *ngIf=\"execution.status === 'Error'\">Error</span>\n <span class=\"success capsule\" *ngIf=\"execution.status === 'Active'\">Applied</span>\n <span class=\"inactive capsule\" *ngIf=\"execution.status === 'Deactivated'\">Deactivated</span>\n <span class=\"warn capsule\" *ngIf=\"execution.status === 'NoEffect'\">No effect</span>\n <span class=\"time capsule\">\n <span>{{execution.timestamp | date: 'HH:mm:ss SSS'}}</span>\n <span>({{execution.duration | number: executionDurationFormat}}ms)</span>\n </span>\n <button\n class=\"icon\"\n [class.icon-caret-down]=\"!expansionStatus[execution.executionId]?.ruleset\"\n [class.icon-caret-up]=\"expansionStatus[execution.executionId]?.ruleset\">\n </button>\n </div>\n </div>\n <div class=\"ruleset-panel-description\" *ngIf=\"expansionStatus[execution.executionId]?.ruleset\">\n <ng-container [ngTemplateOutlet]=\"rules\"\n [ngTemplateOutletContext]=\"{\n rules: execution.rulesetInformation.rules,\n expansionID: execution.executionId\n }\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"inputs\"\n [ngTemplateOutletContext]=\"{\n inputs: execution.inputFacts\n }\"></ng-container>\n <ng-container *ngIf=\"execution.type === 'RulesetExecutionError'; else success\">\n <div class=\"ruleset-panel-category-title\">Rules:</div>\n <ul class=\"ruleset-panel-category-body rule-description\">\n <li *ngFor=\"let ruleEvaluation of execution.rulesEvaluations; let index=index;\">\n <ng-container>\n <div class=\"ruleset-panel-title\" [class.error]=\"ruleEvaluation.error\">\n <span>{{ruleEvaluation.rule.name | titlecase}} </span>\n <span class=\"capsule error\" *ngIf=\"ruleEvaluation.error\">Error</span>\n </div>\n <div>\n <ng-container *ngIf=\"ruleEvaluation.error\">\n <span class=\"ruleset-panel-category-title\">Error:</span>\n <pre class=\"ruleset-panel-category-body error\">{{ruleEvaluation.error | o3rJsonOrString}}</pre>\n </ng-container>\n <ng-container [ngTemplateOutlet]=\"inputs\"\n [ngTemplateOutletContext]=\"{\n inputs: execution.inputFacts,\n runtimeInputs: execution.rulesetInformation?.rules[index]?.inputRuntimeFacts\n }\"></ng-container>\n <o3r-rule-actions-pres *ngIf=\"!ruleEvaluation.error\"\n [temporaryFacts]=\"ruleEvaluation.temporaryFacts\"\n [runtimeOutputs]=\"execution.rulesetInformation?.rules[index]?.outputRuntimeFacts\"\n ></o3r-rule-actions-pres>\n </div>\n </ng-container>\n </li>\n </ul>\n </ng-container>\n <ng-template #success>\n <o3r-rule-actions-pres [actions]=\"execution.outputActions\"></o3r-rule-actions-pres>\n <div class=\"ruleset-panel-category-title\">Executed Rules</div>\n <ul class=\"rule-description ruleset-panel-category-body\">\n <li *ngFor=\"let ruleEvaluation of execution.rulesEvaluations; let index=index;\">\n <div class=\"ruleset-panel-title\">\n <span>{{ruleEvaluation.rule.name | titlecase}}</span>\n <span class=\"capsule inactive\" *ngIf=\"ruleEvaluation.cached\">Cached</span>\n <span class=\"capsule\">({{ruleEvaluation.duration | number: executionDurationFormat}}ms)</span>\n </div>\n <div>\n <ng-container [ngTemplateOutlet]=\"triggers\"\n [ngTemplateOutletContext]=\"{triggers: (ruleEvaluation.triggers[ruleEvaluation.rule.id])}\"></ng-container>\n <o3r-rule-actions-pres\n [actions]=\"ruleEvaluation.outputActions\"\n [temporaryFacts]=\"ruleEvaluation.temporaryFacts\"\n [runtimeOutputs]=\"execution.rulesetInformation?.rules[index]?.outputRuntimeFacts\">\n </o3r-rule-actions-pres>\n </div>\n </li>\n </ul>\n </ng-template>\n </div>\n </li>\n </ul>\n</section>\n\n<ng-template let-triggers=\"triggers\" #triggers>\n <div class=\"ruleset-panel-category-title\">Basefacts Triggers</div>\n <ul class=\"ruleset-panel-category-body triggers\">\n <ng-container *ngFor=\"let trigger of (triggers | keyvalue)\">\n <li *ngIf=\"trigger.value?.factName\">\n <o3r-rule-key-value-pres\n [key]=\"trigger.value.factName\"\n [oldValue]=\"trigger.value.oldValue | o3rFallbackTo\"\n [value]=\"trigger.value.newValue | o3rFallbackTo\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </li>\n </ng-container>\n </ul>\n</ng-template>\n\n<ng-template let-rules=\"rules\" let-expansionID=\"expansionID\" #rules>\n <div class=\"ruleset-panel-category-title ruleset-expansion-action\"\n (click)=\"toggleExpansion(expansionID, 'rulesOverview')\">\n <span>Rules Overview</span>\n <button class=\"icon\"\n [class.icon-caret-down]=\"!expansionStatus[expansionID]?.rulesOverview\"\n [class.icon-caret-up]=\"expansionStatus[expansionID]?.rulesOverview\">\n </button>\n </div>\n <ng-container *ngIf=\"expansionStatus[expansionID]?.rulesOverview\">\n <div *ngIf=\"rules?.length === 0\" class=\"ruleset-panel-category-body empty\">No rule</div>\n <ul class=\"ruleset-panel-category-body\" *ngIf=\"rules?.length > 0\">\n <li *ngFor=\"let rule of rules\">\n <o3r-rule-tree-pres [name]=\"rule.name\"\n [condition]=\"rule?.rootElement?.condition\"\n [blockType]=\"rule?.rootElement?.blockType\"\n [successElements]=\"rule?.rootElement?.successElements\"\n [failureElements]=\"rule?.rootElement?.failureElements\">\n </o3r-rule-tree-pres>\n </li>\n </ul>\n </ng-container>\n</ng-template>\n\n<ng-template let-inputs=\"inputs\" let-runtimeInputs=\"runtimeInputs\" #inputs>\n <div class=\"ruleset-panel-category-title\">Inputs snapshot</div>\n <div *ngIf=\"inputs?.length === 0\" class=\"ruleset-panel-category-body empty\">No inputs</div>\n <ul class=\"ruleset-panel-category-body\" *ngIf=\"inputs?.length > 0\">\n <li *ngFor=\"let input of inputs\">\n <o3r-rule-key-value-pres\n [key]=\"input.factName\"\n [value]=\"input.value | o3rFallbackTo\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </li>\n <li *ngFor=\"let input of runtimeInputs\">{{input}} (scope limited to ruleset)</li>\n </ul>\n</ng-template>\n", styles: ["o3r-ruleset-history-pres .ruleset-panel-title,o3r-ruleset-history-pres .ruleset-panel-category-title{display:flex;justify-content:space-between;align-items:center}o3r-ruleset-history-pres .ruleset-panel-title{font-size:1rem;padding:.5rem 0 .1rem}o3r-ruleset-history-pres .ruleset-expansion-action,o3r-ruleset-history-pres .icon-caret-down,o3r-ruleset-history-pres .icon-caret-up{cursor:pointer}o3r-ruleset-history-pres .ruleset-panel-subtitle{font-size:.75rem}o3r-ruleset-history-pres .ruleset-panel-title-aside{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;min-width:fit-content}o3r-ruleset-history-pres .ruleset-panel-category-title{font-size:.95rem;background:#eee;padding:.5rem;margin-bottom:.5rem;margin-top:1rem}o3r-ruleset-history-pres .rule-description .ruleset-panel-category-title{font-size:.893rem;cursor:default}o3r-ruleset-history-pres .rule-description .ruleset-panel-title{font-size:.94rem}o3r-ruleset-history-pres .rule-description .ruleset-panel-category-body{padding-bottom:.5rem;padding-left:1.5rem}o3r-ruleset-history-pres .rule-description .ruleset-panel-category-body:empty{margin:0;padding:0 0 0 1.5rem}o3r-ruleset-history-pres .rulesets{margin:0;padding:0;list-style:none}o3r-ruleset-history-pres .rulesets ul{margin:0;padding-left:2rem}o3r-ruleset-history-pres .rulesets li.ruleset:nth-child(odd){background:#fbfbfb}o3r-ruleset-history-pres .ruleset-panel-category-body li{list-style:disc}o3r-ruleset-history-pres li:empty{display:none}o3r-ruleset-history-pres .ruleset{border-bottom:1px solid #dddddd}o3r-ruleset-history-pres .ruleset .ruleset-panel-description{padding:0 1rem 0 2rem;margin-bottom:2em}o3r-ruleset-history-pres .ruleset:first-child{border-top:1px solid #dddddd}o3r-ruleset-history-pres .ruleset-panel-title.ruleset-expansion-action{padding:.5rem 1rem}o3r-ruleset-history-pres .empty{font-style:italic;padding-left:1.5rem}o3r-ruleset-history-pres .ruleset-panel-category-body:empty.triggers:after{content:\"No trigger for this rule\";display:block;font-style:italic;padding-bottom:.5rem}o3r-ruleset-history-pres .ruleset-panel-title-aside{padding-left:1rem}o3r-ruleset-history-pres .rule-description .capsule{font-size:.8em;padding:.1rem .5rem;margin:0 .5rem}o3r-ruleset-history-pres .icon{background:none;border:none;font-size:1em}o3r-ruleset-history-pres .capsule{padding:.3rem;margin:.5rem;font-size:.875em;min-width:6rem;text-align:center}o3r-ruleset-history-pres .capsule.time{display:flex;flex-direction:column}o3r-ruleset-history-pres .success{background-color:#16aa32;color:#fff}o3r-ruleset-history-pres .inactive{background-color:#aaa;color:#fff}o3r-ruleset-history-pres .error{color:#c02020}o3r-ruleset-history-pres .error .capsule.error{background-color:#c02020;color:#fff}o3r-ruleset-history-pres .warn{background-color:#b92;color:#fff}o3r-ruleset-history-pres .input-key{color:#26c}o3r-ruleset-history-pres .input-value{color:#c29}o3r-ruleset-history-pres .input-key,o3r-ruleset-history-pres .input-value{font-family:monospace}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: RuleTreePresComponent, selector: "o3r-rule-tree-pres", inputs: ["name", "blockType", "condition", "successElements", "failureElements"] }, { kind: "component", type: RuleActionsPresComponent, selector: "o3r-rule-actions-pres", inputs: ["actions", "temporaryFacts", "runtimeOutputs"] }, { kind: "component", type: RuleKeyValuePresComponent, selector: "o3r-rule-key-value-pres", inputs: ["key", "value", "oldValue", "type"] }, { kind: "pipe", type: O3rFallbackToPipe, name: "o3rFallbackTo" }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i1.DatePipe, name: "date" }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: O3rJsonOrStringPipe, name: "o3rJsonOrString" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
255
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetHistoryPresComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
256
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RulesetHistoryPresComponent, selector: "o3r-ruleset-history-pres", inputs: { rulesetExecutions: "rulesetExecutions", executionDurationFormat: "executionDurationFormat" }, ngImport: i0, template: "<section>\n <h4 class=\"mb-4\">Ruleset Execution History</h4>\n <ng-template #noRulesEngine>\n <div class=\"alert alert-danger m-2\" role=\"alert\">\n The Rules Engine is not configured on this page.\n </div>\n </ng-template>\n <ul *ngIf=\"rulesetExecutions; else noRulesEngine\" class=\"rulesets\">\n <li *ngFor=\"let execution of rulesetExecutions\" class=\"ruleset\">\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -- need to refactor the div to accordion from DF #1518 -->\n <div class=\"ruleset-panel-title ruleset-expansion-action\"\n [class.error]=\"execution.type === 'RulesetExecutionError'\"\n (click)=\"toggleExpansion(execution.executionId, 'ruleset')\">\n <div><span [title]=\"'This ruleset has been evaluated ' + execution.executionCounter + ' time(s)'\">{{execution.executionCounter}}</span> - {{execution.rulesetName | titlecase }}\n <div class=\"ruleset-panel-subtitle\" *ngIf=\"execution.rulesetInformation?.linkedComponents?.or || execution.rulesetInformation?.linkedComponent\">\n <ng-container *ngFor=\"let lc of (execution.rulesetInformation?.linkedComponents?.or || [execution.rulesetInformation.linkedComponent]); last as isLast\">\n <div>{{lc.name}} {{lc.library}} <span *ngIf=\"!isLast\"> OR </span></div>\n </ng-container>\n </div>\n <div class=\"ruleset-panel-subtitle\" *ngIf=\"execution.rulesetInformation?.validityRange as validityRange\">\n Date range: {{validityRange.from}} - {{validityRange.to}}\n </div>\n </div>\n <div class=\"ruleset-panel-title-aside\">\n <span class=\"error capsule\" *ngIf=\"execution.status === 'Error'\">Error</span>\n <span class=\"success capsule\" *ngIf=\"execution.status === 'Active'\">Applied</span>\n <span class=\"inactive capsule\" *ngIf=\"execution.status === 'Deactivated'\">Deactivated</span>\n <span class=\"warn capsule\" *ngIf=\"execution.status === 'NoEffect'\">No effect</span>\n <span class=\"time capsule\">\n <span>{{execution.timestamp | date: 'HH:mm:ss SSS'}}</span>\n <span>({{execution.duration | number: executionDurationFormat}}ms)</span>\n </span>\n <button\n class=\"icon\"\n [class.icon-caret-down]=\"!expansionStatus[execution.executionId]?.ruleset\"\n [class.icon-caret-up]=\"expansionStatus[execution.executionId]?.ruleset\">\n </button>\n </div>\n </div>\n <div class=\"ruleset-panel-description\" *ngIf=\"expansionStatus[execution.executionId]?.ruleset\">\n <ng-container [ngTemplateOutlet]=\"rules\"\n [ngTemplateOutletContext]=\"{\n rules: execution.rulesetInformation.rules,\n expansionID: execution.executionId\n }\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"inputs\"\n [ngTemplateOutletContext]=\"{\n inputs: execution.inputFacts\n }\"></ng-container>\n <ng-container *ngIf=\"execution.type === 'RulesetExecutionError'; else success\">\n <div class=\"ruleset-panel-category-title\">Rules:</div>\n <ul class=\"ruleset-panel-category-body rule-description\">\n <li *ngFor=\"let ruleEvaluation of execution.rulesEvaluations; let index=index;\">\n <ng-container>\n <div class=\"ruleset-panel-title\" [class.error]=\"ruleEvaluation.error\">\n <span>{{ruleEvaluation.rule.name | titlecase}} </span>\n <span class=\"capsule error\" *ngIf=\"ruleEvaluation.error\">Error</span>\n </div>\n <div>\n <ng-container *ngIf=\"ruleEvaluation.error\">\n <span class=\"ruleset-panel-category-title\">Error:</span>\n <pre class=\"ruleset-panel-category-body error\">{{ruleEvaluation.error | o3rJsonOrString}}</pre>\n </ng-container>\n <ng-container [ngTemplateOutlet]=\"inputs\"\n [ngTemplateOutletContext]=\"{\n inputs: execution.inputFacts,\n runtimeInputs: execution.rulesetInformation?.rules[index]?.inputRuntimeFacts\n }\"></ng-container>\n <o3r-rule-actions-pres *ngIf=\"!ruleEvaluation.error\"\n [temporaryFacts]=\"ruleEvaluation.temporaryFacts\"\n [runtimeOutputs]=\"execution.rulesetInformation?.rules[index]?.outputRuntimeFacts\"\n ></o3r-rule-actions-pres>\n </div>\n </ng-container>\n </li>\n </ul>\n </ng-container>\n <ng-template #success>\n <o3r-rule-actions-pres [actions]=\"execution.outputActions\"></o3r-rule-actions-pres>\n <div class=\"ruleset-panel-category-title\">Executed Rules</div>\n <ul class=\"rule-description ruleset-panel-category-body\">\n <li *ngFor=\"let ruleEvaluation of execution.rulesEvaluations; let index=index;\">\n <div class=\"ruleset-panel-title\">\n <span>{{ruleEvaluation.rule.name | titlecase}}</span>\n <span class=\"capsule inactive\" *ngIf=\"ruleEvaluation.cached\">Cached</span>\n <span class=\"capsule\">({{ruleEvaluation.duration | number: executionDurationFormat}}ms)</span>\n </div>\n <div>\n <ng-container [ngTemplateOutlet]=\"triggers\"\n [ngTemplateOutletContext]=\"{triggers: (ruleEvaluation.triggers[ruleEvaluation.rule.id])}\"></ng-container>\n <o3r-rule-actions-pres\n [actions]=\"ruleEvaluation.outputActions\"\n [temporaryFacts]=\"ruleEvaluation.temporaryFacts\"\n [runtimeOutputs]=\"execution.rulesetInformation?.rules[index]?.outputRuntimeFacts\">\n </o3r-rule-actions-pres>\n </div>\n </li>\n </ul>\n </ng-template>\n </div>\n </li>\n </ul>\n</section>\n\n<ng-template let-triggers=\"triggers\" #triggers>\n <div class=\"ruleset-panel-category-title\">Basefacts Triggers</div>\n <ul class=\"ruleset-panel-category-body triggers\">\n <ng-container *ngFor=\"let trigger of (triggers | keyvalue)\">\n <li *ngIf=\"trigger.value?.factName\">\n <o3r-rule-key-value-pres\n [key]=\"trigger.value.factName\"\n [oldValue]=\"trigger.value.oldValue | o3rFallbackTo\"\n [value]=\"trigger.value.newValue | o3rFallbackTo\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </li>\n </ng-container>\n </ul>\n</ng-template>\n\n<ng-template let-rules=\"rules\" let-expansionID=\"expansionID\" #rules>\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -- need to refactor the div to accordion from DF #1518 -->\n <div class=\"ruleset-panel-category-title ruleset-expansion-action\"\n (click)=\"toggleExpansion(expansionID, 'rulesOverview')\">\n <span>Rules Overview</span>\n <button class=\"icon\"\n [class.icon-caret-down]=\"!expansionStatus[expansionID]?.rulesOverview\"\n [class.icon-caret-up]=\"expansionStatus[expansionID]?.rulesOverview\">\n </button>\n </div>\n <ng-container *ngIf=\"expansionStatus[expansionID]?.rulesOverview\">\n <div *ngIf=\"rules?.length === 0\" class=\"ruleset-panel-category-body empty\">No rule</div>\n <ul class=\"ruleset-panel-category-body\" *ngIf=\"rules?.length > 0\">\n <li *ngFor=\"let rule of rules\">\n <o3r-rule-tree-pres [name]=\"rule.name\"\n [condition]=\"rule?.rootElement?.condition\"\n [blockType]=\"rule?.rootElement?.blockType\"\n [successElements]=\"rule?.rootElement?.successElements\"\n [failureElements]=\"rule?.rootElement?.failureElements\">\n </o3r-rule-tree-pres>\n </li>\n </ul>\n </ng-container>\n</ng-template>\n\n<ng-template let-inputs=\"inputs\" let-runtimeInputs=\"runtimeInputs\" #inputs>\n <div class=\"ruleset-panel-category-title\">Inputs snapshot</div>\n <div *ngIf=\"inputs?.length === 0\" class=\"ruleset-panel-category-body empty\">No inputs</div>\n <ul class=\"ruleset-panel-category-body\" *ngIf=\"inputs?.length > 0\">\n <li *ngFor=\"let input of inputs\">\n <o3r-rule-key-value-pres\n [key]=\"input.factName\"\n [value]=\"input.value | o3rFallbackTo\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </li>\n <li *ngFor=\"let input of runtimeInputs\">{{input}} (scope limited to ruleset)</li>\n </ul>\n</ng-template>\n", styles: ["o3r-ruleset-history-pres .ruleset-panel-title,o3r-ruleset-history-pres .ruleset-panel-category-title{display:flex;justify-content:space-between;align-items:center}o3r-ruleset-history-pres .ruleset-panel-title{font-size:1rem;padding:.5rem 0 .1rem}o3r-ruleset-history-pres .ruleset-expansion-action,o3r-ruleset-history-pres .icon-caret-down,o3r-ruleset-history-pres .icon-caret-up{cursor:pointer}o3r-ruleset-history-pres .ruleset-panel-subtitle{font-size:.75rem}o3r-ruleset-history-pres .ruleset-panel-title-aside{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;min-width:fit-content}o3r-ruleset-history-pres .ruleset-panel-category-title{font-size:.95rem;background:#eee;padding:.5rem;margin-bottom:.5rem;margin-top:1rem}o3r-ruleset-history-pres .rule-description .ruleset-panel-category-title{font-size:.893rem;cursor:default}o3r-ruleset-history-pres .rule-description .ruleset-panel-title{font-size:.94rem}o3r-ruleset-history-pres .rule-description .ruleset-panel-category-body{padding-bottom:.5rem;padding-left:1.5rem}o3r-ruleset-history-pres .rule-description .ruleset-panel-category-body:empty{margin:0;padding:0 0 0 1.5rem}o3r-ruleset-history-pres .rulesets{margin:0;padding:0;list-style:none}o3r-ruleset-history-pres .rulesets ul{margin:0;padding-left:2rem}o3r-ruleset-history-pres .rulesets li.ruleset:nth-child(odd){background:#fbfbfb}o3r-ruleset-history-pres .ruleset-panel-category-body li{list-style:disc}o3r-ruleset-history-pres li:empty{display:none}o3r-ruleset-history-pres .ruleset{border-bottom:1px solid #dddddd}o3r-ruleset-history-pres .ruleset .ruleset-panel-description{padding:0 1rem 0 2rem;margin-bottom:2em}o3r-ruleset-history-pres .ruleset:first-child{border-top:1px solid #dddddd}o3r-ruleset-history-pres .ruleset-panel-title.ruleset-expansion-action{padding:.5rem 1rem}o3r-ruleset-history-pres .empty{font-style:italic;padding-left:1.5rem}o3r-ruleset-history-pres .ruleset-panel-category-body:empty.triggers:after{content:\"No trigger for this rule\";display:block;font-style:italic;padding-bottom:.5rem}o3r-ruleset-history-pres .ruleset-panel-title-aside{padding-left:1rem}o3r-ruleset-history-pres .rule-description .capsule{font-size:.8em;padding:.1rem .5rem;margin:0 .5rem}o3r-ruleset-history-pres .icon{background:none;border:none;font-size:1em}o3r-ruleset-history-pres .capsule{padding:.3rem;margin:.5rem;font-size:.875em;min-width:6rem;text-align:center}o3r-ruleset-history-pres .capsule.time{display:flex;flex-direction:column}o3r-ruleset-history-pres .success{background-color:#16aa32;color:#fff}o3r-ruleset-history-pres .inactive{background-color:#aaa;color:#fff}o3r-ruleset-history-pres .error{color:#c02020}o3r-ruleset-history-pres .error .capsule.error{background-color:#c02020;color:#fff}o3r-ruleset-history-pres .warn{background-color:#b92;color:#fff}o3r-ruleset-history-pres .input-key{color:#26c}o3r-ruleset-history-pres .input-value{color:#c29}o3r-ruleset-history-pres .input-key,o3r-ruleset-history-pres .input-value{font-family:monospace}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: RuleTreePresComponent, selector: "o3r-rule-tree-pres", inputs: ["name", "blockType", "condition", "successElements", "failureElements"] }, { kind: "component", type: RuleActionsPresComponent, selector: "o3r-rule-actions-pres", inputs: ["actions", "temporaryFacts", "runtimeOutputs"] }, { kind: "component", type: RuleKeyValuePresComponent, selector: "o3r-rule-key-value-pres", inputs: ["key", "value", "oldValue", "type"] }, { kind: "pipe", type: O3rFallbackToPipe, name: "o3rFallbackTo" }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i1.DatePipe, name: "date" }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: O3rJsonOrStringPipe, name: "o3rJsonOrString" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
309
257
|
}
|
|
310
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
258
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetHistoryPresComponent, decorators: [{
|
|
311
259
|
type: Component,
|
|
312
|
-
args: [{ selector: 'o3r-ruleset-history-pres', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<section>\n <h4 class=\"mb-4\">Ruleset Execution History</h4>\n <ng-template #noRulesEngine>\n <div class=\"alert alert-danger m-2\" role=\"alert\">\n The Rules Engine is not configured on this page.\n </div>\n </ng-template>\n <ul *ngIf=\"rulesetExecutions; else noRulesEngine\" class=\"rulesets\">\n <li *ngFor=\"let execution of rulesetExecutions\" class=\"ruleset\">\n <div class=\"ruleset-panel-title ruleset-expansion-action\"\n [class.error]=\"execution.type === 'RulesetExecutionError'\"\n (click)=\"toggleExpansion(execution.executionId, 'ruleset')\">\n <div><span [title]=\"'This ruleset has been evaluated ' + execution.executionCounter + ' time(s)'\">{{execution.executionCounter}}</span> - {{execution.rulesetName | titlecase }}\n <div class=\"ruleset-panel-subtitle\" *ngIf=\"execution.rulesetInformation?.linkedComponents?.or || execution.rulesetInformation?.linkedComponent\">\n <ng-container *ngFor=\"let lc of (execution.rulesetInformation?.linkedComponents?.or || [execution.rulesetInformation.linkedComponent]); last as isLast\">\n <div>{{lc.name}} {{lc.library}} <span *ngIf=\"!isLast\"> OR </span></div>\n </ng-container>\n </div>\n <div class=\"ruleset-panel-subtitle\" *ngIf=\"execution.rulesetInformation?.validityRange as validityRange\">\n Date range: {{validityRange.from}} - {{validityRange.to}}\n </div>\n </div>\n <div class=\"ruleset-panel-title-aside\">\n <span class=\"error capsule\" *ngIf=\"execution.status === 'Error'\">Error</span>\n <span class=\"success capsule\" *ngIf=\"execution.status === 'Active'\">Applied</span>\n <span class=\"inactive capsule\" *ngIf=\"execution.status === 'Deactivated'\">Deactivated</span>\n <span class=\"warn capsule\" *ngIf=\"execution.status === 'NoEffect'\">No effect</span>\n <span class=\"time capsule\">\n <span>{{execution.timestamp | date: 'HH:mm:ss SSS'}}</span>\n <span>({{execution.duration | number: executionDurationFormat}}ms)</span>\n </span>\n <button\n class=\"icon\"\n [class.icon-caret-down]=\"!expansionStatus[execution.executionId]?.ruleset\"\n [class.icon-caret-up]=\"expansionStatus[execution.executionId]?.ruleset\">\n </button>\n </div>\n </div>\n <div class=\"ruleset-panel-description\" *ngIf=\"expansionStatus[execution.executionId]?.ruleset\">\n <ng-container [ngTemplateOutlet]=\"rules\"\n [ngTemplateOutletContext]=\"{\n rules: execution.rulesetInformation.rules,\n expansionID: execution.executionId\n }\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"inputs\"\n [ngTemplateOutletContext]=\"{\n inputs: execution.inputFacts\n }\"></ng-container>\n <ng-container *ngIf=\"execution.type === 'RulesetExecutionError'; else success\">\n <div class=\"ruleset-panel-category-title\">Rules:</div>\n <ul class=\"ruleset-panel-category-body rule-description\">\n <li *ngFor=\"let ruleEvaluation of execution.rulesEvaluations; let index=index;\">\n <ng-container>\n <div class=\"ruleset-panel-title\" [class.error]=\"ruleEvaluation.error\">\n <span>{{ruleEvaluation.rule.name | titlecase}} </span>\n <span class=\"capsule error\" *ngIf=\"ruleEvaluation.error\">Error</span>\n </div>\n <div>\n <ng-container *ngIf=\"ruleEvaluation.error\">\n <span class=\"ruleset-panel-category-title\">Error:</span>\n <pre class=\"ruleset-panel-category-body error\">{{ruleEvaluation.error | o3rJsonOrString}}</pre>\n </ng-container>\n <ng-container [ngTemplateOutlet]=\"inputs\"\n [ngTemplateOutletContext]=\"{\n inputs: execution.inputFacts,\n runtimeInputs: execution.rulesetInformation?.rules[index]?.inputRuntimeFacts\n }\"></ng-container>\n <o3r-rule-actions-pres *ngIf=\"!ruleEvaluation.error\"\n [temporaryFacts]=\"ruleEvaluation.temporaryFacts\"\n [runtimeOutputs]=\"execution.rulesetInformation?.rules[index]?.outputRuntimeFacts\"\n ></o3r-rule-actions-pres>\n </div>\n </ng-container>\n </li>\n </ul>\n </ng-container>\n <ng-template #success>\n <o3r-rule-actions-pres [actions]=\"execution.outputActions\"></o3r-rule-actions-pres>\n <div class=\"ruleset-panel-category-title\">Executed Rules</div>\n <ul class=\"rule-description ruleset-panel-category-body\">\n <li *ngFor=\"let ruleEvaluation of execution.rulesEvaluations; let index=index;\">\n <div class=\"ruleset-panel-title\">\n <span>{{ruleEvaluation.rule.name | titlecase}}</span>\n <span class=\"capsule inactive\" *ngIf=\"ruleEvaluation.cached\">Cached</span>\n <span class=\"capsule\">({{ruleEvaluation.duration | number: executionDurationFormat}}ms)</span>\n </div>\n <div>\n <ng-container [ngTemplateOutlet]=\"triggers\"\n [ngTemplateOutletContext]=\"{triggers: (ruleEvaluation.triggers[ruleEvaluation.rule.id])}\"></ng-container>\n <o3r-rule-actions-pres\n [actions]=\"ruleEvaluation.outputActions\"\n [temporaryFacts]=\"ruleEvaluation.temporaryFacts\"\n [runtimeOutputs]=\"execution.rulesetInformation?.rules[index]?.outputRuntimeFacts\">\n </o3r-rule-actions-pres>\n </div>\n </li>\n </ul>\n </ng-template>\n </div>\n </li>\n </ul>\n</section>\n\n<ng-template let-triggers=\"triggers\" #triggers>\n <div class=\"ruleset-panel-category-title\">Basefacts Triggers</div>\n <ul class=\"ruleset-panel-category-body triggers\">\n <ng-container *ngFor=\"let trigger of (triggers | keyvalue)\">\n <li *ngIf=\"trigger.value?.factName\">\n <o3r-rule-key-value-pres\n [key]=\"trigger.value.factName\"\n [oldValue]=\"trigger.value.oldValue | o3rFallbackTo\"\n [value]=\"trigger.value.newValue | o3rFallbackTo\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </li>\n </ng-container>\n </ul>\n</ng-template>\n\n<ng-template let-rules=\"rules\" let-expansionID=\"expansionID\" #rules>\n <div class=\"ruleset-panel-category-title ruleset-expansion-action\"\n (click)=\"toggleExpansion(expansionID, 'rulesOverview')\">\n <span>Rules Overview</span>\n <button class=\"icon\"\n [class.icon-caret-down]=\"!expansionStatus[expansionID]?.rulesOverview\"\n [class.icon-caret-up]=\"expansionStatus[expansionID]?.rulesOverview\">\n </button>\n </div>\n <ng-container *ngIf=\"expansionStatus[expansionID]?.rulesOverview\">\n <div *ngIf=\"rules?.length === 0\" class=\"ruleset-panel-category-body empty\">No rule</div>\n <ul class=\"ruleset-panel-category-body\" *ngIf=\"rules?.length > 0\">\n <li *ngFor=\"let rule of rules\">\n <o3r-rule-tree-pres [name]=\"rule.name\"\n [condition]=\"rule?.rootElement?.condition\"\n [blockType]=\"rule?.rootElement?.blockType\"\n [successElements]=\"rule?.rootElement?.successElements\"\n [failureElements]=\"rule?.rootElement?.failureElements\">\n </o3r-rule-tree-pres>\n </li>\n </ul>\n </ng-container>\n</ng-template>\n\n<ng-template let-inputs=\"inputs\" let-runtimeInputs=\"runtimeInputs\" #inputs>\n <div class=\"ruleset-panel-category-title\">Inputs snapshot</div>\n <div *ngIf=\"inputs?.length === 0\" class=\"ruleset-panel-category-body empty\">No inputs</div>\n <ul class=\"ruleset-panel-category-body\" *ngIf=\"inputs?.length > 0\">\n <li *ngFor=\"let input of inputs\">\n <o3r-rule-key-value-pres\n [key]=\"input.factName\"\n [value]=\"input.value | o3rFallbackTo\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </li>\n <li *ngFor=\"let input of runtimeInputs\">{{input}} (scope limited to ruleset)</li>\n </ul>\n</ng-template>\n", styles: ["o3r-ruleset-history-pres .ruleset-panel-title,o3r-ruleset-history-pres .ruleset-panel-category-title{display:flex;justify-content:space-between;align-items:center}o3r-ruleset-history-pres .ruleset-panel-title{font-size:1rem;padding:.5rem 0 .1rem}o3r-ruleset-history-pres .ruleset-expansion-action,o3r-ruleset-history-pres .icon-caret-down,o3r-ruleset-history-pres .icon-caret-up{cursor:pointer}o3r-ruleset-history-pres .ruleset-panel-subtitle{font-size:.75rem}o3r-ruleset-history-pres .ruleset-panel-title-aside{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;min-width:fit-content}o3r-ruleset-history-pres .ruleset-panel-category-title{font-size:.95rem;background:#eee;padding:.5rem;margin-bottom:.5rem;margin-top:1rem}o3r-ruleset-history-pres .rule-description .ruleset-panel-category-title{font-size:.893rem;cursor:default}o3r-ruleset-history-pres .rule-description .ruleset-panel-title{font-size:.94rem}o3r-ruleset-history-pres .rule-description .ruleset-panel-category-body{padding-bottom:.5rem;padding-left:1.5rem}o3r-ruleset-history-pres .rule-description .ruleset-panel-category-body:empty{margin:0;padding:0 0 0 1.5rem}o3r-ruleset-history-pres .rulesets{margin:0;padding:0;list-style:none}o3r-ruleset-history-pres .rulesets ul{margin:0;padding-left:2rem}o3r-ruleset-history-pres .rulesets li.ruleset:nth-child(odd){background:#fbfbfb}o3r-ruleset-history-pres .ruleset-panel-category-body li{list-style:disc}o3r-ruleset-history-pres li:empty{display:none}o3r-ruleset-history-pres .ruleset{border-bottom:1px solid #dddddd}o3r-ruleset-history-pres .ruleset .ruleset-panel-description{padding:0 1rem 0 2rem;margin-bottom:2em}o3r-ruleset-history-pres .ruleset:first-child{border-top:1px solid #dddddd}o3r-ruleset-history-pres .ruleset-panel-title.ruleset-expansion-action{padding:.5rem 1rem}o3r-ruleset-history-pres .empty{font-style:italic;padding-left:1.5rem}o3r-ruleset-history-pres .ruleset-panel-category-body:empty.triggers:after{content:\"No trigger for this rule\";display:block;font-style:italic;padding-bottom:.5rem}o3r-ruleset-history-pres .ruleset-panel-title-aside{padding-left:1rem}o3r-ruleset-history-pres .rule-description .capsule{font-size:.8em;padding:.1rem .5rem;margin:0 .5rem}o3r-ruleset-history-pres .icon{background:none;border:none;font-size:1em}o3r-ruleset-history-pres .capsule{padding:.3rem;margin:.5rem;font-size:.875em;min-width:6rem;text-align:center}o3r-ruleset-history-pres .capsule.time{display:flex;flex-direction:column}o3r-ruleset-history-pres .success{background-color:#16aa32;color:#fff}o3r-ruleset-history-pres .inactive{background-color:#aaa;color:#fff}o3r-ruleset-history-pres .error{color:#c02020}o3r-ruleset-history-pres .error .capsule.error{background-color:#c02020;color:#fff}o3r-ruleset-history-pres .warn{background-color:#b92;color:#fff}o3r-ruleset-history-pres .input-key{color:#26c}o3r-ruleset-history-pres .input-value{color:#c29}o3r-ruleset-history-pres .input-key,o3r-ruleset-history-pres .input-value{font-family:monospace}\n"] }]
|
|
260
|
+
args: [{ selector: 'o3r-ruleset-history-pres', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<section>\n <h4 class=\"mb-4\">Ruleset Execution History</h4>\n <ng-template #noRulesEngine>\n <div class=\"alert alert-danger m-2\" role=\"alert\">\n The Rules Engine is not configured on this page.\n </div>\n </ng-template>\n <ul *ngIf=\"rulesetExecutions; else noRulesEngine\" class=\"rulesets\">\n <li *ngFor=\"let execution of rulesetExecutions\" class=\"ruleset\">\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -- need to refactor the div to accordion from DF #1518 -->\n <div class=\"ruleset-panel-title ruleset-expansion-action\"\n [class.error]=\"execution.type === 'RulesetExecutionError'\"\n (click)=\"toggleExpansion(execution.executionId, 'ruleset')\">\n <div><span [title]=\"'This ruleset has been evaluated ' + execution.executionCounter + ' time(s)'\">{{execution.executionCounter}}</span> - {{execution.rulesetName | titlecase }}\n <div class=\"ruleset-panel-subtitle\" *ngIf=\"execution.rulesetInformation?.linkedComponents?.or || execution.rulesetInformation?.linkedComponent\">\n <ng-container *ngFor=\"let lc of (execution.rulesetInformation?.linkedComponents?.or || [execution.rulesetInformation.linkedComponent]); last as isLast\">\n <div>{{lc.name}} {{lc.library}} <span *ngIf=\"!isLast\"> OR </span></div>\n </ng-container>\n </div>\n <div class=\"ruleset-panel-subtitle\" *ngIf=\"execution.rulesetInformation?.validityRange as validityRange\">\n Date range: {{validityRange.from}} - {{validityRange.to}}\n </div>\n </div>\n <div class=\"ruleset-panel-title-aside\">\n <span class=\"error capsule\" *ngIf=\"execution.status === 'Error'\">Error</span>\n <span class=\"success capsule\" *ngIf=\"execution.status === 'Active'\">Applied</span>\n <span class=\"inactive capsule\" *ngIf=\"execution.status === 'Deactivated'\">Deactivated</span>\n <span class=\"warn capsule\" *ngIf=\"execution.status === 'NoEffect'\">No effect</span>\n <span class=\"time capsule\">\n <span>{{execution.timestamp | date: 'HH:mm:ss SSS'}}</span>\n <span>({{execution.duration | number: executionDurationFormat}}ms)</span>\n </span>\n <button\n class=\"icon\"\n [class.icon-caret-down]=\"!expansionStatus[execution.executionId]?.ruleset\"\n [class.icon-caret-up]=\"expansionStatus[execution.executionId]?.ruleset\">\n </button>\n </div>\n </div>\n <div class=\"ruleset-panel-description\" *ngIf=\"expansionStatus[execution.executionId]?.ruleset\">\n <ng-container [ngTemplateOutlet]=\"rules\"\n [ngTemplateOutletContext]=\"{\n rules: execution.rulesetInformation.rules,\n expansionID: execution.executionId\n }\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"inputs\"\n [ngTemplateOutletContext]=\"{\n inputs: execution.inputFacts\n }\"></ng-container>\n <ng-container *ngIf=\"execution.type === 'RulesetExecutionError'; else success\">\n <div class=\"ruleset-panel-category-title\">Rules:</div>\n <ul class=\"ruleset-panel-category-body rule-description\">\n <li *ngFor=\"let ruleEvaluation of execution.rulesEvaluations; let index=index;\">\n <ng-container>\n <div class=\"ruleset-panel-title\" [class.error]=\"ruleEvaluation.error\">\n <span>{{ruleEvaluation.rule.name | titlecase}} </span>\n <span class=\"capsule error\" *ngIf=\"ruleEvaluation.error\">Error</span>\n </div>\n <div>\n <ng-container *ngIf=\"ruleEvaluation.error\">\n <span class=\"ruleset-panel-category-title\">Error:</span>\n <pre class=\"ruleset-panel-category-body error\">{{ruleEvaluation.error | o3rJsonOrString}}</pre>\n </ng-container>\n <ng-container [ngTemplateOutlet]=\"inputs\"\n [ngTemplateOutletContext]=\"{\n inputs: execution.inputFacts,\n runtimeInputs: execution.rulesetInformation?.rules[index]?.inputRuntimeFacts\n }\"></ng-container>\n <o3r-rule-actions-pres *ngIf=\"!ruleEvaluation.error\"\n [temporaryFacts]=\"ruleEvaluation.temporaryFacts\"\n [runtimeOutputs]=\"execution.rulesetInformation?.rules[index]?.outputRuntimeFacts\"\n ></o3r-rule-actions-pres>\n </div>\n </ng-container>\n </li>\n </ul>\n </ng-container>\n <ng-template #success>\n <o3r-rule-actions-pres [actions]=\"execution.outputActions\"></o3r-rule-actions-pres>\n <div class=\"ruleset-panel-category-title\">Executed Rules</div>\n <ul class=\"rule-description ruleset-panel-category-body\">\n <li *ngFor=\"let ruleEvaluation of execution.rulesEvaluations; let index=index;\">\n <div class=\"ruleset-panel-title\">\n <span>{{ruleEvaluation.rule.name | titlecase}}</span>\n <span class=\"capsule inactive\" *ngIf=\"ruleEvaluation.cached\">Cached</span>\n <span class=\"capsule\">({{ruleEvaluation.duration | number: executionDurationFormat}}ms)</span>\n </div>\n <div>\n <ng-container [ngTemplateOutlet]=\"triggers\"\n [ngTemplateOutletContext]=\"{triggers: (ruleEvaluation.triggers[ruleEvaluation.rule.id])}\"></ng-container>\n <o3r-rule-actions-pres\n [actions]=\"ruleEvaluation.outputActions\"\n [temporaryFacts]=\"ruleEvaluation.temporaryFacts\"\n [runtimeOutputs]=\"execution.rulesetInformation?.rules[index]?.outputRuntimeFacts\">\n </o3r-rule-actions-pres>\n </div>\n </li>\n </ul>\n </ng-template>\n </div>\n </li>\n </ul>\n</section>\n\n<ng-template let-triggers=\"triggers\" #triggers>\n <div class=\"ruleset-panel-category-title\">Basefacts Triggers</div>\n <ul class=\"ruleset-panel-category-body triggers\">\n <ng-container *ngFor=\"let trigger of (triggers | keyvalue)\">\n <li *ngIf=\"trigger.value?.factName\">\n <o3r-rule-key-value-pres\n [key]=\"trigger.value.factName\"\n [oldValue]=\"trigger.value.oldValue | o3rFallbackTo\"\n [value]=\"trigger.value.newValue | o3rFallbackTo\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </li>\n </ng-container>\n </ul>\n</ng-template>\n\n<ng-template let-rules=\"rules\" let-expansionID=\"expansionID\" #rules>\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -- need to refactor the div to accordion from DF #1518 -->\n <div class=\"ruleset-panel-category-title ruleset-expansion-action\"\n (click)=\"toggleExpansion(expansionID, 'rulesOverview')\">\n <span>Rules Overview</span>\n <button class=\"icon\"\n [class.icon-caret-down]=\"!expansionStatus[expansionID]?.rulesOverview\"\n [class.icon-caret-up]=\"expansionStatus[expansionID]?.rulesOverview\">\n </button>\n </div>\n <ng-container *ngIf=\"expansionStatus[expansionID]?.rulesOverview\">\n <div *ngIf=\"rules?.length === 0\" class=\"ruleset-panel-category-body empty\">No rule</div>\n <ul class=\"ruleset-panel-category-body\" *ngIf=\"rules?.length > 0\">\n <li *ngFor=\"let rule of rules\">\n <o3r-rule-tree-pres [name]=\"rule.name\"\n [condition]=\"rule?.rootElement?.condition\"\n [blockType]=\"rule?.rootElement?.blockType\"\n [successElements]=\"rule?.rootElement?.successElements\"\n [failureElements]=\"rule?.rootElement?.failureElements\">\n </o3r-rule-tree-pres>\n </li>\n </ul>\n </ng-container>\n</ng-template>\n\n<ng-template let-inputs=\"inputs\" let-runtimeInputs=\"runtimeInputs\" #inputs>\n <div class=\"ruleset-panel-category-title\">Inputs snapshot</div>\n <div *ngIf=\"inputs?.length === 0\" class=\"ruleset-panel-category-body empty\">No inputs</div>\n <ul class=\"ruleset-panel-category-body\" *ngIf=\"inputs?.length > 0\">\n <li *ngFor=\"let input of inputs\">\n <o3r-rule-key-value-pres\n [key]=\"input.factName\"\n [value]=\"input.value | o3rFallbackTo\"\n [type]=\"'state'\"></o3r-rule-key-value-pres>\n </li>\n <li *ngFor=\"let input of runtimeInputs\">{{input}} (scope limited to ruleset)</li>\n </ul>\n</ng-template>\n", styles: ["o3r-ruleset-history-pres .ruleset-panel-title,o3r-ruleset-history-pres .ruleset-panel-category-title{display:flex;justify-content:space-between;align-items:center}o3r-ruleset-history-pres .ruleset-panel-title{font-size:1rem;padding:.5rem 0 .1rem}o3r-ruleset-history-pres .ruleset-expansion-action,o3r-ruleset-history-pres .icon-caret-down,o3r-ruleset-history-pres .icon-caret-up{cursor:pointer}o3r-ruleset-history-pres .ruleset-panel-subtitle{font-size:.75rem}o3r-ruleset-history-pres .ruleset-panel-title-aside{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;min-width:fit-content}o3r-ruleset-history-pres .ruleset-panel-category-title{font-size:.95rem;background:#eee;padding:.5rem;margin-bottom:.5rem;margin-top:1rem}o3r-ruleset-history-pres .rule-description .ruleset-panel-category-title{font-size:.893rem;cursor:default}o3r-ruleset-history-pres .rule-description .ruleset-panel-title{font-size:.94rem}o3r-ruleset-history-pres .rule-description .ruleset-panel-category-body{padding-bottom:.5rem;padding-left:1.5rem}o3r-ruleset-history-pres .rule-description .ruleset-panel-category-body:empty{margin:0;padding:0 0 0 1.5rem}o3r-ruleset-history-pres .rulesets{margin:0;padding:0;list-style:none}o3r-ruleset-history-pres .rulesets ul{margin:0;padding-left:2rem}o3r-ruleset-history-pres .rulesets li.ruleset:nth-child(odd){background:#fbfbfb}o3r-ruleset-history-pres .ruleset-panel-category-body li{list-style:disc}o3r-ruleset-history-pres li:empty{display:none}o3r-ruleset-history-pres .ruleset{border-bottom:1px solid #dddddd}o3r-ruleset-history-pres .ruleset .ruleset-panel-description{padding:0 1rem 0 2rem;margin-bottom:2em}o3r-ruleset-history-pres .ruleset:first-child{border-top:1px solid #dddddd}o3r-ruleset-history-pres .ruleset-panel-title.ruleset-expansion-action{padding:.5rem 1rem}o3r-ruleset-history-pres .empty{font-style:italic;padding-left:1.5rem}o3r-ruleset-history-pres .ruleset-panel-category-body:empty.triggers:after{content:\"No trigger for this rule\";display:block;font-style:italic;padding-bottom:.5rem}o3r-ruleset-history-pres .ruleset-panel-title-aside{padding-left:1rem}o3r-ruleset-history-pres .rule-description .capsule{font-size:.8em;padding:.1rem .5rem;margin:0 .5rem}o3r-ruleset-history-pres .icon{background:none;border:none;font-size:1em}o3r-ruleset-history-pres .capsule{padding:.3rem;margin:.5rem;font-size:.875em;min-width:6rem;text-align:center}o3r-ruleset-history-pres .capsule.time{display:flex;flex-direction:column}o3r-ruleset-history-pres .success{background-color:#16aa32;color:#fff}o3r-ruleset-history-pres .inactive{background-color:#aaa;color:#fff}o3r-ruleset-history-pres .error{color:#c02020}o3r-ruleset-history-pres .error .capsule.error{background-color:#c02020;color:#fff}o3r-ruleset-history-pres .warn{background-color:#b92;color:#fff}o3r-ruleset-history-pres .input-key{color:#26c}o3r-ruleset-history-pres .input-value{color:#c29}o3r-ruleset-history-pres .input-key,o3r-ruleset-history-pres .input-value{font-family:monospace}\n"] }]
|
|
313
261
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { rulesetExecutions: [{
|
|
314
262
|
type: Input
|
|
315
263
|
}], executionDurationFormat: [{
|
|
316
264
|
type: Input
|
|
317
265
|
}] } });
|
|
318
266
|
|
|
267
|
+
/**
|
|
268
|
+
* Compute the status of the execution depending on its execution event type, the output and whether the execution
|
|
269
|
+
* is still active
|
|
270
|
+
* @param rulesetExecution
|
|
271
|
+
* @param isActive
|
|
272
|
+
*/
|
|
273
|
+
const getStatus = (rulesetExecution, isActive) => {
|
|
274
|
+
if (rulesetExecution.type === 'RulesetExecutionError') {
|
|
275
|
+
return 'Error';
|
|
276
|
+
}
|
|
277
|
+
else if (rulesetExecution.outputActions?.length === 0) {
|
|
278
|
+
return 'NoEffect';
|
|
279
|
+
}
|
|
280
|
+
else if (isActive) {
|
|
281
|
+
return 'Active';
|
|
282
|
+
}
|
|
283
|
+
return 'Deactivated';
|
|
284
|
+
};
|
|
285
|
+
/**
|
|
286
|
+
* Transform the output of the debug reports into the model for the ruleset history debug panel
|
|
287
|
+
* @param events
|
|
288
|
+
* @param rulesetMap
|
|
289
|
+
*/
|
|
290
|
+
const rulesetReportToHistory = (events, rulesetMap) => {
|
|
291
|
+
const availableRulesets = (events.filter((e) => e.type === 'AvailableRulesets').reverse()[0])?.availableRulesets || [];
|
|
292
|
+
const lastActiveRulesets = (events.filter((e) => e.type === 'ActiveRulesets').reverse()[0])?.rulesets || [];
|
|
293
|
+
return availableRulesets
|
|
294
|
+
.filter((ruleset) => !!ruleset)
|
|
295
|
+
.reduce((acc, ruleset) => {
|
|
296
|
+
const rulesetExecutions = events
|
|
297
|
+
.filter((e) => ((e.type === 'RulesetExecutionError' || e.type === 'RulesetExecution') && e.rulesetId === ruleset.id));
|
|
298
|
+
if (rulesetExecutions) {
|
|
299
|
+
acc.push(...rulesetExecutions);
|
|
300
|
+
}
|
|
301
|
+
return acc;
|
|
302
|
+
}, [])
|
|
303
|
+
.sort((execA, execB) => execB.timestamp - execA.timestamp)
|
|
304
|
+
.map((rulesetExecution) => {
|
|
305
|
+
const rulesetInformation = rulesetMap[rulesetExecution.rulesetId];
|
|
306
|
+
const isActive = lastActiveRulesets.find((r) => r.id === rulesetExecution.rulesetId);
|
|
307
|
+
return {
|
|
308
|
+
...rulesetExecution,
|
|
309
|
+
status: getStatus(rulesetExecution, !!isActive),
|
|
310
|
+
isActive: !!isActive,
|
|
311
|
+
rulesetInformation,
|
|
312
|
+
rulesEvaluations: (rulesetExecution.rulesEvaluations || []).sort((evalA, evalB) => (rulesetInformation?.rules.findIndex((r) => r.id === evalA.rule.id) || -1)
|
|
313
|
+
- (rulesetInformation?.rules.findIndex((r) => r.id === evalB.rule.id) || -1))
|
|
314
|
+
};
|
|
315
|
+
});
|
|
316
|
+
};
|
|
317
|
+
|
|
319
318
|
class RulesetHistoryPresModule {
|
|
320
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
321
|
-
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.
|
|
322
|
-
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.
|
|
319
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetHistoryPresModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
320
|
+
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: RulesetHistoryPresModule, declarations: [RulesetHistoryPresComponent, RuleConditionPresComponent, RuleTreePresComponent, RuleActionsPresComponent, RuleKeyValuePresComponent], imports: [O3rFallbackToPipe, CommonModule, CommonModule, CommonModule, JsonPipe, O3rJsonOrStringPipe], exports: [RulesetHistoryPresComponent] }); }
|
|
321
|
+
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetHistoryPresModule, imports: [CommonModule, CommonModule, CommonModule] }); }
|
|
323
322
|
}
|
|
324
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
323
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetHistoryPresModule, decorators: [{
|
|
325
324
|
type: NgModule,
|
|
326
325
|
args: [{
|
|
327
326
|
imports: [O3rFallbackToPipe, CommonModule, CommonModule, CommonModule, JsonPipe, O3rJsonOrStringPipe],
|
|
@@ -331,9 +330,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
331
330
|
}] });
|
|
332
331
|
|
|
333
332
|
const isRulesEngineMessage = (message) => {
|
|
334
|
-
return message && (message.dataType === 'rulesEngineEvents'
|
|
335
|
-
message.dataType === 'requestMessages'
|
|
336
|
-
message.dataType === 'connect');
|
|
333
|
+
return message && (message.dataType === 'rulesEngineEvents'
|
|
334
|
+
|| message.dataType === 'requestMessages'
|
|
335
|
+
|| message.dataType === 'connect');
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
/** Determine if the action should be executed */
|
|
339
|
+
const RULES_ENGINE_OPTIONS = new InjectionToken('Rules Engine Options');
|
|
340
|
+
/** Default Rules engine options */
|
|
341
|
+
const DEFAULT_RULES_ENGINE_OPTIONS = {
|
|
342
|
+
dryRun: false,
|
|
343
|
+
debug: false
|
|
337
344
|
};
|
|
338
345
|
|
|
339
346
|
/** StateDetailsActions */
|
|
@@ -391,10 +398,10 @@ class RulesetsEffect {
|
|
|
391
398
|
*/
|
|
392
399
|
this.upsertEntitiesFromApi$ = createEffect(() => this.actions$.pipe(ofType(upsertRulesetsEntitiesFromApi), mergeMap((payload) => from(payload.call).pipe(map((reply) => upsertRulesetsEntities({ entities: reply, requestId: payload.requestId })), catchError((err) => of(failRulesetsEntities({ error: err, requestId: payload.requestId })))))));
|
|
393
400
|
}
|
|
394
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
395
|
-
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.
|
|
401
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetsEffect, deps: [{ token: i1$1.Actions }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
402
|
+
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetsEffect }); }
|
|
396
403
|
}
|
|
397
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
404
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetsEffect, decorators: [{
|
|
398
405
|
type: Injectable
|
|
399
406
|
}], ctorParameters: () => [{ type: i1$1.Actions }] });
|
|
400
407
|
|
|
@@ -449,13 +456,13 @@ class RulesetsStoreModule {
|
|
|
449
456
|
]
|
|
450
457
|
};
|
|
451
458
|
}
|
|
452
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
453
|
-
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.
|
|
454
|
-
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.
|
|
459
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetsStoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
460
|
+
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: RulesetsStoreModule, imports: [i1$2.StoreFeatureModule, i1$1.EffectsFeatureModule] }); }
|
|
461
|
+
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetsStoreModule, providers: [
|
|
455
462
|
{ provide: RULESETS_REDUCER_TOKEN, useFactory: getDefaultRulesetsReducer }
|
|
456
463
|
], imports: [StoreModule.forFeature(RULESETS_STORE_NAME, RULESETS_REDUCER_TOKEN), EffectsModule.forFeature([RulesetsEffect])] }); }
|
|
457
464
|
}
|
|
458
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
465
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetsStoreModule, decorators: [{
|
|
459
466
|
type: NgModule,
|
|
460
467
|
args: [{
|
|
461
468
|
imports: [
|
|
@@ -484,18 +491,18 @@ const selectRulesetsStorePendingStatus = createSelector(selectRulesetsState, (st
|
|
|
484
491
|
* Check if the given value is a valid date
|
|
485
492
|
* @param d
|
|
486
493
|
*/
|
|
487
|
-
const isValidDate$1 = (d) => !isNaN(d) && d instanceof Date;
|
|
494
|
+
const isValidDate$1 = (d) => !Number.isNaN(d) && d instanceof Date;
|
|
488
495
|
/**
|
|
489
496
|
* Returns the rulesets which are in the validity range, if provided
|
|
490
497
|
*/
|
|
491
498
|
const selectRuleSetsInRange = createSelector(selectAllRulesets, (ruleSets) => ruleSets.filter((ruleSet) => {
|
|
492
499
|
const validity = ruleSet.validityRange;
|
|
493
|
-
if (!validity || !validity.from && !validity.to) {
|
|
500
|
+
if (!validity || (!validity.from && !validity.to)) {
|
|
494
501
|
return true;
|
|
495
502
|
}
|
|
496
503
|
const from = validity.from && new Date(validity.from);
|
|
497
504
|
const to = validity.to && new Date(validity.to);
|
|
498
|
-
if (to && !isValidDate$1(to) || from && !isValidDate$1(from)) {
|
|
505
|
+
if ((to && !isValidDate$1(to)) || (from && !isValidDate$1(from))) {
|
|
499
506
|
return false;
|
|
500
507
|
}
|
|
501
508
|
const time = Date.now();
|
|
@@ -548,7 +555,7 @@ const selectRuleSetLinkComponents = createSelector(selectRuleSetsInRange, (ruleS
|
|
|
548
555
|
return acc;
|
|
549
556
|
}
|
|
550
557
|
if (ruleSet.linkedComponents?.or?.length) {
|
|
551
|
-
ruleSet.linkedComponents.or.forEach(linkComp => {
|
|
558
|
+
ruleSet.linkedComponents.or.forEach((linkComp) => {
|
|
552
559
|
linkRulesetToComponent(linkComp.name, linkComp.library, ruleSet.id, acc);
|
|
553
560
|
});
|
|
554
561
|
return acc;
|
|
@@ -567,7 +574,7 @@ const selectComponentsLinkedToRuleset = createSelector(selectRuleSetsInRange, (r
|
|
|
567
574
|
return acc;
|
|
568
575
|
}
|
|
569
576
|
if (ruleSet.linkedComponents?.or?.length) {
|
|
570
|
-
ruleSet.linkedComponents.or.forEach(linkComp => {
|
|
577
|
+
ruleSet.linkedComponents.or.forEach((linkComp) => {
|
|
571
578
|
linkComponentToRuleset(linkComp.name, linkComp.library, ruleSet.id, acc.or);
|
|
572
579
|
});
|
|
573
580
|
return acc;
|
|
@@ -604,18 +611,15 @@ const rulesetsStorageSync = {
|
|
|
604
611
|
*/
|
|
605
612
|
function retrieveRulesetTriggers(currRes, prevRes) {
|
|
606
613
|
let rulesetTriggers = {};
|
|
607
|
-
const allCurrRulesetTriggersList = currRes.map(r => r.evaluation).filter((e) => !!e).map(e => e.triggers);
|
|
614
|
+
const allCurrRulesetTriggersList = currRes.map((r) => r.evaluation).filter((e) => !!e).map((e) => e.triggers);
|
|
608
615
|
const allCurrRulesetTriggers = {};
|
|
609
616
|
allCurrRulesetTriggersList.forEach((rTrig) => {
|
|
610
617
|
Object.keys(rTrig).forEach((ruleId) => {
|
|
611
618
|
allCurrRulesetTriggers[ruleId] = rTrig[ruleId];
|
|
612
619
|
});
|
|
613
620
|
});
|
|
614
|
-
if (
|
|
615
|
-
|
|
616
|
-
}
|
|
617
|
-
else {
|
|
618
|
-
const allPrevRulesetTriggersList = prevRes.map(r => r.evaluation).filter((e) => !!e).map(e => e.triggers);
|
|
621
|
+
if (prevRes) {
|
|
622
|
+
const allPrevRulesetTriggersList = prevRes.map((r) => r.evaluation).filter((e) => !!e).map((e) => e.triggers);
|
|
619
623
|
const allPrevRulesetTriggers = {};
|
|
620
624
|
allPrevRulesetTriggersList.forEach((rTrig) => {
|
|
621
625
|
Object.keys(rTrig).forEach((ruleId) => {
|
|
@@ -624,14 +628,17 @@ function retrieveRulesetTriggers(currRes, prevRes) {
|
|
|
624
628
|
});
|
|
625
629
|
Object.entries(allCurrRulesetTriggers).forEach(([ruleId, ruleTriggers]) => {
|
|
626
630
|
Object.keys(ruleTriggers).forEach((factName) => {
|
|
627
|
-
if (!allPrevRulesetTriggers[ruleId]
|
|
628
|
-
!allPrevRulesetTriggers[ruleId][factName]
|
|
629
|
-
ruleTriggers[factName].newValue !== allPrevRulesetTriggers[ruleId][factName].newValue) {
|
|
631
|
+
if (!allPrevRulesetTriggers[ruleId]
|
|
632
|
+
|| !allPrevRulesetTriggers[ruleId][factName]
|
|
633
|
+
|| ruleTriggers[factName].newValue !== allPrevRulesetTriggers[ruleId][factName].newValue) {
|
|
630
634
|
(rulesetTriggers[ruleId] ||= {})[factName] = ruleTriggers[factName];
|
|
631
635
|
}
|
|
632
636
|
});
|
|
633
637
|
});
|
|
634
638
|
}
|
|
639
|
+
else {
|
|
640
|
+
rulesetTriggers = allCurrRulesetTriggers;
|
|
641
|
+
}
|
|
635
642
|
return rulesetTriggers;
|
|
636
643
|
}
|
|
637
644
|
/**
|
|
@@ -643,7 +650,7 @@ function retrieveRulesetTriggers(currRes, prevRes) {
|
|
|
643
650
|
function flagCachedRules(rulesEvaluations, triggers) {
|
|
644
651
|
const rulesWhichTriggeredExecution = Object.keys(triggers);
|
|
645
652
|
return rulesEvaluations.map((e) => {
|
|
646
|
-
if (e && rulesWhichTriggeredExecution.
|
|
653
|
+
if (e && !rulesWhichTriggeredExecution.includes(e.rule.id)) {
|
|
647
654
|
return { ...e, cached: true };
|
|
648
655
|
}
|
|
649
656
|
return { ...e };
|
|
@@ -709,8 +716,8 @@ class EngineDebugger {
|
|
|
709
716
|
let rulesetDuration = 0;
|
|
710
717
|
debugEvent.rulesEvaluations.forEach((rule) => {
|
|
711
718
|
const mark = `rules-engine:${this.registeredRuleEngine?.rulesEngineInstanceName || ''}:${debugEvent.rulesetName}:${rule.rule.name}`;
|
|
712
|
-
const measures = performanceMeasures.filter(m => m.name === mark);
|
|
713
|
-
const duration = measures
|
|
719
|
+
const measures = performanceMeasures.filter((m) => m.name === mark);
|
|
720
|
+
const duration = measures.at(-1)?.duration || 0;
|
|
714
721
|
rule.duration = duration;
|
|
715
722
|
rulesetDuration += duration;
|
|
716
723
|
});
|
|
@@ -724,12 +731,12 @@ class EngineDebugger {
|
|
|
724
731
|
}), share());
|
|
725
732
|
}
|
|
726
733
|
initializePerformanceObserver() {
|
|
727
|
-
this.performanceMeasures$ = new Observable(subscriber => {
|
|
734
|
+
this.performanceMeasures$ = new Observable((subscriber) => {
|
|
728
735
|
const performanceObserver = new PerformanceObserver((list) => {
|
|
729
736
|
subscriber.next(list.getEntries());
|
|
730
737
|
});
|
|
731
738
|
performanceObserver.observe({ entryTypes: ['measure'] });
|
|
732
|
-
return performanceObserver.disconnect;
|
|
739
|
+
return performanceObserver.disconnect();
|
|
733
740
|
}).pipe(startWith([]), shareReplay(1));
|
|
734
741
|
}
|
|
735
742
|
async createBaseExecutionOutputObject(ruleset, executionCounter, rulesetInputFacts, runtimeFactValues, rulesetTriggers, rulesExecutions) {
|
|
@@ -758,12 +765,12 @@ class EngineDebugger {
|
|
|
758
765
|
}
|
|
759
766
|
async rulesetExecutionError(timestamp, ruleset, rulesetInputFacts, executionCounter, runtimeFactValues, rulesetTriggers, rulesExecutions) {
|
|
760
767
|
const baseRulesetOutputExecution = await this.createBaseExecutionOutputObject(ruleset, executionCounter, rulesetInputFacts, runtimeFactValues, rulesetTriggers, rulesExecutions);
|
|
761
|
-
const rulesExecWithErrors = rulesExecutions.filter(ex => !!ex && !!ex.error);
|
|
768
|
+
const rulesExecWithErrors = rulesExecutions.filter((ex) => !!ex && !!ex.error);
|
|
762
769
|
const rulesetOutputExecutionSkip = {
|
|
763
770
|
timestamp,
|
|
764
771
|
type: 'RulesetExecutionError',
|
|
765
|
-
rulesCausingTheError: rulesExecWithErrors.map(e => e.rule) || [],
|
|
766
|
-
errors: rulesExecWithErrors.map(e => e.error),
|
|
772
|
+
rulesCausingTheError: rulesExecWithErrors.map((e) => e.rule) || [],
|
|
773
|
+
errors: rulesExecWithErrors.map((e) => e.error),
|
|
767
774
|
...baseRulesetOutputExecution
|
|
768
775
|
};
|
|
769
776
|
return rulesetOutputExecutionSkip;
|
|
@@ -787,7 +794,7 @@ class EngineDebugger {
|
|
|
787
794
|
*/
|
|
788
795
|
handleDebugRulesetExecutionInfo(currRes, prevRes, allExecutionsValid, rulesetInputFacts, runtimeFactValues, executionCounter, ruleset) {
|
|
789
796
|
const rulesetTriggers = retrieveRulesetTriggers(currRes, prevRes);
|
|
790
|
-
const rulesetOutputExecution = currRes.map(r => r.evaluation);
|
|
797
|
+
const rulesetOutputExecution = currRes.map((r) => r.evaluation);
|
|
791
798
|
if (!allExecutionsValid) {
|
|
792
799
|
this.addRulesetExecutionErrorEvent(ruleset, rulesetInputFacts, executionCounter, runtimeFactValues, rulesetTriggers, rulesetOutputExecution);
|
|
793
800
|
}
|
|
@@ -819,13 +826,13 @@ class EngineDebugger {
|
|
|
819
826
|
activeRulesetsChange(ruleSetExecutorMap, restrictiveRuleSets) {
|
|
820
827
|
const timestamp = Date.now();
|
|
821
828
|
const rulesets = Object.keys(ruleSetExecutorMap).map((rulesetId) => ruleSetExecutorMap[rulesetId].engineRuleset);
|
|
822
|
-
const activeRulesets = restrictiveRuleSets
|
|
823
|
-
Object.values(rulesets).filter((ruleSet) => restrictiveRuleSets.
|
|
824
|
-
Object.values(rulesets);
|
|
829
|
+
const activeRulesets = restrictiveRuleSets
|
|
830
|
+
? Object.values(rulesets).filter((ruleSet) => restrictiveRuleSets.includes(ruleSet.id))
|
|
831
|
+
: Object.values(rulesets);
|
|
825
832
|
this.debugEventsSubject$.next(() => ({
|
|
826
833
|
timestamp,
|
|
827
834
|
type: 'ActiveRulesets',
|
|
828
|
-
rulesets: activeRulesets.map(a => ({ name: ruleSetExecutorMap[a.id].ruleset.name, id: ruleSetExecutorMap[a.id].ruleset.id }))
|
|
835
|
+
rulesets: activeRulesets.map((a) => ({ name: ruleSetExecutorMap[a.id].ruleset.name, id: ruleSetExecutorMap[a.id].ruleset.id }))
|
|
829
836
|
}));
|
|
830
837
|
}
|
|
831
838
|
/**
|
|
@@ -845,7 +852,6 @@ class EngineDebugger {
|
|
|
845
852
|
* @param runtimeFactValues
|
|
846
853
|
* @param rulesetTriggers
|
|
847
854
|
* @param rulesExecutions
|
|
848
|
-
* @param retrieveFactFunc
|
|
849
855
|
*/
|
|
850
856
|
addRulesetExecutionEvent(ruleset, executionCounter, rulesetInputFacts, allOutputActions, runtimeFactValues, rulesetTriggers, rulesExecutions) {
|
|
851
857
|
const timestamp = Date.now();
|
|
@@ -859,7 +865,6 @@ class EngineDebugger {
|
|
|
859
865
|
* @param runtimeFactValues
|
|
860
866
|
* @param rulesetTriggers
|
|
861
867
|
* @param rulesExecutions
|
|
862
|
-
* @param retrieveFactFunc
|
|
863
868
|
*/
|
|
864
869
|
addRulesetExecutionErrorEvent(ruleset, rulesetInputFacts, executionCounter, runtimeFactValues, rulesetTriggers, rulesExecutions) {
|
|
865
870
|
const timestamp = Date.now();
|
|
@@ -888,9 +893,9 @@ class EngineDebugger {
|
|
|
888
893
|
function filterRulesetsEventStream(restrictiveRuleSets) {
|
|
889
894
|
return (source$) => source$.pipe(switchMap((ruleSetExecutorMap) => {
|
|
890
895
|
const rulesets = Object.keys(ruleSetExecutorMap).map((rulesetId) => ruleSetExecutorMap[rulesetId].engineRuleset);
|
|
891
|
-
const activeRulesets = restrictiveRuleSets
|
|
892
|
-
Object.values(rulesets).filter((ruleSet) => restrictiveRuleSets.
|
|
893
|
-
Object.values(rulesets);
|
|
896
|
+
const activeRulesets = restrictiveRuleSets
|
|
897
|
+
? Object.values(rulesets).filter((ruleSet) => restrictiveRuleSets.includes(ruleSet.id))
|
|
898
|
+
: Object.values(rulesets);
|
|
894
899
|
return combineLatest(activeRulesets.map((ruleset) => ruleset.rulesResultsSubject$)).pipe(map((item) => item.reduce((acc, currentValue) => {
|
|
895
900
|
acc.push(...currentValue);
|
|
896
901
|
return acc;
|
|
@@ -934,19 +939,19 @@ function executeOperator(lhs, rhs, operator, operatorFacts) {
|
|
|
934
939
|
* @param operand value of one of the operands
|
|
935
940
|
*/
|
|
936
941
|
function numberValidator(operand) {
|
|
937
|
-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
938
|
-
return operand !== '' && !Array.isArray(operand) && !isNaN(+`${operand}`);
|
|
942
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions -- needed to convert any variable in a number (or NaN)
|
|
943
|
+
return operand !== '' && !Array.isArray(operand) && !Number.isNaN(+`${operand}`);
|
|
939
944
|
}
|
|
940
945
|
/**
|
|
941
946
|
* Validate an operand is a range of numbers
|
|
942
947
|
* @param operatorInput value of one of the operands
|
|
943
948
|
*/
|
|
944
949
|
function isRangeNumber(operatorInput) {
|
|
945
|
-
return Array.isArray(operatorInput)
|
|
946
|
-
operatorInput.length === 2
|
|
947
|
-
numberValidator(operatorInput[0])
|
|
948
|
-
numberValidator(operatorInput[1])
|
|
949
|
-
operatorInput[0] <= operatorInput[1];
|
|
950
|
+
return Array.isArray(operatorInput)
|
|
951
|
+
&& operatorInput.length === 2
|
|
952
|
+
&& numberValidator(operatorInput[0])
|
|
953
|
+
&& numberValidator(operatorInput[1])
|
|
954
|
+
&& operatorInput[0] <= operatorInput[1];
|
|
950
955
|
}
|
|
951
956
|
/**
|
|
952
957
|
* Verifies if the parameter is a valid date for the operator (getTime function available returning a number)
|
|
@@ -957,25 +962,25 @@ const isValidDate = (operatorInput) => {
|
|
|
957
962
|
return false;
|
|
958
963
|
}
|
|
959
964
|
const getTimeResult = operatorInput.getTime();
|
|
960
|
-
return typeof getTimeResult === 'number' && !isNaN(getTimeResult);
|
|
965
|
+
return typeof getTimeResult === 'number' && !Number.isNaN(getTimeResult);
|
|
961
966
|
};
|
|
962
967
|
/**
|
|
963
968
|
* Verifies if the parameter is a valid input for Date constructor (new Date returns a valid date)
|
|
964
969
|
* @param operatorInput
|
|
965
970
|
*/
|
|
966
971
|
const isValidDateInput = (operatorInput) => {
|
|
967
|
-
return operatorInput === 0 || !!operatorInput && isValidDate(new Date(operatorInput));
|
|
972
|
+
return operatorInput === 0 || (!!operatorInput && isValidDate(new Date(operatorInput)));
|
|
968
973
|
};
|
|
969
974
|
/**
|
|
970
975
|
* Verifies if the parameter is a valid date range
|
|
971
976
|
* @param operatorInput
|
|
972
977
|
*/
|
|
973
978
|
const isValidDateRange = (operatorInput) => {
|
|
974
|
-
return Array.isArray(operatorInput)
|
|
975
|
-
operatorInput.length === 2
|
|
976
|
-
isValidDateInput(operatorInput[0])
|
|
977
|
-
isValidDateInput(operatorInput[1])
|
|
978
|
-
new Date(operatorInput[0]) <= new Date(operatorInput[1]);
|
|
979
|
+
return Array.isArray(operatorInput)
|
|
980
|
+
&& operatorInput.length === 2
|
|
981
|
+
&& isValidDateInput(operatorInput[0])
|
|
982
|
+
&& isValidDateInput(operatorInput[1])
|
|
983
|
+
&& new Date(operatorInput[0]) <= new Date(operatorInput[1]);
|
|
979
984
|
};
|
|
980
985
|
/**
|
|
981
986
|
* Validate that a value is a supported simple type
|
|
@@ -993,8 +998,6 @@ function isString(value) {
|
|
|
993
998
|
}
|
|
994
999
|
/**
|
|
995
1000
|
* Parse input to return RegExp
|
|
996
|
-
* @param value value to test whether pattern exists (can be string or array of strings)
|
|
997
|
-
* @param inputString regexp pattern
|
|
998
1001
|
* @param inputRegExp
|
|
999
1002
|
*/
|
|
1000
1003
|
function parseRegExp(inputRegExp) {
|
|
@@ -1013,7 +1016,7 @@ function parseRegExp(inputRegExp) {
|
|
|
1013
1016
|
*/
|
|
1014
1017
|
const arrayContains = {
|
|
1015
1018
|
name: 'arrayContains',
|
|
1016
|
-
evaluator: (value, b) => value.
|
|
1019
|
+
evaluator: (value, b) => value.includes(b),
|
|
1017
1020
|
validateLhs: Array.isArray,
|
|
1018
1021
|
validateRhs: isSupportedSimpleTypes
|
|
1019
1022
|
};
|
|
@@ -1023,7 +1026,7 @@ const arrayContains = {
|
|
|
1023
1026
|
*/
|
|
1024
1027
|
const stringContains = {
|
|
1025
1028
|
name: 'stringContains',
|
|
1026
|
-
evaluator: (inputString, substring) => inputString.
|
|
1029
|
+
evaluator: (inputString, substring) => inputString.includes(substring),
|
|
1027
1030
|
validateLhs: isString,
|
|
1028
1031
|
validateRhs: isString
|
|
1029
1032
|
};
|
|
@@ -1033,7 +1036,7 @@ const stringContains = {
|
|
|
1033
1036
|
*/
|
|
1034
1037
|
const notArrayContains = {
|
|
1035
1038
|
name: 'notArrayContains',
|
|
1036
|
-
evaluator: (array, value) => array.
|
|
1039
|
+
evaluator: (array, value) => !array.includes(value),
|
|
1037
1040
|
validateLhs: Array.isArray,
|
|
1038
1041
|
validateRhs: isSupportedSimpleTypes
|
|
1039
1042
|
};
|
|
@@ -1043,7 +1046,7 @@ const notArrayContains = {
|
|
|
1043
1046
|
*/
|
|
1044
1047
|
const notStringContains = {
|
|
1045
1048
|
name: 'notStringContains',
|
|
1046
|
-
evaluator: (inputString, substring) => inputString.
|
|
1049
|
+
evaluator: (inputString, substring) => !inputString.includes(substring),
|
|
1047
1050
|
validateLhs: isString,
|
|
1048
1051
|
validateRhs: isString
|
|
1049
1052
|
};
|
|
@@ -1053,7 +1056,7 @@ const notStringContains = {
|
|
|
1053
1056
|
*/
|
|
1054
1057
|
const allEqual = {
|
|
1055
1058
|
name: 'allEqual',
|
|
1056
|
-
// eslint-disable-next-line eqeqeq
|
|
1059
|
+
// eslint-disable-next-line eqeqeq -- possibility of comparing string and number values
|
|
1057
1060
|
evaluator: (array, value) => array.every((elementValue) => elementValue == value),
|
|
1058
1061
|
validateLhs: Array.isArray,
|
|
1059
1062
|
validateRhs: isSupportedSimpleTypes
|
|
@@ -1074,7 +1077,7 @@ const allGreater = {
|
|
|
1074
1077
|
*/
|
|
1075
1078
|
const allIn = {
|
|
1076
1079
|
name: 'allIn',
|
|
1077
|
-
evaluator: (array, value) => array.every((elementValue) => value.
|
|
1080
|
+
evaluator: (array, value) => array.every((elementValue) => value.includes(elementValue)),
|
|
1078
1081
|
validateLhs: Array.isArray,
|
|
1079
1082
|
validateRhs: Array.isArray
|
|
1080
1083
|
};
|
|
@@ -1084,7 +1087,7 @@ const allIn = {
|
|
|
1084
1087
|
*/
|
|
1085
1088
|
const allNotIn = {
|
|
1086
1089
|
name: 'allNotIn',
|
|
1087
|
-
evaluator: (array, value) => !array.some((elementValue) => value.
|
|
1090
|
+
evaluator: (array, value) => !array.some((elementValue) => value.includes(elementValue)),
|
|
1088
1091
|
validateLhs: Array.isArray,
|
|
1089
1092
|
validateRhs: Array.isArray
|
|
1090
1093
|
};
|
|
@@ -1127,7 +1130,7 @@ const allRangeNumber = {
|
|
|
1127
1130
|
*/
|
|
1128
1131
|
const oneEquals = {
|
|
1129
1132
|
name: 'oneEquals',
|
|
1130
|
-
// eslint-disable-next-line eqeqeq
|
|
1133
|
+
// eslint-disable-next-line eqeqeq -- possibility of comparing string and number values
|
|
1131
1134
|
evaluator: (array, value) => array.some((elementValue) => elementValue == value),
|
|
1132
1135
|
validateLhs: Array.isArray,
|
|
1133
1136
|
validateRhs: isSupportedSimpleTypes
|
|
@@ -1148,7 +1151,7 @@ const oneGreater = {
|
|
|
1148
1151
|
*/
|
|
1149
1152
|
const oneIn = {
|
|
1150
1153
|
name: 'oneIn',
|
|
1151
|
-
evaluator: (firstArray, secondArray) => firstArray.some((elementValue) => secondArray.
|
|
1154
|
+
evaluator: (firstArray, secondArray) => firstArray.some((elementValue) => secondArray.includes(elementValue)),
|
|
1152
1155
|
validateLhs: Array.isArray,
|
|
1153
1156
|
validateRhs: Array.isArray
|
|
1154
1157
|
};
|
|
@@ -1278,7 +1281,7 @@ const arrayBasedOperators = [
|
|
|
1278
1281
|
*/
|
|
1279
1282
|
const equals = {
|
|
1280
1283
|
name: 'equals',
|
|
1281
|
-
// eslint-disable-next-line
|
|
1284
|
+
// eslint-disable-next-line eqeqeq -- possibility of comparing string and number values
|
|
1282
1285
|
evaluator: (firstValue, secondValue) => firstValue == secondValue
|
|
1283
1286
|
};
|
|
1284
1287
|
/**
|
|
@@ -1287,7 +1290,7 @@ const equals = {
|
|
|
1287
1290
|
*/
|
|
1288
1291
|
const notEquals = {
|
|
1289
1292
|
name: 'notEquals',
|
|
1290
|
-
// eslint-disable-next-line eqeqeq
|
|
1293
|
+
// eslint-disable-next-line eqeqeq -- possibility of comparing string and number values
|
|
1291
1294
|
evaluator: (firstValue, secondValue) => firstValue != secondValue
|
|
1292
1295
|
};
|
|
1293
1296
|
/**
|
|
@@ -1296,7 +1299,7 @@ const notEquals = {
|
|
|
1296
1299
|
*/
|
|
1297
1300
|
const inArray = {
|
|
1298
1301
|
name: 'inArray',
|
|
1299
|
-
evaluator: (value, array) => array.
|
|
1302
|
+
evaluator: (value, array) => array.includes(value),
|
|
1300
1303
|
validateLhs: isSupportedSimpleTypes,
|
|
1301
1304
|
validateRhs: Array.isArray
|
|
1302
1305
|
};
|
|
@@ -1306,7 +1309,7 @@ const inArray = {
|
|
|
1306
1309
|
*/
|
|
1307
1310
|
const notInArray = {
|
|
1308
1311
|
name: 'notInArray',
|
|
1309
|
-
evaluator: (value, array) => array.
|
|
1312
|
+
evaluator: (value, array) => !array.includes(value),
|
|
1310
1313
|
validateLhs: isSupportedSimpleTypes,
|
|
1311
1314
|
validateRhs: Array.isArray
|
|
1312
1315
|
};
|
|
@@ -1316,7 +1319,7 @@ const notInArray = {
|
|
|
1316
1319
|
*/
|
|
1317
1320
|
const inString = {
|
|
1318
1321
|
name: 'inString',
|
|
1319
|
-
evaluator: (value, inputString) => inputString.
|
|
1322
|
+
evaluator: (value, inputString) => inputString.includes(value),
|
|
1320
1323
|
validateLhs: isString,
|
|
1321
1324
|
validateRhs: isString
|
|
1322
1325
|
};
|
|
@@ -1326,7 +1329,7 @@ const inString = {
|
|
|
1326
1329
|
*/
|
|
1327
1330
|
const notInString = {
|
|
1328
1331
|
name: 'notInString',
|
|
1329
|
-
evaluator: (value, inputString) => inputString.
|
|
1332
|
+
evaluator: (value, inputString) => !inputString.includes(value),
|
|
1330
1333
|
validateLhs: isString,
|
|
1331
1334
|
validateRhs: isString
|
|
1332
1335
|
};
|
|
@@ -1364,49 +1367,6 @@ const basicOperators = [
|
|
|
1364
1367
|
equals, inArray, inString, isDefined, isUndefined, matchesPattern, notEquals, notInArray, notInString
|
|
1365
1368
|
];
|
|
1366
1369
|
|
|
1367
|
-
/**
|
|
1368
|
-
* Check if the number variable is greater or equal to a specific value
|
|
1369
|
-
* @title ≥
|
|
1370
|
-
*/
|
|
1371
|
-
const greaterThanOrEqual = {
|
|
1372
|
-
name: 'greaterThanOrEqual',
|
|
1373
|
-
evaluator: (firstNumber, secondNumber) => firstNumber >= secondNumber,
|
|
1374
|
-
validateLhs: numberValidator,
|
|
1375
|
-
validateRhs: numberValidator
|
|
1376
|
-
};
|
|
1377
|
-
/**
|
|
1378
|
-
* Check if the number variable is greater than a specific value
|
|
1379
|
-
* @title >
|
|
1380
|
-
*/
|
|
1381
|
-
const greaterThan = {
|
|
1382
|
-
name: 'greaterThan',
|
|
1383
|
-
evaluator: (firstNumber, secondNumber) => firstNumber > secondNumber,
|
|
1384
|
-
validateLhs: numberValidator,
|
|
1385
|
-
validateRhs: numberValidator
|
|
1386
|
-
};
|
|
1387
|
-
/**
|
|
1388
|
-
* Check if the number variable is lower or equal to a specific value
|
|
1389
|
-
* @title ≤
|
|
1390
|
-
*/
|
|
1391
|
-
const lessOrEqual = {
|
|
1392
|
-
name: 'lessOrEqual',
|
|
1393
|
-
evaluator: (firstNumber, secondNumber) => firstNumber <= secondNumber,
|
|
1394
|
-
validateLhs: numberValidator,
|
|
1395
|
-
validateRhs: numberValidator
|
|
1396
|
-
};
|
|
1397
|
-
/**
|
|
1398
|
-
* Check if the number variable is lower than a specific value
|
|
1399
|
-
* @title <
|
|
1400
|
-
*/
|
|
1401
|
-
const lessThan = {
|
|
1402
|
-
name: 'lessThan',
|
|
1403
|
-
evaluator: (firstNumber, secondNumber) => firstNumber < secondNumber,
|
|
1404
|
-
validateLhs: numberValidator,
|
|
1405
|
-
validateRhs: numberValidator
|
|
1406
|
-
};
|
|
1407
|
-
/** List of all default number based operators */
|
|
1408
|
-
const numberBasedOperators = [greaterThan, greaterThanOrEqual, lessThan, lessOrEqual];
|
|
1409
|
-
|
|
1410
1370
|
/**
|
|
1411
1371
|
* Check if a date variable is in a specified date range
|
|
1412
1372
|
* @title is between
|
|
@@ -1435,7 +1395,7 @@ const dateInNextMinutes = {
|
|
|
1435
1395
|
throw new Error('o3rCurrentTime value is not a number');
|
|
1436
1396
|
}
|
|
1437
1397
|
const currentTimeValue = operatorFactValues.o3rCurrentTime;
|
|
1438
|
-
return inRangeDate.evaluator(leftDateInput, [currentTimeValue, currentTimeValue + +minutes *
|
|
1398
|
+
return inRangeDate.evaluator(leftDateInput, [currentTimeValue, currentTimeValue + +minutes * 60_000]);
|
|
1439
1399
|
},
|
|
1440
1400
|
factImplicitDependencies: ['o3rCurrentTime'],
|
|
1441
1401
|
validateLhs: isValidDateInput,
|
|
@@ -1525,6 +1485,49 @@ const dateBasedOperators = [
|
|
|
1525
1485
|
inRangeDate, dateInNextMinutes, dateNotInNextMinutes, dateAfter, dateBefore, dateEquals, dateNotEquals
|
|
1526
1486
|
];
|
|
1527
1487
|
|
|
1488
|
+
/**
|
|
1489
|
+
* Check if the number variable is greater or equal to a specific value
|
|
1490
|
+
* @title ≥
|
|
1491
|
+
*/
|
|
1492
|
+
const greaterThanOrEqual = {
|
|
1493
|
+
name: 'greaterThanOrEqual',
|
|
1494
|
+
evaluator: (firstNumber, secondNumber) => firstNumber >= secondNumber,
|
|
1495
|
+
validateLhs: numberValidator,
|
|
1496
|
+
validateRhs: numberValidator
|
|
1497
|
+
};
|
|
1498
|
+
/**
|
|
1499
|
+
* Check if the number variable is greater than a specific value
|
|
1500
|
+
* @title >
|
|
1501
|
+
*/
|
|
1502
|
+
const greaterThan = {
|
|
1503
|
+
name: 'greaterThan',
|
|
1504
|
+
evaluator: (firstNumber, secondNumber) => firstNumber > secondNumber,
|
|
1505
|
+
validateLhs: numberValidator,
|
|
1506
|
+
validateRhs: numberValidator
|
|
1507
|
+
};
|
|
1508
|
+
/**
|
|
1509
|
+
* Check if the number variable is lower or equal to a specific value
|
|
1510
|
+
* @title ≤
|
|
1511
|
+
*/
|
|
1512
|
+
const lessOrEqual = {
|
|
1513
|
+
name: 'lessOrEqual',
|
|
1514
|
+
evaluator: (firstNumber, secondNumber) => firstNumber <= secondNumber,
|
|
1515
|
+
validateLhs: numberValidator,
|
|
1516
|
+
validateRhs: numberValidator
|
|
1517
|
+
};
|
|
1518
|
+
/**
|
|
1519
|
+
* Check if the number variable is lower than a specific value
|
|
1520
|
+
* @title <
|
|
1521
|
+
*/
|
|
1522
|
+
const lessThan = {
|
|
1523
|
+
name: 'lessThan',
|
|
1524
|
+
evaluator: (firstNumber, secondNumber) => firstNumber < secondNumber,
|
|
1525
|
+
validateLhs: numberValidator,
|
|
1526
|
+
validateRhs: numberValidator
|
|
1527
|
+
};
|
|
1528
|
+
/** List of all default number based operators */
|
|
1529
|
+
const numberBasedOperators = [greaterThan, greaterThanOrEqual, lessThan, lessOrEqual];
|
|
1530
|
+
|
|
1528
1531
|
const operatorList = [...arrayBasedOperators, ...basicOperators, ...numberBasedOperators, ...dateBasedOperators];
|
|
1529
1532
|
|
|
1530
1533
|
/**
|
|
@@ -1586,6 +1589,15 @@ class RulesetExecutor {
|
|
|
1586
1589
|
*/
|
|
1587
1590
|
constructor(ruleset, rulesEngine) {
|
|
1588
1591
|
this.executionCounter = 0;
|
|
1592
|
+
/**
|
|
1593
|
+
* Find rule input facts
|
|
1594
|
+
* @param obj
|
|
1595
|
+
*/
|
|
1596
|
+
this.findRuleInputFacts = (obj) => {
|
|
1597
|
+
const ruleInputFacts = new Set();
|
|
1598
|
+
this.collectRuleInputFacts(obj, ruleInputFacts);
|
|
1599
|
+
return Array.from(ruleInputFacts);
|
|
1600
|
+
};
|
|
1589
1601
|
this.ruleset = ruleset;
|
|
1590
1602
|
this.rulesEngine = rulesEngine;
|
|
1591
1603
|
this.operators = rulesEngine.operators;
|
|
@@ -1609,7 +1621,7 @@ class RulesetExecutor {
|
|
|
1609
1621
|
if ((key === 'operator') && isConditionProperties(currentObject)) {
|
|
1610
1622
|
const op = this.operators[currentObject[key]];
|
|
1611
1623
|
if (op && op.factImplicitDependencies) {
|
|
1612
|
-
op.factImplicitDependencies.forEach(dep => ruleInputFacts.add(dep));
|
|
1624
|
+
op.factImplicitDependencies.forEach((dep) => ruleInputFacts.add(dep));
|
|
1613
1625
|
}
|
|
1614
1626
|
}
|
|
1615
1627
|
else if (typeof currentObject[key] === 'object') {
|
|
@@ -1644,7 +1656,7 @@ class RulesetExecutor {
|
|
|
1644
1656
|
}
|
|
1645
1657
|
else if (isOperandFact(operand)) {
|
|
1646
1658
|
const factValue = factsValue[operand.value];
|
|
1647
|
-
// eslint-disable-next-line new-cap
|
|
1659
|
+
// eslint-disable-next-line new-cap -- convention for JSONPath
|
|
1648
1660
|
return operand.path ? factValue && JSONPath({ wrap: false, json: factValue, path: operand.path }) : factValue;
|
|
1649
1661
|
}
|
|
1650
1662
|
else if (isOperandLiteral(operand)) {
|
|
@@ -1671,9 +1683,9 @@ class RulesetExecutor {
|
|
|
1671
1683
|
* Recursively process a block to extract all the actions keeping the order
|
|
1672
1684
|
* Note that runtimeFactValues will be mutated by all the runtime facts actions executed
|
|
1673
1685
|
* @param element
|
|
1674
|
-
* @param actions
|
|
1675
1686
|
* @param factsValue
|
|
1676
1687
|
* @param runtimeFactValues This runtime fact map will be mutated by all the runtime facts actions executed
|
|
1688
|
+
* @param actions
|
|
1677
1689
|
* @protected
|
|
1678
1690
|
*/
|
|
1679
1691
|
evaluateBlock(element, factsValue, runtimeFactValues, actions = []) {
|
|
@@ -1735,7 +1747,7 @@ class RulesetExecutor {
|
|
|
1735
1747
|
}
|
|
1736
1748
|
if (nestedCondition.all || nestedCondition.any) {
|
|
1737
1749
|
const evaluate = (condition) => this.evaluateCondition(condition, factsValue, runtimeFactValues);
|
|
1738
|
-
return isAllConditions(nestedCondition) ? nestedCondition.all.every(evaluate) : nestedCondition.any.some(evaluate);
|
|
1750
|
+
return isAllConditions(nestedCondition) ? nestedCondition.all.every((element) => evaluate(element)) : nestedCondition.any.some((element) => evaluate(element));
|
|
1739
1751
|
}
|
|
1740
1752
|
throw new Error(`Unknown condition block met : ${JSON.stringify(nestedCondition)}`);
|
|
1741
1753
|
}
|
|
@@ -1744,22 +1756,17 @@ class RulesetExecutor {
|
|
|
1744
1756
|
*/
|
|
1745
1757
|
plugRuleset() {
|
|
1746
1758
|
const inputFactsForRule = {};
|
|
1747
|
-
|
|
1748
|
-
const ruleInputFacts = new Set();
|
|
1749
|
-
this.collectRuleInputFacts(obj, ruleInputFacts);
|
|
1750
|
-
return Array.from(ruleInputFacts);
|
|
1751
|
-
};
|
|
1752
|
-
this.ruleset.rules.forEach((rule) => inputFactsForRule[rule.id] = findRuleInputFacts(rule.rootElement));
|
|
1759
|
+
this.ruleset.rules.forEach((rule) => inputFactsForRule[rule.id] = this.findRuleInputFacts(rule.rootElement));
|
|
1753
1760
|
const factsThatRerunEverything = [];
|
|
1754
1761
|
this.ruleset.rules.forEach((rule) => {
|
|
1755
1762
|
if (rule.outputRuntimeFacts.length > 0 || rule.inputRuntimeFacts.length > 0) {
|
|
1756
1763
|
factsThatRerunEverything.push(...inputFactsForRule[rule.id]);
|
|
1757
1764
|
}
|
|
1758
|
-
else {
|
|
1759
|
-
}
|
|
1765
|
+
else { }
|
|
1760
1766
|
});
|
|
1761
|
-
const triggerFull$ = factsThatRerunEverything.length === 0
|
|
1762
|
-
|
|
1767
|
+
const triggerFull$ = factsThatRerunEverything.length === 0
|
|
1768
|
+
? of([])
|
|
1769
|
+
: combineLatest(factsThatRerunEverything.map((fact) => this.rulesEngine.retrieveOrCreateFactStream(fact)));
|
|
1763
1770
|
const result$ = triggerFull$.pipe(switchMap(() => {
|
|
1764
1771
|
const runtimeFactValues = {};
|
|
1765
1772
|
let rulesetInputFacts;
|
|
@@ -1772,7 +1779,7 @@ class RulesetExecutor {
|
|
|
1772
1779
|
return combineLatest(this.ruleset.rules.map((rule) => {
|
|
1773
1780
|
const inputFacts = inputFactsForRule[rule.id];
|
|
1774
1781
|
const values$ = inputFacts.map((fact) => this.rulesEngine.retrieveOrCreateFactStream(fact));
|
|
1775
|
-
return (values$.length ? combineLatest(values$) : of([[]]))
|
|
1782
|
+
return (values$.length > 0 ? combineLatest(values$) : of([[]]))
|
|
1776
1783
|
.pipe(startWith(undefined), pairwise(), tap(() => this.performanceMark(rule, 'start')), map(([oldFactValues, factValues]) => {
|
|
1777
1784
|
const output = { actions: undefined };
|
|
1778
1785
|
try {
|
|
@@ -1795,7 +1802,7 @@ class RulesetExecutor {
|
|
|
1795
1802
|
return output;
|
|
1796
1803
|
}), tap(() => this.performanceMark(rule, 'end')));
|
|
1797
1804
|
})).pipe(startWith(undefined), pairwise(), map(([prevRes, currRes]) => {
|
|
1798
|
-
const actionsLists = currRes.map(r => r.actions);
|
|
1805
|
+
const actionsLists = currRes.map((r) => r.actions);
|
|
1799
1806
|
const allExecutionsValid = actionsLists.every((actions) => !!actions);
|
|
1800
1807
|
let execInfo = { actionsLists: (allExecutionsValid ? actionsLists : [[]]) };
|
|
1801
1808
|
if (this.rulesEngine.engineDebug) {
|
|
@@ -1834,14 +1841,13 @@ class RulesEngine {
|
|
|
1834
1841
|
/**
|
|
1835
1842
|
* Rules engine
|
|
1836
1843
|
* @param options rules engine options
|
|
1837
|
-
* @param logger
|
|
1838
1844
|
*/
|
|
1839
1845
|
constructor(options) {
|
|
1840
1846
|
/** Map of registered fact stream, this map is mutated by the ruleset executors */
|
|
1841
1847
|
this.factMap = {};
|
|
1842
1848
|
/** Subject containing the rulesets and the results stream*/
|
|
1843
1849
|
this.rulesetMapSubject = new BehaviorSubject({});
|
|
1844
|
-
this.performance = options?.performance || (typeof window
|
|
1850
|
+
this.performance = options?.performance || (typeof window === 'undefined' ? undefined : window.performance);
|
|
1845
1851
|
this.engineDebug = options?.debugger;
|
|
1846
1852
|
this.engineDebug?.registerRuleEngine(this);
|
|
1847
1853
|
this.logger = options?.logger;
|
|
@@ -1865,7 +1871,6 @@ class RulesEngine {
|
|
|
1865
1871
|
}
|
|
1866
1872
|
/**
|
|
1867
1873
|
* Attach debug events to actions stream if debug engine is activated
|
|
1868
|
-
* @param actionsStream
|
|
1869
1874
|
*/
|
|
1870
1875
|
handleActionsStreamOutput() {
|
|
1871
1876
|
return (actionsStream$) => this.engineDebug ? actionsStream$.pipe(tap((allActions) => this.engineDebug.allActionsChange(allActions))) : actionsStream$;
|
|
@@ -1875,8 +1880,8 @@ class RulesEngine {
|
|
|
1875
1880
|
* @param ruleSets
|
|
1876
1881
|
*/
|
|
1877
1882
|
prepareActionsStream(ruleSets) {
|
|
1878
|
-
return (rulesetMapSubject$) => (this.engineDebug
|
|
1879
|
-
rulesetMapSubject$.pipe(tap((ruleSetExecutorMap) => this.engineDebug.activeRulesetsChange(ruleSetExecutorMap, ruleSets)), filterRulesetsEventStream(ruleSets))
|
|
1883
|
+
return (rulesetMapSubject$) => (this.engineDebug
|
|
1884
|
+
? rulesetMapSubject$.pipe(tap((ruleSetExecutorMap) => this.engineDebug.activeRulesetsChange(ruleSetExecutorMap, ruleSets)), filterRulesetsEventStream(ruleSets))
|
|
1880
1885
|
: rulesetMapSubject$.pipe(filterRulesetsEventStream(ruleSets)));
|
|
1881
1886
|
}
|
|
1882
1887
|
/**
|
|
@@ -1887,9 +1892,9 @@ class RulesEngine {
|
|
|
1887
1892
|
*/
|
|
1888
1893
|
retrieveOrCreateFactStream(id, factValue$) {
|
|
1889
1894
|
// trick to emit undefined if the observable is not immediately emitting (to not bloc execution)
|
|
1890
|
-
const obs$ = factValue$
|
|
1891
|
-
merge(factValue$, of(undefined).pipe(delay(this.factDefaultDelay || 0), takeUntil(factValue$)))
|
|
1892
|
-
factValue$;
|
|
1895
|
+
const obs$ = factValue$
|
|
1896
|
+
? merge(factValue$, of(undefined).pipe(delay(this.factDefaultDelay || 0), takeUntil(factValue$)))
|
|
1897
|
+
: factValue$;
|
|
1893
1898
|
const factObj = this.factMap[id];
|
|
1894
1899
|
if (factObj) {
|
|
1895
1900
|
if (factValue$) {
|
|
@@ -1922,7 +1927,6 @@ class RulesEngine {
|
|
|
1922
1927
|
}
|
|
1923
1928
|
/**
|
|
1924
1929
|
* Update or insert rule in rules engine
|
|
1925
|
-
* @param rules rule list to add / update
|
|
1926
1930
|
* @param rulesets
|
|
1927
1931
|
*/
|
|
1928
1932
|
upsertRulesets(rulesets) {
|
|
@@ -1955,14 +1959,6 @@ class RulesEngine {
|
|
|
1955
1959
|
}
|
|
1956
1960
|
}
|
|
1957
1961
|
|
|
1958
|
-
/** Determine if the action should be executed */
|
|
1959
|
-
const RULES_ENGINE_OPTIONS = new InjectionToken('Rules Engine Options');
|
|
1960
|
-
/** Default Rules engine options */
|
|
1961
|
-
const DEFAULT_RULES_ENGINE_OPTIONS = {
|
|
1962
|
-
dryRun: false,
|
|
1963
|
-
debug: false
|
|
1964
|
-
};
|
|
1965
|
-
|
|
1966
1962
|
class RulesEngineRunnerService {
|
|
1967
1963
|
constructor(store, logger, engineConfig) {
|
|
1968
1964
|
this.store = store;
|
|
@@ -1970,7 +1966,10 @@ class RulesEngineRunnerService {
|
|
|
1970
1966
|
this.subscription = new Subscription();
|
|
1971
1967
|
/** Observable of component linked to the component */
|
|
1972
1968
|
this.linkedComponents$ = new BehaviorSubject({});
|
|
1973
|
-
/**
|
|
1969
|
+
/**
|
|
1970
|
+
* List of action handlers
|
|
1971
|
+
* @deprecated will become protected in Otter v13, instead use {@link registerActionHandlers}
|
|
1972
|
+
*/
|
|
1974
1973
|
this.actionHandlers = new Set();
|
|
1975
1974
|
this.enabled = !engineConfig?.dryRun;
|
|
1976
1975
|
this.engine = new RulesEngine({
|
|
@@ -1994,7 +1993,7 @@ class RulesEngineRunnerService {
|
|
|
1994
1993
|
*/
|
|
1995
1994
|
async executeActions(actions) {
|
|
1996
1995
|
const actionHandlers = [...this.actionHandlers];
|
|
1997
|
-
const supportedActions = new Set(actionHandlers.
|
|
1996
|
+
const supportedActions = new Set(actionHandlers.flatMap((handler) => handler.supportingActions));
|
|
1998
1997
|
const actionMaps = actions
|
|
1999
1998
|
.filter((action) => {
|
|
2000
1999
|
const isKnown = supportedActions.has(action.actionType);
|
|
@@ -2015,26 +2014,40 @@ class RulesEngineRunnerService {
|
|
|
2015
2014
|
await Promise.all(handling);
|
|
2016
2015
|
}
|
|
2017
2016
|
/**
|
|
2018
|
-
* Update or insert fact in rules engine
|
|
2017
|
+
* Update or insert fact in the rules engine
|
|
2019
2018
|
* @param facts fact list to add / update
|
|
2020
2019
|
*/
|
|
2021
2020
|
upsertFacts(facts) {
|
|
2022
2021
|
this.engine.upsertFacts(facts);
|
|
2023
2022
|
}
|
|
2024
2023
|
/**
|
|
2025
|
-
* Update or insert operator in rules engine
|
|
2024
|
+
* Update or insert operator in the rules engine
|
|
2026
2025
|
* @param operators operator list to add / update
|
|
2027
2026
|
*/
|
|
2028
2027
|
upsertOperators(operators) {
|
|
2029
2028
|
this.engine.upsertOperators(operators);
|
|
2030
2029
|
}
|
|
2031
2030
|
/**
|
|
2032
|
-
* Upsert a list of RuleSets to be run in the engine
|
|
2031
|
+
* Upsert a list of RuleSets to be run in the rules engine
|
|
2033
2032
|
* @param ruleSets
|
|
2034
2033
|
*/
|
|
2035
2034
|
upsertRulesets(ruleSets) {
|
|
2036
2035
|
this.store.dispatch(setRulesetsEntities({ entities: ruleSets }));
|
|
2037
2036
|
}
|
|
2037
|
+
/**
|
|
2038
|
+
* Add action handlers in the rules engine
|
|
2039
|
+
* @param actionHandlers
|
|
2040
|
+
*/
|
|
2041
|
+
registerActionHandlers(...actionHandlers) {
|
|
2042
|
+
actionHandlers.forEach((actionHandler) => this.actionHandlers.add(actionHandler));
|
|
2043
|
+
}
|
|
2044
|
+
/**
|
|
2045
|
+
* Remove action handlers in the rules engine
|
|
2046
|
+
* @param actionHandlers
|
|
2047
|
+
*/
|
|
2048
|
+
unregisterActionHandlers(...actionHandlers) {
|
|
2049
|
+
actionHandlers.forEach((actionHandler) => this.actionHandlers.delete(actionHandler));
|
|
2050
|
+
}
|
|
2038
2051
|
/** @inheritdoc */
|
|
2039
2052
|
ngOnDestroy() {
|
|
2040
2053
|
this.subscription.unsubscribe();
|
|
@@ -2059,10 +2072,10 @@ class RulesEngineRunnerService {
|
|
|
2059
2072
|
this.linkedComponents$.next(newMap);
|
|
2060
2073
|
}
|
|
2061
2074
|
}
|
|
2062
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2063
|
-
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.
|
|
2075
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerService, deps: [{ token: i1$2.Store }, { token: i2.LoggerService }, { token: RULES_ENGINE_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2076
|
+
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerService }); }
|
|
2064
2077
|
}
|
|
2065
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2078
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerService, decorators: [{
|
|
2066
2079
|
type: Injectable
|
|
2067
2080
|
}], ctorParameters: () => [{ type: i1$2.Store }, { type: i2.LoggerService }, { type: undefined, decorators: [{
|
|
2068
2081
|
type: Optional
|
|
@@ -2082,15 +2095,15 @@ class RulesEngineRunnerModule {
|
|
|
2082
2095
|
]
|
|
2083
2096
|
};
|
|
2084
2097
|
}
|
|
2085
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2086
|
-
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.
|
|
2098
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2099
|
+
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerModule, imports: [StoreModule,
|
|
2087
2100
|
RulesetsStoreModule,
|
|
2088
2101
|
LoggerModule] }); }
|
|
2089
|
-
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.
|
|
2102
|
+
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerModule, imports: [StoreModule,
|
|
2090
2103
|
RulesetsStoreModule,
|
|
2091
2104
|
LoggerModule] }); }
|
|
2092
2105
|
}
|
|
2093
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2106
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerModule, decorators: [{
|
|
2094
2107
|
type: NgModule,
|
|
2095
2108
|
args: [{
|
|
2096
2109
|
imports: [
|
|
@@ -2138,17 +2151,17 @@ class OtterRulesEngineDevtools {
|
|
|
2138
2151
|
}
|
|
2139
2152
|
/** Returns the list of active rulesets (name and id) at the moment when the function is called */
|
|
2140
2153
|
async getActiveRulesets() {
|
|
2141
|
-
const lastActiveRulesetsEvent = (this.rulesEngineEvents$ && await firstValueFrom(this.rulesEngineEvents$))?.filter(e => e.type === 'ActiveRulesets').reverse()[0];
|
|
2154
|
+
const lastActiveRulesetsEvent = (this.rulesEngineEvents$ && await firstValueFrom(this.rulesEngineEvents$))?.filter((e) => e.type === 'ActiveRulesets').reverse()[0];
|
|
2142
2155
|
return lastActiveRulesetsEvent?.rulesets;
|
|
2143
2156
|
}
|
|
2144
2157
|
/** Returns the list of available rulesets (name and id) at the moment when the function is called */
|
|
2145
2158
|
async getAvailableRulesets() {
|
|
2146
|
-
const lastAvailableRulesetsEvent = (this.rulesEngineEvents$ && await firstValueFrom(this.rulesEngineEvents$))?.filter(e => e.type === 'AvailableRulesets').reverse()[0];
|
|
2159
|
+
const lastAvailableRulesetsEvent = (this.rulesEngineEvents$ && await firstValueFrom(this.rulesEngineEvents$))?.filter((e) => e.type === 'AvailableRulesets').reverse()[0];
|
|
2147
2160
|
return lastAvailableRulesetsEvent?.availableRulesets;
|
|
2148
2161
|
}
|
|
2149
2162
|
/** Returns the list of output actions emitted by the rules engine at the moment when the function is called */
|
|
2150
2163
|
async getAllOutputActions() {
|
|
2151
|
-
return (this.rulesEngineEvents$ && await firstValueFrom(this.rulesEngineEvents$))?.filter(e => e.type === 'AllActions')?.reverse()[0];
|
|
2164
|
+
return (this.rulesEngineEvents$ && await firstValueFrom(this.rulesEngineEvents$))?.filter((e) => e.type === 'AllActions')?.reverse()[0];
|
|
2152
2165
|
}
|
|
2153
2166
|
/**
|
|
2154
2167
|
* Get the list of executions for the given ruleset
|
|
@@ -2164,7 +2177,7 @@ class OtterRulesEngineDevtools {
|
|
|
2164
2177
|
* @returns True if the ruleset is active; False if the ruleset is inactive or it does not exist
|
|
2165
2178
|
*/
|
|
2166
2179
|
async isRulesetActive(rulesetId) {
|
|
2167
|
-
return !!(await this.getActiveRulesets())?.find(r => r.id === rulesetId);
|
|
2180
|
+
return !!(await this.getActiveRulesets())?.find((r) => r.id === rulesetId);
|
|
2168
2181
|
}
|
|
2169
2182
|
/**
|
|
2170
2183
|
* Get the list of rules executed for the specified ruleset
|
|
@@ -2172,7 +2185,7 @@ class OtterRulesEngineDevtools {
|
|
|
2172
2185
|
*/
|
|
2173
2186
|
async getRulesEvaluationsForRuleset(rulesetId) {
|
|
2174
2187
|
const rulesetExec = await this.getRulesetExecutions(rulesetId);
|
|
2175
|
-
return rulesetExec?.map(e => e?.rulesEvaluations?.filter(re => !re.cached)).flat();
|
|
2188
|
+
return rulesetExec?.map((e) => e?.rulesEvaluations?.filter((re) => !re.cached)).flat();
|
|
2176
2189
|
}
|
|
2177
2190
|
/**
|
|
2178
2191
|
* Get the list of input facts (name, current value) for the specified ruleset, at the moment when the function is called
|
|
@@ -2180,14 +2193,14 @@ class OtterRulesEngineDevtools {
|
|
|
2180
2193
|
*/
|
|
2181
2194
|
async getInputFactsForRuleset(rulesetId) {
|
|
2182
2195
|
const rulesetExecutions = await this.getRulesetExecutions(rulesetId);
|
|
2183
|
-
return rulesetExecutions ? rulesetExecutions
|
|
2196
|
+
return rulesetExecutions ? rulesetExecutions.at(-1).inputFacts : undefined;
|
|
2184
2197
|
}
|
|
2185
2198
|
/**
|
|
2186
2199
|
* Get the list of triggers for the specified ruleset
|
|
2187
2200
|
* @param rulesetId
|
|
2188
2201
|
*/
|
|
2189
2202
|
async getTriggersForRuleset(rulesetId) {
|
|
2190
|
-
return (await this.getRulesEvaluationsForRuleset(rulesetId))?.map(e => e.triggers).flat().
|
|
2203
|
+
return (await this.getRulesEvaluationsForRuleset(rulesetId))?.map((e) => e.triggers).flat().flatMap((triggersMap) => Object.values(triggersMap));
|
|
2191
2204
|
}
|
|
2192
2205
|
/**
|
|
2193
2206
|
* Get the list of outputed actions emitted by the given ruleset, at the moment when the function is called
|
|
@@ -2195,7 +2208,7 @@ class OtterRulesEngineDevtools {
|
|
|
2195
2208
|
*/
|
|
2196
2209
|
async getOutputActionsForRuleset(rulesetId) {
|
|
2197
2210
|
const rulesetExecutions = await this.getRulesetExecutions(rulesetId);
|
|
2198
|
-
return rulesetExecutions ? rulesetExecutions
|
|
2211
|
+
return rulesetExecutions ? rulesetExecutions.at(-1).outputActions : undefined;
|
|
2199
2212
|
}
|
|
2200
2213
|
/** Get the list of fact names and corresponding values */
|
|
2201
2214
|
getAllFactsSnapshot() {
|
|
@@ -2211,10 +2224,10 @@ class OtterRulesEngineDevtools {
|
|
|
2211
2224
|
getRulesetInformation(rulesetId) {
|
|
2212
2225
|
return firstValueFrom(this.store.pipe(select(selectRulesetsEntities), map((entities) => entities[rulesetId])));
|
|
2213
2226
|
}
|
|
2214
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2215
|
-
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.
|
|
2227
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OtterRulesEngineDevtools, deps: [{ token: i1$2.Store }, { token: RulesEngineRunnerService }, { token: OTTER_RULES_ENGINE_DEVTOOLS_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2228
|
+
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OtterRulesEngineDevtools, providedIn: 'root' }); }
|
|
2216
2229
|
}
|
|
2217
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2230
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OtterRulesEngineDevtools, decorators: [{
|
|
2218
2231
|
type: Injectable,
|
|
2219
2232
|
args: [{
|
|
2220
2233
|
providedIn: 'root'
|
|
@@ -2226,7 +2239,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
2226
2239
|
args: [OTTER_RULES_ENGINE_DEVTOOLS_OPTIONS]
|
|
2227
2240
|
}] }] });
|
|
2228
2241
|
|
|
2229
|
-
/* eslint-disable no-console */
|
|
2242
|
+
/* eslint-disable no-console -- purpose of the service is to log in the console */
|
|
2230
2243
|
class RulesEngineDevtoolsConsoleService {
|
|
2231
2244
|
/** Name of the Window property to access to the devtools */
|
|
2232
2245
|
static { this.windowModuleName = 'rulesEngine'; }
|
|
@@ -2243,9 +2256,7 @@ class RulesEngineDevtoolsConsoleService {
|
|
|
2243
2256
|
/** @inheritDoc */
|
|
2244
2257
|
activate() {
|
|
2245
2258
|
const windowWithDevtools = window;
|
|
2246
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
2247
2259
|
windowWithDevtools._OTTER_DEVTOOLS_ ||= {};
|
|
2248
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
2249
2260
|
windowWithDevtools._OTTER_DEVTOOLS_[RulesEngineDevtoolsConsoleService.windowModuleName] = this;
|
|
2250
2261
|
console.info(`Otter rules engine Devtools is now accessible via the _OTTER_DEVTOOLS_.${RulesEngineDevtoolsConsoleService.windowModuleName} variable`);
|
|
2251
2262
|
}
|
|
@@ -2319,10 +2330,10 @@ class RulesEngineDevtoolsConsoleService {
|
|
|
2319
2330
|
async getRulesetInformation(rulesetId) {
|
|
2320
2331
|
console.log(await this.rulesEngineDevtools.getRulesetInformation(rulesetId));
|
|
2321
2332
|
}
|
|
2322
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2323
|
-
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.
|
|
2333
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsConsoleService, deps: [{ token: OtterRulesEngineDevtools }, { token: OTTER_RULES_ENGINE_DEVTOOLS_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2334
|
+
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsConsoleService, providedIn: 'root' }); }
|
|
2324
2335
|
}
|
|
2325
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2336
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsConsoleService, decorators: [{
|
|
2326
2337
|
type: Injectable,
|
|
2327
2338
|
args: [{
|
|
2328
2339
|
providedIn: 'root'
|
|
@@ -2341,6 +2352,7 @@ class RulesEngineDevtoolsMessageService {
|
|
|
2341
2352
|
this.subscriptions = new Subscription();
|
|
2342
2353
|
this.forceEmitRulesEngineReport = new BehaviorSubject(undefined);
|
|
2343
2354
|
this.sendMessage = (sendOtterMessage);
|
|
2355
|
+
this.serializeError = (error) => error instanceof Error ? error.toString() : error;
|
|
2344
2356
|
this.options = {
|
|
2345
2357
|
...OTTER_RULES_ENGINE_DEVTOOLS_DEFAULT_OPTIONS,
|
|
2346
2358
|
...options
|
|
@@ -2360,7 +2372,6 @@ class RulesEngineDevtoolsMessageService {
|
|
|
2360
2372
|
}
|
|
2361
2373
|
/**
|
|
2362
2374
|
* Function to handle the incoming messages from Otter Chrome DevTools extension
|
|
2363
|
-
* @param event Event coming from the Otter Chrome DevTools extension
|
|
2364
2375
|
* @param message
|
|
2365
2376
|
*/
|
|
2366
2377
|
handleEvents(message) {
|
|
@@ -2384,7 +2395,6 @@ class RulesEngineDevtoolsMessageService {
|
|
|
2384
2395
|
* @param debugEvent
|
|
2385
2396
|
*/
|
|
2386
2397
|
serializeReportEvent(debugEvent) {
|
|
2387
|
-
const serializeError = (error) => error instanceof Error ? error.toString() : error;
|
|
2388
2398
|
if (debugEvent.type !== 'RulesetExecutionError') {
|
|
2389
2399
|
return debugEvent;
|
|
2390
2400
|
}
|
|
@@ -2392,9 +2402,10 @@ class RulesEngineDevtoolsMessageService {
|
|
|
2392
2402
|
...debugEvent,
|
|
2393
2403
|
rulesEvaluations: debugEvent.rulesEvaluations.map((ruleEvaluation) => ({
|
|
2394
2404
|
...ruleEvaluation,
|
|
2395
|
-
error: serializeError(ruleEvaluation.error)
|
|
2405
|
+
error: this.serializeError(ruleEvaluation.error)
|
|
2396
2406
|
})),
|
|
2397
|
-
|
|
2407
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- type is explicitly `any`
|
|
2408
|
+
errors: debugEvent.errors.map((error) => this.serializeError(error))
|
|
2398
2409
|
};
|
|
2399
2410
|
}
|
|
2400
2411
|
/**
|
|
@@ -2424,10 +2435,10 @@ class RulesEngineDevtoolsMessageService {
|
|
|
2424
2435
|
ngOnDestroy() {
|
|
2425
2436
|
this.subscriptions.unsubscribe();
|
|
2426
2437
|
}
|
|
2427
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2428
|
-
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.
|
|
2438
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsMessageService, deps: [{ token: OtterRulesEngineDevtools }, { token: i2.LoggerService }, { token: OTTER_RULES_ENGINE_DEVTOOLS_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2439
|
+
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsMessageService, providedIn: 'root' }); }
|
|
2429
2440
|
}
|
|
2430
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2441
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsMessageService, decorators: [{
|
|
2431
2442
|
type: Injectable,
|
|
2432
2443
|
args: [{
|
|
2433
2444
|
providedIn: 'root'
|
|
@@ -2454,17 +2465,17 @@ class RulesEngineDevtoolsModule {
|
|
|
2454
2465
|
]
|
|
2455
2466
|
};
|
|
2456
2467
|
}
|
|
2457
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2458
|
-
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.
|
|
2468
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2469
|
+
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsModule, imports: [StoreModule,
|
|
2459
2470
|
RulesetsStoreModule] }); }
|
|
2460
|
-
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.
|
|
2471
|
+
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsModule, providers: [
|
|
2461
2472
|
{ provide: OTTER_RULES_ENGINE_DEVTOOLS_OPTIONS, useValue: OTTER_RULES_ENGINE_DEVTOOLS_DEFAULT_OPTIONS },
|
|
2462
2473
|
RulesEngineDevtoolsMessageService,
|
|
2463
2474
|
RulesEngineDevtoolsConsoleService
|
|
2464
2475
|
], imports: [StoreModule,
|
|
2465
2476
|
RulesetsStoreModule] }); }
|
|
2466
2477
|
}
|
|
2467
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2478
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsModule, decorators: [{
|
|
2468
2479
|
type: NgModule,
|
|
2469
2480
|
args: [{
|
|
2470
2481
|
imports: [
|
|
@@ -2504,10 +2515,10 @@ class CurrentTimeFactsService extends FactsService {
|
|
|
2504
2515
|
tick() {
|
|
2505
2516
|
this.currentTimeSubject$.next(Date.now());
|
|
2506
2517
|
}
|
|
2507
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2508
|
-
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.
|
|
2518
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CurrentTimeFactsService, deps: [{ token: RulesEngineRunnerService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2519
|
+
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CurrentTimeFactsService, providedIn: 'root' }); }
|
|
2509
2520
|
}
|
|
2510
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2521
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CurrentTimeFactsService, decorators: [{
|
|
2511
2522
|
type: Injectable,
|
|
2512
2523
|
args: [{
|
|
2513
2524
|
providedIn: 'root'
|