Skip to content

Commit

Permalink
feat(dpf-18714): inNextMinutes operator
Browse files Browse the repository at this point in the history
  • Loading branch information
vscaiceanu-1a committed Nov 10, 2023
1 parent b8d079f commit 6b143ea
Show file tree
Hide file tree
Showing 25 changed files with 573 additions and 184 deletions.
29 changes: 23 additions & 6 deletions apps/showcase/src/app/rules-engine/rules-engine.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,24 @@ import { ConfigOverrideStoreModule, ConfigurationBaseServiceModule, Configuratio
import { O3rComponent } from '@o3r/core';
import { AssetPathOverrideStoreModule, DynamicContentService } from '@o3r/dynamic-content';
import { LocalizationOverrideStoreModule } from '@o3r/localization';
import { Rule, RulesEngineDevtoolsMessageService, RulesEngineDevtoolsModule, RulesEngineModule, RulesEngineService, RulesetsStore, setRulesetsEntities, UnaryOperator } from '@o3r/rules-engine';
import {
dateInNextMinutes,
Operator,
Rule,
RulesEngineDevtoolsMessageService,
RulesEngineDevtoolsModule,
RulesEngineModule,
RulesEngineService,
RulesetsStore,
setRulesetsEntities,
UnaryOperator
} from '@o3r/rules-engine';
import { firstValueFrom } from 'rxjs';
import { CopyTextPresComponent, IN_PAGE_NAV_PRES_DIRECTIVES, InPageNavLink, InPageNavLinkDirective, InPageNavPresService, RulesEnginePresComponent } from '../../components/index';
import { environment } from '../../environments/environment.development';
import { TripFactsService } from '../../facts/index';
import { duringSummer } from '../../operators/index';
import { CurrentTimeFactsService } from '../../services/current-time-facts.service';

@O3rComponent({ componentType: 'Page' })
@Component({
Expand Down Expand Up @@ -44,6 +56,7 @@ export class RulesEngineComponent implements OnInit, AfterViewInit {
public newYorkAvailableRule = '';
public helloNewYorkRule = '';
public summerOtterRule = '';
public lateOtterRule = '';

@ViewChildren(InPageNavLinkDirective)
private inPageNavLinkDirectives!: QueryList<InPageNavLink>;
Expand All @@ -55,16 +68,16 @@ export class RulesEngineComponent implements OnInit, AfterViewInit {
private inPageNavPresService: InPageNavPresService,
private dynamicContentService: DynamicContentService,
private tripFactsService: TripFactsService,
public currentTimeFactsService: CurrentTimeFactsService,
private store: Store<RulesetsStore>,
configurationDevtoolsMessageService: ConfigurationDevtoolsMessageService,
rulesEngineDevtoolsMessageService: RulesEngineDevtoolsMessageService,
rulesEngineService: RulesEngineService
) {
configurationDevtoolsMessageService.activate();
rulesEngineDevtoolsMessageService.activate();
rulesEngineService.engine.upsertOperators([
duringSummer
] as UnaryOperator[]);
rulesEngineService.engine.upsertOperators([duringSummer] as UnaryOperator[]);
rulesEngineService.engine.upsertOperators([dateInNextMinutes] as Operator[]);
}

private formatRule(rule: Rule) {
Expand All @@ -84,16 +97,20 @@ export class RulesEngineComponent implements OnInit, AfterViewInit {
const resultCall = await fetch(path);
const result = await resultCall.json();

this.store.dispatch(setRulesetsEntities({entities: result.rulesets}));
this.store.dispatch(setRulesetsEntities({ entities: result.rulesets }));
this.tripFactsService.register();
// uncomment to test currentTimeFactsService override
// this.currentTimeFactsService.register();
const [
newYorkAvailableRule,
helloNewYorkRule,
summerOtterRule
summerOtterRule,
lateOtterRule
] = result.rulesets[0].rules as Rule[];
this.newYorkAvailableRule = JSON.stringify(this.formatRule(newYorkAvailableRule), null, 2);
this.helloNewYorkRule = JSON.stringify(this.formatRule(helloNewYorkRule), null, 2);
this.summerOtterRule = JSON.stringify(this.formatRule(summerOtterRule), null, 2);
this.lateOtterRule = JSON.stringify(this.formatRule(lateOtterRule), null, 2);
}

public ngAfterViewInit() {
Expand Down
11 changes: 11 additions & 0 deletions apps/showcase/src/app/rules-engine/rules-engine.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ <h2 id="rules-engine-example">Example</h2>
<li class="nav-item">
<a class="nav-link" [class.active]="activeRuleTab === 'dynamic-content'" (click)="activateRuleTab('dynamic-content')">Dynamic content rule</a>
</li>
<li class="nav-item">
<a class="nav-link" [class.active]="activeRuleTab === 'operator-fact'" (click)="activateRuleTab('operator-fact')">Operator fact</a>
</li>
</ul>
<div class="p-3">
<div *ngIf="activeRuleTab === 'configuration'">
Expand Down Expand Up @@ -64,6 +67,14 @@ <h2 id="rules-engine-example">Example</h2>
</p>
<o3r-copy-text-pres language="json" [text]="helloNewYorkRule"></o3r-copy-text-pres>
</div>
<div *ngIf="activeRuleTab === 'operator-fact'">
<p>
When selecting a departure date in less than 2 days, the otter picture changes. We have created the following rule to change the targeted asset.
<br>
It is using the `inNextMinutes` operator which is based on the current time.
</p>
<o3r-copy-text-pres language="json" [text]="lateOtterRule"></o3r-copy-text-pres>
</div>
</div>
</div>
<h2 id="rules-engine-install">How to install</h2>
Expand Down
44 changes: 38 additions & 6 deletions apps/showcase/src/assets/rules/rulesets.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
"disabled": false,
"rules": [
{
"id": "5467e501-b9ff-414f-8026-56885d0d7a4c",
"id": "5467e501-b9ff-414f-8026-56885d0d7a4b",
"name": "New-York availability",
"disabled": false,
"outputRuntimeFacts": [],
"inputFacts": ["outboundDate"],
"inputRuntimeFacts": [],
"rootElement": {
"elementType": "RULE_BLOCK",
Expand Down Expand Up @@ -50,7 +49,6 @@
"name": "Destination selected",
"disabled": false,
"outputRuntimeFacts": [],
"inputFacts": ["destination"],
"inputRuntimeFacts": [],
"rootElement": {
"elementType": "RULE_BLOCK",
Expand Down Expand Up @@ -78,11 +76,10 @@
}
},
{
"id": "5467e501-b9ff-414f-8026-56885d0d7a4c",
"name": "The otter is in vacations",
"id": "5467e501-b9ff-414f-8026-56885d0d7a4d",
"name":"The otter is on vacation",
"disabled": false,
"outputRuntimeFacts": [],
"inputFacts": ["outboundDate"],
"inputRuntimeFacts": [],
"rootElement": {
"elementType": "RULE_BLOCK",
Expand All @@ -108,6 +105,41 @@
],
"failureElements": []
}
},
{
"id": "5467e501-b9ff-414f-8026-56885d0d7a4c",
"name": "The otter is late",
"disabled": false,
"outputRuntimeFacts": [],
"inputRuntimeFacts": [],
"rootElement": {
"elementType": "RULE_BLOCK",
"blockType": "IF_ELSE",
"condition": {
"all": [
{
"lhs": {
"type": "FACT",
"value": "outboundDate"
},
"rhs": {
"type": "LITERAL",
"value": "2880"
},
"operator": "dateInNextMinutes"
}
]
},
"successElements": [
{
"elementType": "ACTION",
"actionType": "UPDATE_ASSET",
"asset": "otter.svg",
"value": "otter-summer.svg"
}
],
"failureElements": []
}
}
]
}
Expand Down
24 changes: 24 additions & 0 deletions apps/showcase/src/services/current-time-facts.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Injectable } from '@angular/core';
import { CurrentTimeFacts, FactsService, RulesEngineService } from '@o3r/rules-engine';
import { BehaviorSubject } from 'rxjs';

@Injectable({
providedIn: 'root'
})
export class CurrentTimeFactsService extends FactsService<CurrentTimeFacts> {

private currentTimeSubject$ = new BehaviorSubject(new Date('2023-11-2').getTime());
/** @inheritDoc */
public facts = {
o3rCurrentTime: this.currentTimeSubject$.asObservable()
};

constructor(rulesEngine: RulesEngineService) {
super(rulesEngine);
}

/** Compute the current time */
public tick() {
this.currentTimeSubject$.next(Date.now());
}
}
4 changes: 4 additions & 0 deletions docs/rules-engine/facts.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,7 @@ See the [runtime-facts](./examples/runtime-facts.md) example.


Note that the runtime fact is only accessible in the ruleset where it has been defined. If you create 2 runtime facts in two different rulesets it will be 2 different entities, isolated from each others.

## Facts available by default

`o3rCurrentTime` is a fact that represents the current time. It is provided by the rules engine as two operators, `dateInNextMinutes` and `dateNotInNextMinutes` need it in order to execute. See [Operators with dependencies](./operators.md#operators-with-dependencies) for more details.
Loading

0 comments on commit 6b143ea

Please sign in to comment.