@o3r/rules-engine 11.6.0-prerelease.6 → 11.6.0-prerelease.61
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 +2 -2
- package/builders/rules-engine-extractor/index.d.ts.map +1 -1
- package/builders/rules-engine-extractor/index.js +18 -24
- 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 +3 -6
- 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 +23 -23
- 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 +18 -22
- 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 +314 -325
- 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/package.json +18 -18
- 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 +0 -4
- package/schematics/ng-update/index.d.ts.map +1 -1
- package/schematics/ng-update/index.js +0 -4
- 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.map +1 -1
- 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 +4 -8
- 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,8 +1,8 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Component, ChangeDetectionStrategy, ViewEncapsulation, Input, Pipe, NgModule, InjectionToken, Injectable, Optional, Inject, inject, DestroyRef } from '@angular/core';
|
|
1
3
|
import * as i1 from '@angular/common';
|
|
2
4
|
import { CommonModule, JsonPipe } from '@angular/common';
|
|
3
|
-
import
|
|
4
|
-
import { Component, ChangeDetectionStrategy, ViewEncapsulation, Input, Pipe, NgModule, Injectable, InjectionToken, Optional, Inject } from '@angular/core';
|
|
5
|
-
import { Subject, of, from, ReplaySubject, Observable, combineLatest, BehaviorSubject, merge, firstValueFrom, Subscription, fromEvent } from 'rxjs';
|
|
5
|
+
import { Subject, of, from, ReplaySubject, Observable, combineLatest, BehaviorSubject, merge, firstValueFrom, 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';
|
|
8
8
|
import { createAction, props, on, createReducer, StoreModule, createFeatureSelector, createSelector, select } from '@ngrx/store';
|
|
@@ -12,8 +12,42 @@ import { asyncProps, fromApiEffectSwitchMap, asyncStoreItemAdapter, computeItemI
|
|
|
12
12
|
import * as i1$1 from '@ngrx/effects';
|
|
13
13
|
import { createEffect, ofType, EffectsModule } from '@ngrx/effects';
|
|
14
14
|
import { createEntityAdapter } from '@ngrx/entity';
|
|
15
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
15
16
|
import { JSONPath } from 'jsonpath-plus';
|
|
16
17
|
|
|
18
|
+
class RuleConditionPresComponent {
|
|
19
|
+
constructor() {
|
|
20
|
+
/**
|
|
21
|
+
* Left hand operator as it will be displayed in the template.
|
|
22
|
+
* In the case of a fact with a json path, will resolve the whole fact path, else will only display the value
|
|
23
|
+
*/
|
|
24
|
+
this.lhs = 'undefined';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Rule condition that will be flattened by the component setter
|
|
28
|
+
*/
|
|
29
|
+
set condition(condition) {
|
|
30
|
+
this._condition = condition;
|
|
31
|
+
this.lhs = condition?.lhs ? this.getOperandName(condition.lhs) : 'undefined';
|
|
32
|
+
this.rhs = condition?.rhs ? this.getOperandName(condition.rhs) : undefined;
|
|
33
|
+
}
|
|
34
|
+
get condition() {
|
|
35
|
+
return this._condition;
|
|
36
|
+
}
|
|
37
|
+
getOperandName(operand) {
|
|
38
|
+
const value = `${operand.value ?? 'MISSING_VALUE'}`;
|
|
39
|
+
return operand.path ? operand.path.replace(/^\$/, value) : value;
|
|
40
|
+
}
|
|
41
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleConditionPresComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
42
|
+
/** @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 }); }
|
|
43
|
+
}
|
|
44
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleConditionPresComponent, decorators: [{
|
|
45
|
+
type: Component,
|
|
46
|
+
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"] }]
|
|
47
|
+
}], propDecorators: { condition: [{
|
|
48
|
+
type: Input
|
|
49
|
+
}] } });
|
|
50
|
+
|
|
17
51
|
/**
|
|
18
52
|
* Duration of the notification for clipboard feature (in milliseconds)
|
|
19
53
|
*/
|
|
@@ -56,12 +90,12 @@ class RuleKeyValuePresComponent {
|
|
|
56
90
|
await navigator.clipboard.writeText(content);
|
|
57
91
|
this.triggerNotification.next();
|
|
58
92
|
}
|
|
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.
|
|
93
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleKeyValuePresComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
94
|
+
/** @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
95
|
}
|
|
62
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
96
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleKeyValuePresComponent, decorators: [{
|
|
63
97
|
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\"
|
|
98
|
+
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
99
|
}], propDecorators: { key: [{
|
|
66
100
|
type: Input
|
|
67
101
|
}], value: [{
|
|
@@ -74,12 +108,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
74
108
|
|
|
75
109
|
class O3rFallbackToPipe {
|
|
76
110
|
transform(value, fallback = 'undefined') {
|
|
77
|
-
return value
|
|
111
|
+
return value === undefined ? fallback : value;
|
|
78
112
|
}
|
|
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.
|
|
113
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: O3rFallbackToPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
114
|
+
/** @nocollapse */ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: O3rFallbackToPipe, isStandalone: true, name: "o3rFallbackTo" }); }
|
|
81
115
|
}
|
|
82
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
116
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: O3rFallbackToPipe, decorators: [{
|
|
83
117
|
type: Pipe,
|
|
84
118
|
args: [{ name: 'o3rFallbackTo', standalone: true }]
|
|
85
119
|
}] });
|
|
@@ -87,10 +121,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
87
121
|
* @deprecated please use O3rFallbackToPipe, will be removed in v12.
|
|
88
122
|
*/
|
|
89
123
|
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.
|
|
124
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FallbackToPipe, deps: null, target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
125
|
+
/** @nocollapse */ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: FallbackToPipe, name: "fallbackTo" }); }
|
|
92
126
|
}
|
|
93
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
127
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FallbackToPipe, decorators: [{
|
|
94
128
|
type: Pipe,
|
|
95
129
|
args: [{ name: 'fallbackTo' }]
|
|
96
130
|
}] });
|
|
@@ -111,10 +145,10 @@ class RuleActionsPresComponent {
|
|
|
111
145
|
*/
|
|
112
146
|
this.runtimeOutputs = [];
|
|
113
147
|
}
|
|
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.
|
|
148
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleActionsPresComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
149
|
+
/** @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
150
|
}
|
|
117
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
151
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleActionsPresComponent, decorators: [{
|
|
118
152
|
type: Component,
|
|
119
153
|
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
154
|
}], propDecorators: { actions: [{
|
|
@@ -125,40 +159,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
125
159
|
type: Input
|
|
126
160
|
}] } });
|
|
127
161
|
|
|
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
162
|
class RuleTreePresComponent {
|
|
163
163
|
constructor() {
|
|
164
164
|
/**
|
|
@@ -184,10 +184,10 @@ class RuleTreePresComponent {
|
|
|
184
184
|
*/
|
|
185
185
|
this.successActionsExpanded = false;
|
|
186
186
|
}
|
|
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.
|
|
187
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleTreePresComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
188
|
+
/** @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
189
|
}
|
|
190
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
190
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RuleTreePresComponent, decorators: [{
|
|
191
191
|
type: Component,
|
|
192
192
|
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
193
|
}], propDecorators: { name: [{
|
|
@@ -202,57 +202,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
202
202
|
type: Input
|
|
203
203
|
}] } });
|
|
204
204
|
|
|
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
205
|
class O3rJsonOrStringPipe {
|
|
257
206
|
/**
|
|
258
207
|
* @inheritDoc
|
|
@@ -263,10 +212,10 @@ class O3rJsonOrStringPipe {
|
|
|
263
212
|
}
|
|
264
213
|
return JSON.stringify(value, null, 2);
|
|
265
214
|
}
|
|
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.
|
|
215
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: O3rJsonOrStringPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
216
|
+
/** @nocollapse */ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: O3rJsonOrStringPipe, isStandalone: true, name: "o3rJsonOrString" }); }
|
|
268
217
|
}
|
|
269
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
218
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: O3rJsonOrStringPipe, decorators: [{
|
|
270
219
|
type: Pipe,
|
|
271
220
|
args: [{
|
|
272
221
|
name: 'o3rJsonOrString',
|
|
@@ -296,32 +245,83 @@ class RulesetHistoryPresComponent {
|
|
|
296
245
|
* @param subpanel element to collapse. 'ruleset' will toggle the whole panel but won't reset the subpanels states.
|
|
297
246
|
*/
|
|
298
247
|
toggleExpansion(ruleId, subpanel) {
|
|
299
|
-
if (
|
|
300
|
-
this.expansionStatus[ruleId] =
|
|
248
|
+
if (this.expansionStatus[ruleId]) {
|
|
249
|
+
this.expansionStatus[ruleId][subpanel] = !this.expansionStatus[ruleId][subpanel];
|
|
301
250
|
}
|
|
302
251
|
else {
|
|
303
|
-
this.expansionStatus[ruleId]
|
|
252
|
+
this.expansionStatus[ruleId] = { [subpanel]: true };
|
|
304
253
|
}
|
|
305
254
|
this.cd.detectChanges();
|
|
306
255
|
}
|
|
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 }); }
|
|
256
|
+
/** @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 }); }
|
|
257
|
+
/** @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
258
|
}
|
|
310
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
259
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetHistoryPresComponent, decorators: [{
|
|
311
260
|
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"] }]
|
|
261
|
+
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
262
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { rulesetExecutions: [{
|
|
314
263
|
type: Input
|
|
315
264
|
}], executionDurationFormat: [{
|
|
316
265
|
type: Input
|
|
317
266
|
}] } });
|
|
318
267
|
|
|
268
|
+
/**
|
|
269
|
+
* Compute the status of the execution depending on its execution event type, the output and whether the execution
|
|
270
|
+
* is still active
|
|
271
|
+
* @param rulesetExecution
|
|
272
|
+
* @param isActive
|
|
273
|
+
*/
|
|
274
|
+
const getStatus = (rulesetExecution, isActive) => {
|
|
275
|
+
if (rulesetExecution.type === 'RulesetExecutionError') {
|
|
276
|
+
return 'Error';
|
|
277
|
+
}
|
|
278
|
+
else if (rulesetExecution.outputActions?.length === 0) {
|
|
279
|
+
return 'NoEffect';
|
|
280
|
+
}
|
|
281
|
+
else if (isActive) {
|
|
282
|
+
return 'Active';
|
|
283
|
+
}
|
|
284
|
+
return 'Deactivated';
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Transform the output of the debug reports into the model for the ruleset history debug panel
|
|
288
|
+
* @param events
|
|
289
|
+
* @param rulesetMap
|
|
290
|
+
*/
|
|
291
|
+
const rulesetReportToHistory = (events, rulesetMap) => {
|
|
292
|
+
const availableRulesets = (events.filter((e) => e.type === 'AvailableRulesets').reverse()[0])?.availableRulesets || [];
|
|
293
|
+
const lastActiveRulesets = (events.filter((e) => e.type === 'ActiveRulesets').reverse()[0])?.rulesets || [];
|
|
294
|
+
return availableRulesets
|
|
295
|
+
.filter((ruleset) => !!ruleset)
|
|
296
|
+
.reduce((acc, ruleset) => {
|
|
297
|
+
const rulesetExecutions = events
|
|
298
|
+
.filter((e) => ((e.type === 'RulesetExecutionError' || e.type === 'RulesetExecution') && e.rulesetId === ruleset.id));
|
|
299
|
+
if (rulesetExecutions) {
|
|
300
|
+
acc.push(...rulesetExecutions);
|
|
301
|
+
}
|
|
302
|
+
return acc;
|
|
303
|
+
}, [])
|
|
304
|
+
.sort((execA, execB) => execB.timestamp - execA.timestamp)
|
|
305
|
+
.map((rulesetExecution) => {
|
|
306
|
+
const rulesetInformation = rulesetMap[rulesetExecution.rulesetId];
|
|
307
|
+
const isActive = lastActiveRulesets.find((r) => r.id === rulesetExecution.rulesetId);
|
|
308
|
+
return {
|
|
309
|
+
...rulesetExecution,
|
|
310
|
+
status: getStatus(rulesetExecution, !!isActive),
|
|
311
|
+
isActive: !!isActive,
|
|
312
|
+
rulesetInformation,
|
|
313
|
+
rulesEvaluations: (rulesetExecution.rulesEvaluations || []).sort((evalA, evalB) => (rulesetInformation?.rules.findIndex((r) => r.id === evalA.rule.id) || -1)
|
|
314
|
+
- (rulesetInformation?.rules.findIndex((r) => r.id === evalB.rule.id) || -1))
|
|
315
|
+
};
|
|
316
|
+
});
|
|
317
|
+
};
|
|
318
|
+
|
|
319
319
|
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.
|
|
320
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetHistoryPresModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
321
|
+
/** @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] }); }
|
|
322
|
+
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetHistoryPresModule, imports: [CommonModule, CommonModule, CommonModule] }); }
|
|
323
323
|
}
|
|
324
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
324
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetHistoryPresModule, decorators: [{
|
|
325
325
|
type: NgModule,
|
|
326
326
|
args: [{
|
|
327
327
|
imports: [O3rFallbackToPipe, CommonModule, CommonModule, CommonModule, JsonPipe, O3rJsonOrStringPipe],
|
|
@@ -331,9 +331,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
331
331
|
}] });
|
|
332
332
|
|
|
333
333
|
const isRulesEngineMessage = (message) => {
|
|
334
|
-
return message && (message.dataType === 'rulesEngineEvents'
|
|
335
|
-
message.dataType === 'requestMessages'
|
|
336
|
-
message.dataType === 'connect');
|
|
334
|
+
return message && (message.dataType === 'rulesEngineEvents'
|
|
335
|
+
|| message.dataType === 'requestMessages'
|
|
336
|
+
|| message.dataType === 'connect');
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
/** Determine if the action should be executed */
|
|
340
|
+
const RULES_ENGINE_OPTIONS = new InjectionToken('Rules Engine Options');
|
|
341
|
+
/** Default Rules engine options */
|
|
342
|
+
const DEFAULT_RULES_ENGINE_OPTIONS = {
|
|
343
|
+
dryRun: false,
|
|
344
|
+
debug: false
|
|
337
345
|
};
|
|
338
346
|
|
|
339
347
|
/** StateDetailsActions */
|
|
@@ -391,10 +399,10 @@ class RulesetsEffect {
|
|
|
391
399
|
*/
|
|
392
400
|
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
401
|
}
|
|
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.
|
|
402
|
+
/** @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 }); }
|
|
403
|
+
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetsEffect }); }
|
|
396
404
|
}
|
|
397
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
405
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetsEffect, decorators: [{
|
|
398
406
|
type: Injectable
|
|
399
407
|
}], ctorParameters: () => [{ type: i1$1.Actions }] });
|
|
400
408
|
|
|
@@ -449,13 +457,13 @@ class RulesetsStoreModule {
|
|
|
449
457
|
]
|
|
450
458
|
};
|
|
451
459
|
}
|
|
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.
|
|
460
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetsStoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
461
|
+
/** @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] }); }
|
|
462
|
+
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetsStoreModule, providers: [
|
|
455
463
|
{ provide: RULESETS_REDUCER_TOKEN, useFactory: getDefaultRulesetsReducer }
|
|
456
464
|
], imports: [StoreModule.forFeature(RULESETS_STORE_NAME, RULESETS_REDUCER_TOKEN), EffectsModule.forFeature([RulesetsEffect])] }); }
|
|
457
465
|
}
|
|
458
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
466
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesetsStoreModule, decorators: [{
|
|
459
467
|
type: NgModule,
|
|
460
468
|
args: [{
|
|
461
469
|
imports: [
|
|
@@ -484,18 +492,18 @@ const selectRulesetsStorePendingStatus = createSelector(selectRulesetsState, (st
|
|
|
484
492
|
* Check if the given value is a valid date
|
|
485
493
|
* @param d
|
|
486
494
|
*/
|
|
487
|
-
const isValidDate$1 = (d) => !isNaN(d) && d instanceof Date;
|
|
495
|
+
const isValidDate$1 = (d) => !Number.isNaN(d) && d instanceof Date;
|
|
488
496
|
/**
|
|
489
497
|
* Returns the rulesets which are in the validity range, if provided
|
|
490
498
|
*/
|
|
491
499
|
const selectRuleSetsInRange = createSelector(selectAllRulesets, (ruleSets) => ruleSets.filter((ruleSet) => {
|
|
492
500
|
const validity = ruleSet.validityRange;
|
|
493
|
-
if (!validity || !validity.from && !validity.to) {
|
|
501
|
+
if (!validity || (!validity.from && !validity.to)) {
|
|
494
502
|
return true;
|
|
495
503
|
}
|
|
496
504
|
const from = validity.from && new Date(validity.from);
|
|
497
505
|
const to = validity.to && new Date(validity.to);
|
|
498
|
-
if (to && !isValidDate$1(to) || from && !isValidDate$1(from)) {
|
|
506
|
+
if ((to && !isValidDate$1(to)) || (from && !isValidDate$1(from))) {
|
|
499
507
|
return false;
|
|
500
508
|
}
|
|
501
509
|
const time = Date.now();
|
|
@@ -548,7 +556,7 @@ const selectRuleSetLinkComponents = createSelector(selectRuleSetsInRange, (ruleS
|
|
|
548
556
|
return acc;
|
|
549
557
|
}
|
|
550
558
|
if (ruleSet.linkedComponents?.or?.length) {
|
|
551
|
-
ruleSet.linkedComponents.or.forEach(linkComp => {
|
|
559
|
+
ruleSet.linkedComponents.or.forEach((linkComp) => {
|
|
552
560
|
linkRulesetToComponent(linkComp.name, linkComp.library, ruleSet.id, acc);
|
|
553
561
|
});
|
|
554
562
|
return acc;
|
|
@@ -567,7 +575,7 @@ const selectComponentsLinkedToRuleset = createSelector(selectRuleSetsInRange, (r
|
|
|
567
575
|
return acc;
|
|
568
576
|
}
|
|
569
577
|
if (ruleSet.linkedComponents?.or?.length) {
|
|
570
|
-
ruleSet.linkedComponents.or.forEach(linkComp => {
|
|
578
|
+
ruleSet.linkedComponents.or.forEach((linkComp) => {
|
|
571
579
|
linkComponentToRuleset(linkComp.name, linkComp.library, ruleSet.id, acc.or);
|
|
572
580
|
});
|
|
573
581
|
return acc;
|
|
@@ -604,18 +612,15 @@ const rulesetsStorageSync = {
|
|
|
604
612
|
*/
|
|
605
613
|
function retrieveRulesetTriggers(currRes, prevRes) {
|
|
606
614
|
let rulesetTriggers = {};
|
|
607
|
-
const allCurrRulesetTriggersList = currRes.map(r => r.evaluation).filter((e) => !!e).map(e => e.triggers);
|
|
615
|
+
const allCurrRulesetTriggersList = currRes.map((r) => r.evaluation).filter((e) => !!e).map((e) => e.triggers);
|
|
608
616
|
const allCurrRulesetTriggers = {};
|
|
609
617
|
allCurrRulesetTriggersList.forEach((rTrig) => {
|
|
610
618
|
Object.keys(rTrig).forEach((ruleId) => {
|
|
611
619
|
allCurrRulesetTriggers[ruleId] = rTrig[ruleId];
|
|
612
620
|
});
|
|
613
621
|
});
|
|
614
|
-
if (
|
|
615
|
-
|
|
616
|
-
}
|
|
617
|
-
else {
|
|
618
|
-
const allPrevRulesetTriggersList = prevRes.map(r => r.evaluation).filter((e) => !!e).map(e => e.triggers);
|
|
622
|
+
if (prevRes) {
|
|
623
|
+
const allPrevRulesetTriggersList = prevRes.map((r) => r.evaluation).filter((e) => !!e).map((e) => e.triggers);
|
|
619
624
|
const allPrevRulesetTriggers = {};
|
|
620
625
|
allPrevRulesetTriggersList.forEach((rTrig) => {
|
|
621
626
|
Object.keys(rTrig).forEach((ruleId) => {
|
|
@@ -624,14 +629,17 @@ function retrieveRulesetTriggers(currRes, prevRes) {
|
|
|
624
629
|
});
|
|
625
630
|
Object.entries(allCurrRulesetTriggers).forEach(([ruleId, ruleTriggers]) => {
|
|
626
631
|
Object.keys(ruleTriggers).forEach((factName) => {
|
|
627
|
-
if (!allPrevRulesetTriggers[ruleId]
|
|
628
|
-
!allPrevRulesetTriggers[ruleId][factName]
|
|
629
|
-
ruleTriggers[factName].newValue !== allPrevRulesetTriggers[ruleId][factName].newValue) {
|
|
632
|
+
if (!allPrevRulesetTriggers[ruleId]
|
|
633
|
+
|| !allPrevRulesetTriggers[ruleId][factName]
|
|
634
|
+
|| ruleTriggers[factName].newValue !== allPrevRulesetTriggers[ruleId][factName].newValue) {
|
|
630
635
|
(rulesetTriggers[ruleId] ||= {})[factName] = ruleTriggers[factName];
|
|
631
636
|
}
|
|
632
637
|
});
|
|
633
638
|
});
|
|
634
639
|
}
|
|
640
|
+
else {
|
|
641
|
+
rulesetTriggers = allCurrRulesetTriggers;
|
|
642
|
+
}
|
|
635
643
|
return rulesetTriggers;
|
|
636
644
|
}
|
|
637
645
|
/**
|
|
@@ -643,7 +651,7 @@ function retrieveRulesetTriggers(currRes, prevRes) {
|
|
|
643
651
|
function flagCachedRules(rulesEvaluations, triggers) {
|
|
644
652
|
const rulesWhichTriggeredExecution = Object.keys(triggers);
|
|
645
653
|
return rulesEvaluations.map((e) => {
|
|
646
|
-
if (e && rulesWhichTriggeredExecution.
|
|
654
|
+
if (e && !rulesWhichTriggeredExecution.includes(e.rule.id)) {
|
|
647
655
|
return { ...e, cached: true };
|
|
648
656
|
}
|
|
649
657
|
return { ...e };
|
|
@@ -709,8 +717,8 @@ class EngineDebugger {
|
|
|
709
717
|
let rulesetDuration = 0;
|
|
710
718
|
debugEvent.rulesEvaluations.forEach((rule) => {
|
|
711
719
|
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
|
|
720
|
+
const measures = performanceMeasures.filter((m) => m.name === mark);
|
|
721
|
+
const duration = measures.at(-1)?.duration || 0;
|
|
714
722
|
rule.duration = duration;
|
|
715
723
|
rulesetDuration += duration;
|
|
716
724
|
});
|
|
@@ -724,12 +732,12 @@ class EngineDebugger {
|
|
|
724
732
|
}), share());
|
|
725
733
|
}
|
|
726
734
|
initializePerformanceObserver() {
|
|
727
|
-
this.performanceMeasures$ = new Observable(subscriber => {
|
|
735
|
+
this.performanceMeasures$ = new Observable((subscriber) => {
|
|
728
736
|
const performanceObserver = new PerformanceObserver((list) => {
|
|
729
737
|
subscriber.next(list.getEntries());
|
|
730
738
|
});
|
|
731
739
|
performanceObserver.observe({ entryTypes: ['measure'] });
|
|
732
|
-
return performanceObserver.disconnect;
|
|
740
|
+
return performanceObserver.disconnect();
|
|
733
741
|
}).pipe(startWith([]), shareReplay(1));
|
|
734
742
|
}
|
|
735
743
|
async createBaseExecutionOutputObject(ruleset, executionCounter, rulesetInputFacts, runtimeFactValues, rulesetTriggers, rulesExecutions) {
|
|
@@ -758,12 +766,12 @@ class EngineDebugger {
|
|
|
758
766
|
}
|
|
759
767
|
async rulesetExecutionError(timestamp, ruleset, rulesetInputFacts, executionCounter, runtimeFactValues, rulesetTriggers, rulesExecutions) {
|
|
760
768
|
const baseRulesetOutputExecution = await this.createBaseExecutionOutputObject(ruleset, executionCounter, rulesetInputFacts, runtimeFactValues, rulesetTriggers, rulesExecutions);
|
|
761
|
-
const rulesExecWithErrors = rulesExecutions.filter(ex => !!ex && !!ex.error);
|
|
769
|
+
const rulesExecWithErrors = rulesExecutions.filter((ex) => !!ex && !!ex.error);
|
|
762
770
|
const rulesetOutputExecutionSkip = {
|
|
763
771
|
timestamp,
|
|
764
772
|
type: 'RulesetExecutionError',
|
|
765
|
-
rulesCausingTheError: rulesExecWithErrors.map(e => e.rule) || [],
|
|
766
|
-
errors: rulesExecWithErrors.map(e => e.error),
|
|
773
|
+
rulesCausingTheError: rulesExecWithErrors.map((e) => e.rule) || [],
|
|
774
|
+
errors: rulesExecWithErrors.map((e) => e.error),
|
|
767
775
|
...baseRulesetOutputExecution
|
|
768
776
|
};
|
|
769
777
|
return rulesetOutputExecutionSkip;
|
|
@@ -787,7 +795,7 @@ class EngineDebugger {
|
|
|
787
795
|
*/
|
|
788
796
|
handleDebugRulesetExecutionInfo(currRes, prevRes, allExecutionsValid, rulesetInputFacts, runtimeFactValues, executionCounter, ruleset) {
|
|
789
797
|
const rulesetTriggers = retrieveRulesetTriggers(currRes, prevRes);
|
|
790
|
-
const rulesetOutputExecution = currRes.map(r => r.evaluation);
|
|
798
|
+
const rulesetOutputExecution = currRes.map((r) => r.evaluation);
|
|
791
799
|
if (!allExecutionsValid) {
|
|
792
800
|
this.addRulesetExecutionErrorEvent(ruleset, rulesetInputFacts, executionCounter, runtimeFactValues, rulesetTriggers, rulesetOutputExecution);
|
|
793
801
|
}
|
|
@@ -819,13 +827,13 @@ class EngineDebugger {
|
|
|
819
827
|
activeRulesetsChange(ruleSetExecutorMap, restrictiveRuleSets) {
|
|
820
828
|
const timestamp = Date.now();
|
|
821
829
|
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);
|
|
830
|
+
const activeRulesets = restrictiveRuleSets
|
|
831
|
+
? Object.values(rulesets).filter((ruleSet) => restrictiveRuleSets.includes(ruleSet.id))
|
|
832
|
+
: Object.values(rulesets);
|
|
825
833
|
this.debugEventsSubject$.next(() => ({
|
|
826
834
|
timestamp,
|
|
827
835
|
type: 'ActiveRulesets',
|
|
828
|
-
rulesets: activeRulesets.map(a => ({ name: ruleSetExecutorMap[a.id].ruleset.name, id: ruleSetExecutorMap[a.id].ruleset.id }))
|
|
836
|
+
rulesets: activeRulesets.map((a) => ({ name: ruleSetExecutorMap[a.id].ruleset.name, id: ruleSetExecutorMap[a.id].ruleset.id }))
|
|
829
837
|
}));
|
|
830
838
|
}
|
|
831
839
|
/**
|
|
@@ -845,7 +853,6 @@ class EngineDebugger {
|
|
|
845
853
|
* @param runtimeFactValues
|
|
846
854
|
* @param rulesetTriggers
|
|
847
855
|
* @param rulesExecutions
|
|
848
|
-
* @param retrieveFactFunc
|
|
849
856
|
*/
|
|
850
857
|
addRulesetExecutionEvent(ruleset, executionCounter, rulesetInputFacts, allOutputActions, runtimeFactValues, rulesetTriggers, rulesExecutions) {
|
|
851
858
|
const timestamp = Date.now();
|
|
@@ -859,7 +866,6 @@ class EngineDebugger {
|
|
|
859
866
|
* @param runtimeFactValues
|
|
860
867
|
* @param rulesetTriggers
|
|
861
868
|
* @param rulesExecutions
|
|
862
|
-
* @param retrieveFactFunc
|
|
863
869
|
*/
|
|
864
870
|
addRulesetExecutionErrorEvent(ruleset, rulesetInputFacts, executionCounter, runtimeFactValues, rulesetTriggers, rulesExecutions) {
|
|
865
871
|
const timestamp = Date.now();
|
|
@@ -888,9 +894,9 @@ class EngineDebugger {
|
|
|
888
894
|
function filterRulesetsEventStream(restrictiveRuleSets) {
|
|
889
895
|
return (source$) => source$.pipe(switchMap((ruleSetExecutorMap) => {
|
|
890
896
|
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);
|
|
897
|
+
const activeRulesets = restrictiveRuleSets
|
|
898
|
+
? Object.values(rulesets).filter((ruleSet) => restrictiveRuleSets.includes(ruleSet.id))
|
|
899
|
+
: Object.values(rulesets);
|
|
894
900
|
return combineLatest(activeRulesets.map((ruleset) => ruleset.rulesResultsSubject$)).pipe(map((item) => item.reduce((acc, currentValue) => {
|
|
895
901
|
acc.push(...currentValue);
|
|
896
902
|
return acc;
|
|
@@ -934,19 +940,19 @@ function executeOperator(lhs, rhs, operator, operatorFacts) {
|
|
|
934
940
|
* @param operand value of one of the operands
|
|
935
941
|
*/
|
|
936
942
|
function numberValidator(operand) {
|
|
937
|
-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
938
|
-
return operand !== '' && !Array.isArray(operand) && !isNaN(+`${operand}`);
|
|
943
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions -- needed to convert any variable in a number (or NaN)
|
|
944
|
+
return operand !== '' && !Array.isArray(operand) && !Number.isNaN(+`${operand}`);
|
|
939
945
|
}
|
|
940
946
|
/**
|
|
941
947
|
* Validate an operand is a range of numbers
|
|
942
948
|
* @param operatorInput value of one of the operands
|
|
943
949
|
*/
|
|
944
950
|
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];
|
|
951
|
+
return Array.isArray(operatorInput)
|
|
952
|
+
&& operatorInput.length === 2
|
|
953
|
+
&& numberValidator(operatorInput[0])
|
|
954
|
+
&& numberValidator(operatorInput[1])
|
|
955
|
+
&& operatorInput[0] <= operatorInput[1];
|
|
950
956
|
}
|
|
951
957
|
/**
|
|
952
958
|
* Verifies if the parameter is a valid date for the operator (getTime function available returning a number)
|
|
@@ -957,25 +963,25 @@ const isValidDate = (operatorInput) => {
|
|
|
957
963
|
return false;
|
|
958
964
|
}
|
|
959
965
|
const getTimeResult = operatorInput.getTime();
|
|
960
|
-
return typeof getTimeResult === 'number' && !isNaN(getTimeResult);
|
|
966
|
+
return typeof getTimeResult === 'number' && !Number.isNaN(getTimeResult);
|
|
961
967
|
};
|
|
962
968
|
/**
|
|
963
969
|
* Verifies if the parameter is a valid input for Date constructor (new Date returns a valid date)
|
|
964
970
|
* @param operatorInput
|
|
965
971
|
*/
|
|
966
972
|
const isValidDateInput = (operatorInput) => {
|
|
967
|
-
return operatorInput === 0 || !!operatorInput && isValidDate(new Date(operatorInput));
|
|
973
|
+
return operatorInput === 0 || (!!operatorInput && isValidDate(new Date(operatorInput)));
|
|
968
974
|
};
|
|
969
975
|
/**
|
|
970
976
|
* Verifies if the parameter is a valid date range
|
|
971
977
|
* @param operatorInput
|
|
972
978
|
*/
|
|
973
979
|
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]);
|
|
980
|
+
return Array.isArray(operatorInput)
|
|
981
|
+
&& operatorInput.length === 2
|
|
982
|
+
&& isValidDateInput(operatorInput[0])
|
|
983
|
+
&& isValidDateInput(operatorInput[1])
|
|
984
|
+
&& new Date(operatorInput[0]) <= new Date(operatorInput[1]);
|
|
979
985
|
};
|
|
980
986
|
/**
|
|
981
987
|
* Validate that a value is a supported simple type
|
|
@@ -993,8 +999,6 @@ function isString(value) {
|
|
|
993
999
|
}
|
|
994
1000
|
/**
|
|
995
1001
|
* 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
1002
|
* @param inputRegExp
|
|
999
1003
|
*/
|
|
1000
1004
|
function parseRegExp(inputRegExp) {
|
|
@@ -1013,7 +1017,7 @@ function parseRegExp(inputRegExp) {
|
|
|
1013
1017
|
*/
|
|
1014
1018
|
const arrayContains = {
|
|
1015
1019
|
name: 'arrayContains',
|
|
1016
|
-
evaluator: (value, b) => value.
|
|
1020
|
+
evaluator: (value, b) => value.includes(b),
|
|
1017
1021
|
validateLhs: Array.isArray,
|
|
1018
1022
|
validateRhs: isSupportedSimpleTypes
|
|
1019
1023
|
};
|
|
@@ -1023,7 +1027,7 @@ const arrayContains = {
|
|
|
1023
1027
|
*/
|
|
1024
1028
|
const stringContains = {
|
|
1025
1029
|
name: 'stringContains',
|
|
1026
|
-
evaluator: (inputString, substring) => inputString.
|
|
1030
|
+
evaluator: (inputString, substring) => inputString.includes(substring),
|
|
1027
1031
|
validateLhs: isString,
|
|
1028
1032
|
validateRhs: isString
|
|
1029
1033
|
};
|
|
@@ -1033,7 +1037,7 @@ const stringContains = {
|
|
|
1033
1037
|
*/
|
|
1034
1038
|
const notArrayContains = {
|
|
1035
1039
|
name: 'notArrayContains',
|
|
1036
|
-
evaluator: (array, value) => array.
|
|
1040
|
+
evaluator: (array, value) => !array.includes(value),
|
|
1037
1041
|
validateLhs: Array.isArray,
|
|
1038
1042
|
validateRhs: isSupportedSimpleTypes
|
|
1039
1043
|
};
|
|
@@ -1043,7 +1047,7 @@ const notArrayContains = {
|
|
|
1043
1047
|
*/
|
|
1044
1048
|
const notStringContains = {
|
|
1045
1049
|
name: 'notStringContains',
|
|
1046
|
-
evaluator: (inputString, substring) => inputString.
|
|
1050
|
+
evaluator: (inputString, substring) => !inputString.includes(substring),
|
|
1047
1051
|
validateLhs: isString,
|
|
1048
1052
|
validateRhs: isString
|
|
1049
1053
|
};
|
|
@@ -1053,7 +1057,7 @@ const notStringContains = {
|
|
|
1053
1057
|
*/
|
|
1054
1058
|
const allEqual = {
|
|
1055
1059
|
name: 'allEqual',
|
|
1056
|
-
// eslint-disable-next-line eqeqeq
|
|
1060
|
+
// eslint-disable-next-line eqeqeq -- possibility of comparing string and number values
|
|
1057
1061
|
evaluator: (array, value) => array.every((elementValue) => elementValue == value),
|
|
1058
1062
|
validateLhs: Array.isArray,
|
|
1059
1063
|
validateRhs: isSupportedSimpleTypes
|
|
@@ -1074,7 +1078,7 @@ const allGreater = {
|
|
|
1074
1078
|
*/
|
|
1075
1079
|
const allIn = {
|
|
1076
1080
|
name: 'allIn',
|
|
1077
|
-
evaluator: (array, value) => array.every((elementValue) => value.
|
|
1081
|
+
evaluator: (array, value) => array.every((elementValue) => value.includes(elementValue)),
|
|
1078
1082
|
validateLhs: Array.isArray,
|
|
1079
1083
|
validateRhs: Array.isArray
|
|
1080
1084
|
};
|
|
@@ -1084,7 +1088,7 @@ const allIn = {
|
|
|
1084
1088
|
*/
|
|
1085
1089
|
const allNotIn = {
|
|
1086
1090
|
name: 'allNotIn',
|
|
1087
|
-
evaluator: (array, value) => !array.some((elementValue) => value.
|
|
1091
|
+
evaluator: (array, value) => !array.some((elementValue) => value.includes(elementValue)),
|
|
1088
1092
|
validateLhs: Array.isArray,
|
|
1089
1093
|
validateRhs: Array.isArray
|
|
1090
1094
|
};
|
|
@@ -1127,7 +1131,7 @@ const allRangeNumber = {
|
|
|
1127
1131
|
*/
|
|
1128
1132
|
const oneEquals = {
|
|
1129
1133
|
name: 'oneEquals',
|
|
1130
|
-
// eslint-disable-next-line eqeqeq
|
|
1134
|
+
// eslint-disable-next-line eqeqeq -- possibility of comparing string and number values
|
|
1131
1135
|
evaluator: (array, value) => array.some((elementValue) => elementValue == value),
|
|
1132
1136
|
validateLhs: Array.isArray,
|
|
1133
1137
|
validateRhs: isSupportedSimpleTypes
|
|
@@ -1148,7 +1152,7 @@ const oneGreater = {
|
|
|
1148
1152
|
*/
|
|
1149
1153
|
const oneIn = {
|
|
1150
1154
|
name: 'oneIn',
|
|
1151
|
-
evaluator: (firstArray, secondArray) => firstArray.some((elementValue) => secondArray.
|
|
1155
|
+
evaluator: (firstArray, secondArray) => firstArray.some((elementValue) => secondArray.includes(elementValue)),
|
|
1152
1156
|
validateLhs: Array.isArray,
|
|
1153
1157
|
validateRhs: Array.isArray
|
|
1154
1158
|
};
|
|
@@ -1278,7 +1282,7 @@ const arrayBasedOperators = [
|
|
|
1278
1282
|
*/
|
|
1279
1283
|
const equals = {
|
|
1280
1284
|
name: 'equals',
|
|
1281
|
-
// eslint-disable-next-line
|
|
1285
|
+
// eslint-disable-next-line eqeqeq -- possibility of comparing string and number values
|
|
1282
1286
|
evaluator: (firstValue, secondValue) => firstValue == secondValue
|
|
1283
1287
|
};
|
|
1284
1288
|
/**
|
|
@@ -1287,7 +1291,7 @@ const equals = {
|
|
|
1287
1291
|
*/
|
|
1288
1292
|
const notEquals = {
|
|
1289
1293
|
name: 'notEquals',
|
|
1290
|
-
// eslint-disable-next-line eqeqeq
|
|
1294
|
+
// eslint-disable-next-line eqeqeq -- possibility of comparing string and number values
|
|
1291
1295
|
evaluator: (firstValue, secondValue) => firstValue != secondValue
|
|
1292
1296
|
};
|
|
1293
1297
|
/**
|
|
@@ -1296,7 +1300,7 @@ const notEquals = {
|
|
|
1296
1300
|
*/
|
|
1297
1301
|
const inArray = {
|
|
1298
1302
|
name: 'inArray',
|
|
1299
|
-
evaluator: (value, array) => array.
|
|
1303
|
+
evaluator: (value, array) => array.includes(value),
|
|
1300
1304
|
validateLhs: isSupportedSimpleTypes,
|
|
1301
1305
|
validateRhs: Array.isArray
|
|
1302
1306
|
};
|
|
@@ -1306,7 +1310,7 @@ const inArray = {
|
|
|
1306
1310
|
*/
|
|
1307
1311
|
const notInArray = {
|
|
1308
1312
|
name: 'notInArray',
|
|
1309
|
-
evaluator: (value, array) => array.
|
|
1313
|
+
evaluator: (value, array) => !array.includes(value),
|
|
1310
1314
|
validateLhs: isSupportedSimpleTypes,
|
|
1311
1315
|
validateRhs: Array.isArray
|
|
1312
1316
|
};
|
|
@@ -1316,7 +1320,7 @@ const notInArray = {
|
|
|
1316
1320
|
*/
|
|
1317
1321
|
const inString = {
|
|
1318
1322
|
name: 'inString',
|
|
1319
|
-
evaluator: (value, inputString) => inputString.
|
|
1323
|
+
evaluator: (value, inputString) => inputString.includes(value),
|
|
1320
1324
|
validateLhs: isString,
|
|
1321
1325
|
validateRhs: isString
|
|
1322
1326
|
};
|
|
@@ -1326,7 +1330,7 @@ const inString = {
|
|
|
1326
1330
|
*/
|
|
1327
1331
|
const notInString = {
|
|
1328
1332
|
name: 'notInString',
|
|
1329
|
-
evaluator: (value, inputString) => inputString.
|
|
1333
|
+
evaluator: (value, inputString) => !inputString.includes(value),
|
|
1330
1334
|
validateLhs: isString,
|
|
1331
1335
|
validateRhs: isString
|
|
1332
1336
|
};
|
|
@@ -1364,49 +1368,6 @@ const basicOperators = [
|
|
|
1364
1368
|
equals, inArray, inString, isDefined, isUndefined, matchesPattern, notEquals, notInArray, notInString
|
|
1365
1369
|
];
|
|
1366
1370
|
|
|
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
1371
|
/**
|
|
1411
1372
|
* Check if a date variable is in a specified date range
|
|
1412
1373
|
* @title is between
|
|
@@ -1435,7 +1396,7 @@ const dateInNextMinutes = {
|
|
|
1435
1396
|
throw new Error('o3rCurrentTime value is not a number');
|
|
1436
1397
|
}
|
|
1437
1398
|
const currentTimeValue = operatorFactValues.o3rCurrentTime;
|
|
1438
|
-
return inRangeDate.evaluator(leftDateInput, [currentTimeValue, currentTimeValue + +minutes *
|
|
1399
|
+
return inRangeDate.evaluator(leftDateInput, [currentTimeValue, currentTimeValue + +minutes * 60_000]);
|
|
1439
1400
|
},
|
|
1440
1401
|
factImplicitDependencies: ['o3rCurrentTime'],
|
|
1441
1402
|
validateLhs: isValidDateInput,
|
|
@@ -1525,6 +1486,49 @@ const dateBasedOperators = [
|
|
|
1525
1486
|
inRangeDate, dateInNextMinutes, dateNotInNextMinutes, dateAfter, dateBefore, dateEquals, dateNotEquals
|
|
1526
1487
|
];
|
|
1527
1488
|
|
|
1489
|
+
/**
|
|
1490
|
+
* Check if the number variable is greater or equal to a specific value
|
|
1491
|
+
* @title ≥
|
|
1492
|
+
*/
|
|
1493
|
+
const greaterThanOrEqual = {
|
|
1494
|
+
name: 'greaterThanOrEqual',
|
|
1495
|
+
evaluator: (firstNumber, secondNumber) => firstNumber >= secondNumber,
|
|
1496
|
+
validateLhs: numberValidator,
|
|
1497
|
+
validateRhs: numberValidator
|
|
1498
|
+
};
|
|
1499
|
+
/**
|
|
1500
|
+
* Check if the number variable is greater than a specific value
|
|
1501
|
+
* @title >
|
|
1502
|
+
*/
|
|
1503
|
+
const greaterThan = {
|
|
1504
|
+
name: 'greaterThan',
|
|
1505
|
+
evaluator: (firstNumber, secondNumber) => firstNumber > secondNumber,
|
|
1506
|
+
validateLhs: numberValidator,
|
|
1507
|
+
validateRhs: numberValidator
|
|
1508
|
+
};
|
|
1509
|
+
/**
|
|
1510
|
+
* Check if the number variable is lower or equal to a specific value
|
|
1511
|
+
* @title ≤
|
|
1512
|
+
*/
|
|
1513
|
+
const lessOrEqual = {
|
|
1514
|
+
name: 'lessOrEqual',
|
|
1515
|
+
evaluator: (firstNumber, secondNumber) => firstNumber <= secondNumber,
|
|
1516
|
+
validateLhs: numberValidator,
|
|
1517
|
+
validateRhs: numberValidator
|
|
1518
|
+
};
|
|
1519
|
+
/**
|
|
1520
|
+
* Check if the number variable is lower than a specific value
|
|
1521
|
+
* @title <
|
|
1522
|
+
*/
|
|
1523
|
+
const lessThan = {
|
|
1524
|
+
name: 'lessThan',
|
|
1525
|
+
evaluator: (firstNumber, secondNumber) => firstNumber < secondNumber,
|
|
1526
|
+
validateLhs: numberValidator,
|
|
1527
|
+
validateRhs: numberValidator
|
|
1528
|
+
};
|
|
1529
|
+
/** List of all default number based operators */
|
|
1530
|
+
const numberBasedOperators = [greaterThan, greaterThanOrEqual, lessThan, lessOrEqual];
|
|
1531
|
+
|
|
1528
1532
|
const operatorList = [...arrayBasedOperators, ...basicOperators, ...numberBasedOperators, ...dateBasedOperators];
|
|
1529
1533
|
|
|
1530
1534
|
/**
|
|
@@ -1586,6 +1590,15 @@ class RulesetExecutor {
|
|
|
1586
1590
|
*/
|
|
1587
1591
|
constructor(ruleset, rulesEngine) {
|
|
1588
1592
|
this.executionCounter = 0;
|
|
1593
|
+
/**
|
|
1594
|
+
* Find rule input facts
|
|
1595
|
+
* @param obj
|
|
1596
|
+
*/
|
|
1597
|
+
this.findRuleInputFacts = (obj) => {
|
|
1598
|
+
const ruleInputFacts = new Set();
|
|
1599
|
+
this.collectRuleInputFacts(obj, ruleInputFacts);
|
|
1600
|
+
return Array.from(ruleInputFacts);
|
|
1601
|
+
};
|
|
1589
1602
|
this.ruleset = ruleset;
|
|
1590
1603
|
this.rulesEngine = rulesEngine;
|
|
1591
1604
|
this.operators = rulesEngine.operators;
|
|
@@ -1609,7 +1622,7 @@ class RulesetExecutor {
|
|
|
1609
1622
|
if ((key === 'operator') && isConditionProperties(currentObject)) {
|
|
1610
1623
|
const op = this.operators[currentObject[key]];
|
|
1611
1624
|
if (op && op.factImplicitDependencies) {
|
|
1612
|
-
op.factImplicitDependencies.forEach(dep => ruleInputFacts.add(dep));
|
|
1625
|
+
op.factImplicitDependencies.forEach((dep) => ruleInputFacts.add(dep));
|
|
1613
1626
|
}
|
|
1614
1627
|
}
|
|
1615
1628
|
else if (typeof currentObject[key] === 'object') {
|
|
@@ -1644,7 +1657,7 @@ class RulesetExecutor {
|
|
|
1644
1657
|
}
|
|
1645
1658
|
else if (isOperandFact(operand)) {
|
|
1646
1659
|
const factValue = factsValue[operand.value];
|
|
1647
|
-
// eslint-disable-next-line new-cap
|
|
1660
|
+
// eslint-disable-next-line new-cap -- convention for JSONPath
|
|
1648
1661
|
return operand.path ? factValue && JSONPath({ wrap: false, json: factValue, path: operand.path }) : factValue;
|
|
1649
1662
|
}
|
|
1650
1663
|
else if (isOperandLiteral(operand)) {
|
|
@@ -1671,9 +1684,9 @@ class RulesetExecutor {
|
|
|
1671
1684
|
* Recursively process a block to extract all the actions keeping the order
|
|
1672
1685
|
* Note that runtimeFactValues will be mutated by all the runtime facts actions executed
|
|
1673
1686
|
* @param element
|
|
1674
|
-
* @param actions
|
|
1675
1687
|
* @param factsValue
|
|
1676
1688
|
* @param runtimeFactValues This runtime fact map will be mutated by all the runtime facts actions executed
|
|
1689
|
+
* @param actions
|
|
1677
1690
|
* @protected
|
|
1678
1691
|
*/
|
|
1679
1692
|
evaluateBlock(element, factsValue, runtimeFactValues, actions = []) {
|
|
@@ -1735,7 +1748,7 @@ class RulesetExecutor {
|
|
|
1735
1748
|
}
|
|
1736
1749
|
if (nestedCondition.all || nestedCondition.any) {
|
|
1737
1750
|
const evaluate = (condition) => this.evaluateCondition(condition, factsValue, runtimeFactValues);
|
|
1738
|
-
return isAllConditions(nestedCondition) ? nestedCondition.all.every(evaluate) : nestedCondition.any.some(evaluate);
|
|
1751
|
+
return isAllConditions(nestedCondition) ? nestedCondition.all.every((element) => evaluate(element)) : nestedCondition.any.some((element) => evaluate(element));
|
|
1739
1752
|
}
|
|
1740
1753
|
throw new Error(`Unknown condition block met : ${JSON.stringify(nestedCondition)}`);
|
|
1741
1754
|
}
|
|
@@ -1744,22 +1757,17 @@ class RulesetExecutor {
|
|
|
1744
1757
|
*/
|
|
1745
1758
|
plugRuleset() {
|
|
1746
1759
|
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));
|
|
1760
|
+
this.ruleset.rules.forEach((rule) => inputFactsForRule[rule.id] = this.findRuleInputFacts(rule.rootElement));
|
|
1753
1761
|
const factsThatRerunEverything = [];
|
|
1754
1762
|
this.ruleset.rules.forEach((rule) => {
|
|
1755
1763
|
if (rule.outputRuntimeFacts.length > 0 || rule.inputRuntimeFacts.length > 0) {
|
|
1756
1764
|
factsThatRerunEverything.push(...inputFactsForRule[rule.id]);
|
|
1757
1765
|
}
|
|
1758
|
-
else {
|
|
1759
|
-
}
|
|
1766
|
+
else { }
|
|
1760
1767
|
});
|
|
1761
|
-
const triggerFull$ = factsThatRerunEverything.length === 0
|
|
1762
|
-
|
|
1768
|
+
const triggerFull$ = factsThatRerunEverything.length === 0
|
|
1769
|
+
? of([])
|
|
1770
|
+
: combineLatest(factsThatRerunEverything.map((fact) => this.rulesEngine.retrieveOrCreateFactStream(fact)));
|
|
1763
1771
|
const result$ = triggerFull$.pipe(switchMap(() => {
|
|
1764
1772
|
const runtimeFactValues = {};
|
|
1765
1773
|
let rulesetInputFacts;
|
|
@@ -1772,7 +1780,7 @@ class RulesetExecutor {
|
|
|
1772
1780
|
return combineLatest(this.ruleset.rules.map((rule) => {
|
|
1773
1781
|
const inputFacts = inputFactsForRule[rule.id];
|
|
1774
1782
|
const values$ = inputFacts.map((fact) => this.rulesEngine.retrieveOrCreateFactStream(fact));
|
|
1775
|
-
return (values$.length ? combineLatest(values$) : of([[]]))
|
|
1783
|
+
return (values$.length > 0 ? combineLatest(values$) : of([[]]))
|
|
1776
1784
|
.pipe(startWith(undefined), pairwise(), tap(() => this.performanceMark(rule, 'start')), map(([oldFactValues, factValues]) => {
|
|
1777
1785
|
const output = { actions: undefined };
|
|
1778
1786
|
try {
|
|
@@ -1795,7 +1803,7 @@ class RulesetExecutor {
|
|
|
1795
1803
|
return output;
|
|
1796
1804
|
}), tap(() => this.performanceMark(rule, 'end')));
|
|
1797
1805
|
})).pipe(startWith(undefined), pairwise(), map(([prevRes, currRes]) => {
|
|
1798
|
-
const actionsLists = currRes.map(r => r.actions);
|
|
1806
|
+
const actionsLists = currRes.map((r) => r.actions);
|
|
1799
1807
|
const allExecutionsValid = actionsLists.every((actions) => !!actions);
|
|
1800
1808
|
let execInfo = { actionsLists: (allExecutionsValid ? actionsLists : [[]]) };
|
|
1801
1809
|
if (this.rulesEngine.engineDebug) {
|
|
@@ -1834,14 +1842,13 @@ class RulesEngine {
|
|
|
1834
1842
|
/**
|
|
1835
1843
|
* Rules engine
|
|
1836
1844
|
* @param options rules engine options
|
|
1837
|
-
* @param logger
|
|
1838
1845
|
*/
|
|
1839
1846
|
constructor(options) {
|
|
1840
1847
|
/** Map of registered fact stream, this map is mutated by the ruleset executors */
|
|
1841
1848
|
this.factMap = {};
|
|
1842
1849
|
/** Subject containing the rulesets and the results stream*/
|
|
1843
1850
|
this.rulesetMapSubject = new BehaviorSubject({});
|
|
1844
|
-
this.performance = options?.performance || (typeof window
|
|
1851
|
+
this.performance = options?.performance || (typeof window === 'undefined' ? undefined : window.performance);
|
|
1845
1852
|
this.engineDebug = options?.debugger;
|
|
1846
1853
|
this.engineDebug?.registerRuleEngine(this);
|
|
1847
1854
|
this.logger = options?.logger;
|
|
@@ -1865,7 +1872,6 @@ class RulesEngine {
|
|
|
1865
1872
|
}
|
|
1866
1873
|
/**
|
|
1867
1874
|
* Attach debug events to actions stream if debug engine is activated
|
|
1868
|
-
* @param actionsStream
|
|
1869
1875
|
*/
|
|
1870
1876
|
handleActionsStreamOutput() {
|
|
1871
1877
|
return (actionsStream$) => this.engineDebug ? actionsStream$.pipe(tap((allActions) => this.engineDebug.allActionsChange(allActions))) : actionsStream$;
|
|
@@ -1875,8 +1881,8 @@ class RulesEngine {
|
|
|
1875
1881
|
* @param ruleSets
|
|
1876
1882
|
*/
|
|
1877
1883
|
prepareActionsStream(ruleSets) {
|
|
1878
|
-
return (rulesetMapSubject$) => (this.engineDebug
|
|
1879
|
-
rulesetMapSubject$.pipe(tap((ruleSetExecutorMap) => this.engineDebug.activeRulesetsChange(ruleSetExecutorMap, ruleSets)), filterRulesetsEventStream(ruleSets))
|
|
1884
|
+
return (rulesetMapSubject$) => (this.engineDebug
|
|
1885
|
+
? rulesetMapSubject$.pipe(tap((ruleSetExecutorMap) => this.engineDebug.activeRulesetsChange(ruleSetExecutorMap, ruleSets)), filterRulesetsEventStream(ruleSets))
|
|
1880
1886
|
: rulesetMapSubject$.pipe(filterRulesetsEventStream(ruleSets)));
|
|
1881
1887
|
}
|
|
1882
1888
|
/**
|
|
@@ -1887,9 +1893,9 @@ class RulesEngine {
|
|
|
1887
1893
|
*/
|
|
1888
1894
|
retrieveOrCreateFactStream(id, factValue$) {
|
|
1889
1895
|
// 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$;
|
|
1896
|
+
const obs$ = factValue$
|
|
1897
|
+
? merge(factValue$, of(undefined).pipe(delay(this.factDefaultDelay || 0), takeUntil(factValue$)))
|
|
1898
|
+
: factValue$;
|
|
1893
1899
|
const factObj = this.factMap[id];
|
|
1894
1900
|
if (factObj) {
|
|
1895
1901
|
if (factValue$) {
|
|
@@ -1922,7 +1928,6 @@ class RulesEngine {
|
|
|
1922
1928
|
}
|
|
1923
1929
|
/**
|
|
1924
1930
|
* Update or insert rule in rules engine
|
|
1925
|
-
* @param rules rule list to add / update
|
|
1926
1931
|
* @param rulesets
|
|
1927
1932
|
*/
|
|
1928
1933
|
upsertRulesets(rulesets) {
|
|
@@ -1955,19 +1960,10 @@ class RulesEngine {
|
|
|
1955
1960
|
}
|
|
1956
1961
|
}
|
|
1957
1962
|
|
|
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
1963
|
class RulesEngineRunnerService {
|
|
1967
1964
|
constructor(store, logger, engineConfig) {
|
|
1968
1965
|
this.store = store;
|
|
1969
1966
|
this.logger = logger;
|
|
1970
|
-
this.subscription = new Subscription();
|
|
1971
1967
|
/** Observable of component linked to the component */
|
|
1972
1968
|
this.linkedComponents$ = new BehaviorSubject({});
|
|
1973
1969
|
/**
|
|
@@ -1986,10 +1982,10 @@ class RulesEngineRunnerService {
|
|
|
1986
1982
|
]).pipe(map(([activeRulesets, linkedComponentsRulesetsIds]) => ([...activeRulesets, ...linkedComponentsRulesetsIds])));
|
|
1987
1983
|
this.events$ = this.ruleSets$.pipe(this.engine.getEventStream(), shareReplay(1));
|
|
1988
1984
|
this.upsertOperators(operatorList);
|
|
1989
|
-
this.
|
|
1990
|
-
this.
|
|
1991
|
-
|
|
1992
|
-
})
|
|
1985
|
+
this.store.pipe(select(selectAllRulesets), takeUntilDestroyed()).subscribe((rulesets) => this.engine.upsertRulesets(rulesets));
|
|
1986
|
+
this.events$.pipe(takeUntilDestroyed(), filter(() => this.enabled)).subscribe((events) => {
|
|
1987
|
+
void this.executeActions(events);
|
|
1988
|
+
});
|
|
1993
1989
|
}
|
|
1994
1990
|
/**
|
|
1995
1991
|
* Execute the list of actions
|
|
@@ -1997,7 +1993,7 @@ class RulesEngineRunnerService {
|
|
|
1997
1993
|
*/
|
|
1998
1994
|
async executeActions(actions) {
|
|
1999
1995
|
const actionHandlers = [...this.actionHandlers];
|
|
2000
|
-
const supportedActions = new Set(actionHandlers.
|
|
1996
|
+
const supportedActions = new Set(actionHandlers.flatMap((handler) => handler.supportingActions));
|
|
2001
1997
|
const actionMaps = actions
|
|
2002
1998
|
.filter((action) => {
|
|
2003
1999
|
const isKnown = supportedActions.has(action.actionType);
|
|
@@ -2052,10 +2048,6 @@ class RulesEngineRunnerService {
|
|
|
2052
2048
|
unregisterActionHandlers(...actionHandlers) {
|
|
2053
2049
|
actionHandlers.forEach((actionHandler) => this.actionHandlers.delete(actionHandler));
|
|
2054
2050
|
}
|
|
2055
|
-
/** @inheritdoc */
|
|
2056
|
-
ngOnDestroy() {
|
|
2057
|
-
this.subscription.unsubscribe();
|
|
2058
|
-
}
|
|
2059
2051
|
/**
|
|
2060
2052
|
* Enable temporary a rule set
|
|
2061
2053
|
* @param componentComputedName Name of the component to enable the ruleset for
|
|
@@ -2076,10 +2068,10 @@ class RulesEngineRunnerService {
|
|
|
2076
2068
|
this.linkedComponents$.next(newMap);
|
|
2077
2069
|
}
|
|
2078
2070
|
}
|
|
2079
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2080
|
-
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.
|
|
2071
|
+
/** @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 }); }
|
|
2072
|
+
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerService }); }
|
|
2081
2073
|
}
|
|
2082
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2074
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerService, decorators: [{
|
|
2083
2075
|
type: Injectable
|
|
2084
2076
|
}], ctorParameters: () => [{ type: i1$2.Store }, { type: i2.LoggerService }, { type: undefined, decorators: [{
|
|
2085
2077
|
type: Optional
|
|
@@ -2099,15 +2091,15 @@ class RulesEngineRunnerModule {
|
|
|
2099
2091
|
]
|
|
2100
2092
|
};
|
|
2101
2093
|
}
|
|
2102
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2103
|
-
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.
|
|
2094
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2095
|
+
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerModule, imports: [StoreModule,
|
|
2104
2096
|
RulesetsStoreModule,
|
|
2105
2097
|
LoggerModule] }); }
|
|
2106
|
-
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.
|
|
2098
|
+
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerModule, imports: [StoreModule,
|
|
2107
2099
|
RulesetsStoreModule,
|
|
2108
2100
|
LoggerModule] }); }
|
|
2109
2101
|
}
|
|
2110
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2102
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineRunnerModule, decorators: [{
|
|
2111
2103
|
type: NgModule,
|
|
2112
2104
|
args: [{
|
|
2113
2105
|
imports: [
|
|
@@ -2155,17 +2147,17 @@ class OtterRulesEngineDevtools {
|
|
|
2155
2147
|
}
|
|
2156
2148
|
/** Returns the list of active rulesets (name and id) at the moment when the function is called */
|
|
2157
2149
|
async getActiveRulesets() {
|
|
2158
|
-
const lastActiveRulesetsEvent = (this.rulesEngineEvents$ && await firstValueFrom(this.rulesEngineEvents$))?.filter(e => e.type === 'ActiveRulesets').reverse()[0];
|
|
2150
|
+
const lastActiveRulesetsEvent = (this.rulesEngineEvents$ && await firstValueFrom(this.rulesEngineEvents$))?.filter((e) => e.type === 'ActiveRulesets').reverse()[0];
|
|
2159
2151
|
return lastActiveRulesetsEvent?.rulesets;
|
|
2160
2152
|
}
|
|
2161
2153
|
/** Returns the list of available rulesets (name and id) at the moment when the function is called */
|
|
2162
2154
|
async getAvailableRulesets() {
|
|
2163
|
-
const lastAvailableRulesetsEvent = (this.rulesEngineEvents$ && await firstValueFrom(this.rulesEngineEvents$))?.filter(e => e.type === 'AvailableRulesets').reverse()[0];
|
|
2155
|
+
const lastAvailableRulesetsEvent = (this.rulesEngineEvents$ && await firstValueFrom(this.rulesEngineEvents$))?.filter((e) => e.type === 'AvailableRulesets').reverse()[0];
|
|
2164
2156
|
return lastAvailableRulesetsEvent?.availableRulesets;
|
|
2165
2157
|
}
|
|
2166
2158
|
/** Returns the list of output actions emitted by the rules engine at the moment when the function is called */
|
|
2167
2159
|
async getAllOutputActions() {
|
|
2168
|
-
return (this.rulesEngineEvents$ && await firstValueFrom(this.rulesEngineEvents$))?.filter(e => e.type === 'AllActions')?.reverse()[0];
|
|
2160
|
+
return (this.rulesEngineEvents$ && await firstValueFrom(this.rulesEngineEvents$))?.filter((e) => e.type === 'AllActions')?.reverse()[0];
|
|
2169
2161
|
}
|
|
2170
2162
|
/**
|
|
2171
2163
|
* Get the list of executions for the given ruleset
|
|
@@ -2181,7 +2173,7 @@ class OtterRulesEngineDevtools {
|
|
|
2181
2173
|
* @returns True if the ruleset is active; False if the ruleset is inactive or it does not exist
|
|
2182
2174
|
*/
|
|
2183
2175
|
async isRulesetActive(rulesetId) {
|
|
2184
|
-
return !!(await this.getActiveRulesets())?.find(r => r.id === rulesetId);
|
|
2176
|
+
return !!(await this.getActiveRulesets())?.find((r) => r.id === rulesetId);
|
|
2185
2177
|
}
|
|
2186
2178
|
/**
|
|
2187
2179
|
* Get the list of rules executed for the specified ruleset
|
|
@@ -2189,7 +2181,7 @@ class OtterRulesEngineDevtools {
|
|
|
2189
2181
|
*/
|
|
2190
2182
|
async getRulesEvaluationsForRuleset(rulesetId) {
|
|
2191
2183
|
const rulesetExec = await this.getRulesetExecutions(rulesetId);
|
|
2192
|
-
return rulesetExec?.map(e => e?.rulesEvaluations?.filter(re => !re.cached)).flat();
|
|
2184
|
+
return rulesetExec?.map((e) => e?.rulesEvaluations?.filter((re) => !re.cached)).flat();
|
|
2193
2185
|
}
|
|
2194
2186
|
/**
|
|
2195
2187
|
* Get the list of input facts (name, current value) for the specified ruleset, at the moment when the function is called
|
|
@@ -2197,14 +2189,14 @@ class OtterRulesEngineDevtools {
|
|
|
2197
2189
|
*/
|
|
2198
2190
|
async getInputFactsForRuleset(rulesetId) {
|
|
2199
2191
|
const rulesetExecutions = await this.getRulesetExecutions(rulesetId);
|
|
2200
|
-
return rulesetExecutions ? rulesetExecutions
|
|
2192
|
+
return rulesetExecutions ? rulesetExecutions.at(-1).inputFacts : undefined;
|
|
2201
2193
|
}
|
|
2202
2194
|
/**
|
|
2203
2195
|
* Get the list of triggers for the specified ruleset
|
|
2204
2196
|
* @param rulesetId
|
|
2205
2197
|
*/
|
|
2206
2198
|
async getTriggersForRuleset(rulesetId) {
|
|
2207
|
-
return (await this.getRulesEvaluationsForRuleset(rulesetId))?.map(e => e.triggers).flat().
|
|
2199
|
+
return (await this.getRulesEvaluationsForRuleset(rulesetId))?.map((e) => e.triggers).flat().flatMap((triggersMap) => Object.values(triggersMap));
|
|
2208
2200
|
}
|
|
2209
2201
|
/**
|
|
2210
2202
|
* Get the list of outputed actions emitted by the given ruleset, at the moment when the function is called
|
|
@@ -2212,7 +2204,7 @@ class OtterRulesEngineDevtools {
|
|
|
2212
2204
|
*/
|
|
2213
2205
|
async getOutputActionsForRuleset(rulesetId) {
|
|
2214
2206
|
const rulesetExecutions = await this.getRulesetExecutions(rulesetId);
|
|
2215
|
-
return rulesetExecutions ? rulesetExecutions
|
|
2207
|
+
return rulesetExecutions ? rulesetExecutions.at(-1).outputActions : undefined;
|
|
2216
2208
|
}
|
|
2217
2209
|
/** Get the list of fact names and corresponding values */
|
|
2218
2210
|
getAllFactsSnapshot() {
|
|
@@ -2228,10 +2220,10 @@ class OtterRulesEngineDevtools {
|
|
|
2228
2220
|
getRulesetInformation(rulesetId) {
|
|
2229
2221
|
return firstValueFrom(this.store.pipe(select(selectRulesetsEntities), map((entities) => entities[rulesetId])));
|
|
2230
2222
|
}
|
|
2231
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2232
|
-
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.
|
|
2223
|
+
/** @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 }); }
|
|
2224
|
+
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OtterRulesEngineDevtools, providedIn: 'root' }); }
|
|
2233
2225
|
}
|
|
2234
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2226
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OtterRulesEngineDevtools, decorators: [{
|
|
2235
2227
|
type: Injectable,
|
|
2236
2228
|
args: [{
|
|
2237
2229
|
providedIn: 'root'
|
|
@@ -2243,7 +2235,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
2243
2235
|
args: [OTTER_RULES_ENGINE_DEVTOOLS_OPTIONS]
|
|
2244
2236
|
}] }] });
|
|
2245
2237
|
|
|
2246
|
-
/* eslint-disable no-console */
|
|
2238
|
+
/* eslint-disable no-console -- purpose of the service is to log in the console */
|
|
2247
2239
|
class RulesEngineDevtoolsConsoleService {
|
|
2248
2240
|
/** Name of the Window property to access to the devtools */
|
|
2249
2241
|
static { this.windowModuleName = 'rulesEngine'; }
|
|
@@ -2260,9 +2252,7 @@ class RulesEngineDevtoolsConsoleService {
|
|
|
2260
2252
|
/** @inheritDoc */
|
|
2261
2253
|
activate() {
|
|
2262
2254
|
const windowWithDevtools = window;
|
|
2263
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
2264
2255
|
windowWithDevtools._OTTER_DEVTOOLS_ ||= {};
|
|
2265
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
2266
2256
|
windowWithDevtools._OTTER_DEVTOOLS_[RulesEngineDevtoolsConsoleService.windowModuleName] = this;
|
|
2267
2257
|
console.info(`Otter rules engine Devtools is now accessible via the _OTTER_DEVTOOLS_.${RulesEngineDevtoolsConsoleService.windowModuleName} variable`);
|
|
2268
2258
|
}
|
|
@@ -2336,10 +2326,10 @@ class RulesEngineDevtoolsConsoleService {
|
|
|
2336
2326
|
async getRulesetInformation(rulesetId) {
|
|
2337
2327
|
console.log(await this.rulesEngineDevtools.getRulesetInformation(rulesetId));
|
|
2338
2328
|
}
|
|
2339
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2340
|
-
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.
|
|
2329
|
+
/** @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 }); }
|
|
2330
|
+
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsConsoleService, providedIn: 'root' }); }
|
|
2341
2331
|
}
|
|
2342
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2332
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsConsoleService, decorators: [{
|
|
2343
2333
|
type: Injectable,
|
|
2344
2334
|
args: [{
|
|
2345
2335
|
providedIn: 'root'
|
|
@@ -2355,9 +2345,10 @@ class RulesEngineDevtoolsMessageService {
|
|
|
2355
2345
|
constructor(rulesEngineDevtools, logger, options) {
|
|
2356
2346
|
this.rulesEngineDevtools = rulesEngineDevtools;
|
|
2357
2347
|
this.logger = logger;
|
|
2358
|
-
this.subscriptions = new Subscription();
|
|
2359
2348
|
this.forceEmitRulesEngineReport = new BehaviorSubject(undefined);
|
|
2360
2349
|
this.sendMessage = (sendOtterMessage);
|
|
2350
|
+
this.destroyRef = inject(DestroyRef);
|
|
2351
|
+
this.serializeError = (error) => error instanceof Error ? error.toString() : error;
|
|
2361
2352
|
this.options = {
|
|
2362
2353
|
...OTTER_RULES_ENGINE_DEVTOOLS_DEFAULT_OPTIONS,
|
|
2363
2354
|
...options
|
|
@@ -2377,7 +2368,6 @@ class RulesEngineDevtoolsMessageService {
|
|
|
2377
2368
|
}
|
|
2378
2369
|
/**
|
|
2379
2370
|
* Function to handle the incoming messages from Otter Chrome DevTools extension
|
|
2380
|
-
* @param event Event coming from the Otter Chrome DevTools extension
|
|
2381
2371
|
* @param message
|
|
2382
2372
|
*/
|
|
2383
2373
|
handleEvents(message) {
|
|
@@ -2401,7 +2391,6 @@ class RulesEngineDevtoolsMessageService {
|
|
|
2401
2391
|
* @param debugEvent
|
|
2402
2392
|
*/
|
|
2403
2393
|
serializeReportEvent(debugEvent) {
|
|
2404
|
-
const serializeError = (error) => error instanceof Error ? error.toString() : error;
|
|
2405
2394
|
if (debugEvent.type !== 'RulesetExecutionError') {
|
|
2406
2395
|
return debugEvent;
|
|
2407
2396
|
}
|
|
@@ -2409,9 +2398,10 @@ class RulesEngineDevtoolsMessageService {
|
|
|
2409
2398
|
...debugEvent,
|
|
2410
2399
|
rulesEvaluations: debugEvent.rulesEvaluations.map((ruleEvaluation) => ({
|
|
2411
2400
|
...ruleEvaluation,
|
|
2412
|
-
error: serializeError(ruleEvaluation.error)
|
|
2401
|
+
error: this.serializeError(ruleEvaluation.error)
|
|
2413
2402
|
})),
|
|
2414
|
-
|
|
2403
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- type is explicitly `any`
|
|
2404
|
+
errors: debugEvent.errors.map((error) => this.serializeError(error))
|
|
2415
2405
|
};
|
|
2416
2406
|
}
|
|
2417
2407
|
/**
|
|
@@ -2419,10 +2409,13 @@ class RulesEngineDevtoolsMessageService {
|
|
|
2419
2409
|
*/
|
|
2420
2410
|
startRulesEngineReport() {
|
|
2421
2411
|
if (this.rulesEngineDevtools.rulesEngineReport$) {
|
|
2422
|
-
|
|
2412
|
+
combineLatest([
|
|
2413
|
+
this.forceEmitRulesEngineReport,
|
|
2414
|
+
this.rulesEngineDevtools.rulesEngineReport$
|
|
2415
|
+
]).pipe(takeUntilDestroyed(this.destroyRef)).subscribe(([, report]) => {
|
|
2423
2416
|
const sanitizedReport = { ...report, events: report.events.map((reportEvents) => this.serializeReportEvent(reportEvents)) };
|
|
2424
2417
|
this.sendMessage('rulesEngineEvents', sanitizedReport);
|
|
2425
|
-
})
|
|
2418
|
+
});
|
|
2426
2419
|
}
|
|
2427
2420
|
}
|
|
2428
2421
|
/**
|
|
@@ -2435,16 +2428,12 @@ class RulesEngineDevtoolsMessageService {
|
|
|
2435
2428
|
/** Activate the Otter DevTools */
|
|
2436
2429
|
activate() {
|
|
2437
2430
|
this.startRulesEngineReport();
|
|
2438
|
-
|
|
2439
|
-
}
|
|
2440
|
-
/** @inheritDoc */
|
|
2441
|
-
ngOnDestroy() {
|
|
2442
|
-
this.subscriptions.unsubscribe();
|
|
2431
|
+
fromEvent(window, 'message').pipe(takeUntilDestroyed(this.destroyRef), filterMessageContent(isRulesEngineMessage)).subscribe((e) => this.handleEvents(e));
|
|
2443
2432
|
}
|
|
2444
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2445
|
-
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.
|
|
2433
|
+
/** @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 }); }
|
|
2434
|
+
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsMessageService, providedIn: 'root' }); }
|
|
2446
2435
|
}
|
|
2447
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2436
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsMessageService, decorators: [{
|
|
2448
2437
|
type: Injectable,
|
|
2449
2438
|
args: [{
|
|
2450
2439
|
providedIn: 'root'
|
|
@@ -2471,17 +2460,17 @@ class RulesEngineDevtoolsModule {
|
|
|
2471
2460
|
]
|
|
2472
2461
|
};
|
|
2473
2462
|
}
|
|
2474
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2475
|
-
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.
|
|
2463
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2464
|
+
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsModule, imports: [StoreModule,
|
|
2476
2465
|
RulesetsStoreModule] }); }
|
|
2477
|
-
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.
|
|
2466
|
+
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsModule, providers: [
|
|
2478
2467
|
{ provide: OTTER_RULES_ENGINE_DEVTOOLS_OPTIONS, useValue: OTTER_RULES_ENGINE_DEVTOOLS_DEFAULT_OPTIONS },
|
|
2479
2468
|
RulesEngineDevtoolsMessageService,
|
|
2480
2469
|
RulesEngineDevtoolsConsoleService
|
|
2481
2470
|
], imports: [StoreModule,
|
|
2482
2471
|
RulesetsStoreModule] }); }
|
|
2483
2472
|
}
|
|
2484
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2473
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RulesEngineDevtoolsModule, decorators: [{
|
|
2485
2474
|
type: NgModule,
|
|
2486
2475
|
args: [{
|
|
2487
2476
|
imports: [
|
|
@@ -2521,10 +2510,10 @@ class CurrentTimeFactsService extends FactsService {
|
|
|
2521
2510
|
tick() {
|
|
2522
2511
|
this.currentTimeSubject$.next(Date.now());
|
|
2523
2512
|
}
|
|
2524
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.
|
|
2525
|
-
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.
|
|
2513
|
+
/** @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 }); }
|
|
2514
|
+
/** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CurrentTimeFactsService, providedIn: 'root' }); }
|
|
2526
2515
|
}
|
|
2527
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.
|
|
2516
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CurrentTimeFactsService, decorators: [{
|
|
2528
2517
|
type: Injectable,
|
|
2529
2518
|
args: [{
|
|
2530
2519
|
providedIn: 'root'
|