Open rule chain from rule node link

This commit is contained in:
Vladyslav_Prykhodko 2020-07-31 16:18:49 +03:00
parent 6603d6f1a4
commit b29a610f7a
5 changed files with 145 additions and 85 deletions

View File

@ -171,12 +171,27 @@
.fc-edit { .fc-edit {
.fc-nodeedit, .fc-nodeedit,
.fc-nodedelete { .fc-nodedelete,
.fc-nodeopen {
box-sizing: content-box; box-sizing: content-box;
border: solid 2px #fff; border: solid 2px #fff;
background: #f83e05; background: #f83e05;
outline: none; outline: none;
} }
.fc-nodeopen{
top: 30px;
right: -14px;
mat-icon{
width: 20px;
min-width: 20px;
height: 20px;
min-height: 20px;
font-size: 18px;
line-height: 18px;
}
}
} }
.fc-arrow-marker { .fc-arrow-marker {

View File

@ -20,6 +20,7 @@ import {
ElementRef, ElementRef,
HostBinding, HostBinding,
Inject, Inject,
OnDestroy,
OnInit, OnInit,
QueryList, QueryList,
SkipSelf, SkipSelf,
@ -64,7 +65,7 @@ import {
} from '@shared/models/rule-node.models'; } from '@shared/models/rule-node.models';
import { FcRuleNodeModel, FcRuleNodeTypeModel, RuleChainMenuContextInfo } from './rulechain-page.models'; import { FcRuleNodeModel, FcRuleNodeTypeModel, RuleChainMenuContextInfo } from './rulechain-page.models';
import { RuleChainService } from '@core/http/rule-chain.service'; import { RuleChainService } from '@core/http/rule-chain.service';
import { fromEvent, NEVER, Observable, of } from 'rxjs'; import { fromEvent, NEVER, Observable, of, Subscription } from 'rxjs';
import { debounceTime, distinctUntilChanged, mergeMap, tap } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, mergeMap, tap } from 'rxjs/operators';
import { ISearchableComponent } from '../../models/searchable-component.models'; import { ISearchableComponent } from '../../models/searchable-component.models';
import { deepClone } from '@core/utils'; import { deepClone } from '@core/utils';
@ -85,7 +86,7 @@ import Timeout = NodeJS.Timeout;
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class RuleChainPageComponent extends PageComponent export class RuleChainPageComponent extends PageComponent
implements AfterViewInit, OnInit, HasDirtyFlag, ISearchableComponent { implements AfterViewInit, OnInit, OnDestroy, HasDirtyFlag, ISearchableComponent {
get isDirty(): boolean { get isDirty(): boolean {
return this.isDirtyValue || this.isImport; return this.isDirtyValue || this.isImport;
@ -234,6 +235,8 @@ export class RuleChainPageComponent extends PageComponent
flowchartConstants = FlowchartConstants; flowchartConstants = FlowchartConstants;
private rxSubscription: Subscription;
private tooltipTimeout: Timeout; private tooltipTimeout: Timeout;
constructor(protected store: Store<AppState>, constructor(protected store: Store<AppState>,
@ -247,7 +250,13 @@ export class RuleChainPageComponent extends PageComponent
public dialogService: DialogService, public dialogService: DialogService,
public fb: FormBuilder) { public fb: FormBuilder) {
super(store); super(store);
this.init();
this.rxSubscription = this.route.data.subscribe(
() => {
this.reset();
this.init();
}
);
} }
ngOnInit() { ngOnInit() {
@ -266,6 +275,11 @@ export class RuleChainPageComponent extends PageComponent
this.ruleChainCanvas.adjustCanvasSize(true); this.ruleChainCanvas.adjustCanvasSize(true);
} }
ngOnDestroy() {
super.ngOnDestroy();
this.rxSubscription.unsubscribe();
}
onSearchTextUpdated(searchText: string) { onSearchTextUpdated(searchText: string) {
this.ruleNodeSearch = searchText; this.ruleNodeSearch = searchText;
this.updateRuleNodesHighlight(); this.updateRuleNodesHighlight();
@ -299,87 +313,100 @@ export class RuleChainPageComponent extends PageComponent
this.createRuleChainModel(); this.createRuleChainModel();
} }
private reset(): void {
this.selectedObjects = [];
this.ruleChainModel.nodes = [];
this.ruleChainModel.edges = [];
this.ruleNodeTypesModel = {};
if (this.ruleChainCanvas) {
this.ruleChainCanvas.adjustCanvasSize(true);
}
this.updateRuleNodesHighlight();
}
private initHotKeys(): void { private initHotKeys(): void {
this.hotKeys.push( if (!this.hotKeys.length) {
new Hotkey('ctrl+a', (event: KeyboardEvent) => { this.hotKeys.push(
if (this.enableHotKeys) { new Hotkey('ctrl+a', (event: KeyboardEvent) => {
event.preventDefault(); if (this.enableHotKeys) {
this.ruleChainCanvas.modelService.selectAll(); event.preventDefault();
return false; this.ruleChainCanvas.modelService.selectAll();
} return false;
return true;
}, ['INPUT', 'SELECT', 'TEXTAREA'],
this.translate.instant('rulenode.select-all-objects'))
);
this.hotKeys.push(
new Hotkey('ctrl+c', (event: KeyboardEvent) => {
if (this.enableHotKeys) {
event.preventDefault();
this.copyRuleNodes();
return false;
}
return true;
}, ['INPUT', 'SELECT', 'TEXTAREA'],
this.translate.instant('rulenode.copy-selected'))
);
this.hotKeys.push(
new Hotkey('ctrl+v', (event: KeyboardEvent) => {
if (this.enableHotKeys) {
event.preventDefault();
if (this.itembuffer.hasRuleNodes()) {
this.pasteRuleNodes();
} }
return false; return true;
} }, ['INPUT', 'SELECT', 'TEXTAREA'],
return true; this.translate.instant('rulenode.select-all-objects'))
}, ['INPUT', 'SELECT', 'TEXTAREA'], );
this.translate.instant('action.paste')) this.hotKeys.push(
); new Hotkey('ctrl+c', (event: KeyboardEvent) => {
this.hotKeys.push( if (this.enableHotKeys) {
new Hotkey('esc', (event: KeyboardEvent) => { event.preventDefault();
if (this.enableHotKeys) { this.copyRuleNodes();
event.preventDefault(); return false;
event.stopPropagation(); }
this.ruleChainCanvas.modelService.deselectAll(); return true;
return false; }, ['INPUT', 'SELECT', 'TEXTAREA'],
} this.translate.instant('rulenode.copy-selected'))
return true; );
}, ['INPUT', 'SELECT', 'TEXTAREA'], this.hotKeys.push(
this.translate.instant('rulenode.deselect-all-objects')) new Hotkey('ctrl+v', (event: KeyboardEvent) => {
); if (this.enableHotKeys) {
this.hotKeys.push( event.preventDefault();
new Hotkey('ctrl+s', (event: KeyboardEvent) => { if (this.itembuffer.hasRuleNodes()) {
if (this.enableHotKeys) { this.pasteRuleNodes();
event.preventDefault(); }
this.saveRuleChain(); return false;
return false; }
} return true;
return true; }, ['INPUT', 'SELECT', 'TEXTAREA'],
}, ['INPUT', 'SELECT', 'TEXTAREA'], this.translate.instant('action.paste'))
this.translate.instant('action.apply')) );
); this.hotKeys.push(
this.hotKeys.push( new Hotkey('esc', (event: KeyboardEvent) => {
new Hotkey('ctrl+z', (event: KeyboardEvent) => { if (this.enableHotKeys) {
if (this.enableHotKeys) { event.preventDefault();
event.preventDefault(); event.stopPropagation();
this.revertRuleChain(); this.ruleChainCanvas.modelService.deselectAll();
return false; return false;
} }
return true; return true;
}, ['INPUT', 'SELECT', 'TEXTAREA'], }, ['INPUT', 'SELECT', 'TEXTAREA'],
this.translate.instant('action.decline-changes')) this.translate.instant('rulenode.deselect-all-objects'))
); );
this.hotKeys.push( this.hotKeys.push(
new Hotkey('del', (event: KeyboardEvent) => { new Hotkey('ctrl+s', (event: KeyboardEvent) => {
if (this.enableHotKeys) { if (this.enableHotKeys) {
event.preventDefault(); event.preventDefault();
this.ruleChainCanvas.modelService.deleteSelected(); this.saveRuleChain();
return false; return false;
} }
return true; return true;
}, ['INPUT', 'SELECT', 'TEXTAREA'], }, ['INPUT', 'SELECT', 'TEXTAREA'],
this.translate.instant('rulenode.delete-selected-objects')) this.translate.instant('action.apply'))
); );
this.hotKeys.push(
new Hotkey('ctrl+z', (event: KeyboardEvent) => {
if (this.enableHotKeys) {
event.preventDefault();
this.revertRuleChain();
return false;
}
return true;
}, ['INPUT', 'SELECT', 'TEXTAREA'],
this.translate.instant('action.decline-changes'))
);
this.hotKeys.push(
new Hotkey('del', (event: KeyboardEvent) => {
if (this.enableHotKeys) {
event.preventDefault();
this.ruleChainCanvas.modelService.deleteSelected();
return false;
}
return true;
}, ['INPUT', 'SELECT', 'TEXTAREA'],
this.translate.instant('rulenode.delete-selected-objects'))
);
}
} }
updateRuleChainLibrary() { updateRuleChainLibrary() {

View File

@ -59,4 +59,9 @@
&times; &times;
</div> </div>
</section> </section>
<section class="fc-edit" *ngIf="node.component.type === RuleNodeType.RULE_CHAIN">
<div class="fc-nodeedit fc-nodeopen" (click)="openRuleChain($event, node)">
<mat-icon class="material-icons" svgIcon="mdi:login"></mat-icon>
</div>
</section>
</div> </div>

View File

@ -40,7 +40,8 @@
:host-context(.fc-edit) { :host-context(.fc-edit) {
.fc-nodeedit, .fc-nodeedit,
.fc-nodedelete { .fc-nodedelete,
.fc-nodeopen {
box-sizing: content-box; box-sizing: content-box;
border: solid 2px #fff; border: solid 2px #fff;
background: #f83e05; background: #f83e05;

View File

@ -17,6 +17,8 @@
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FcNodeComponent } from 'ngx-flowchart/dist/ngx-flowchart'; import { FcNodeComponent } from 'ngx-flowchart/dist/ngx-flowchart';
import { FcRuleNode, RuleNodeType } from '@shared/models/rule-node.models';
import { Router } from '@angular/router';
@Component({ @Component({
// tslint:disable-next-line:component-selector // tslint:disable-next-line:component-selector
@ -27,8 +29,10 @@ import { FcNodeComponent } from 'ngx-flowchart/dist/ngx-flowchart';
export class RuleNodeComponent extends FcNodeComponent implements OnInit { export class RuleNodeComponent extends FcNodeComponent implements OnInit {
iconUrl: SafeResourceUrl; iconUrl: SafeResourceUrl;
RuleNodeType = RuleNodeType;
constructor(private sanitizer: DomSanitizer) { constructor(private sanitizer: DomSanitizer,
private router: Router) {
super(); super();
} }
@ -39,4 +43,12 @@ export class RuleNodeComponent extends FcNodeComponent implements OnInit {
} }
} }
openRuleChain($event: Event, node: FcRuleNode) {
if ($event) {
$event.stopPropagation();
}
if (node.targetRuleChainId) {
this.router.navigateByUrl(`/ruleChains/${node.targetRuleChainId}`);
}
}
} }