diff options
Diffstat (limited to 'public/src/app/rule-engine/rule-list')
3 files changed, 379 insertions, 0 deletions
diff --git a/public/src/app/rule-engine/rule-list/rule-list.component.html b/public/src/app/rule-engine/rule-list/rule-list.component.html new file mode 100644 index 0000000..c68c706 --- /dev/null +++ b/public/src/app/rule-engine/rule-list/rule-list.component.html @@ -0,0 +1,73 @@ +<div class="container"> + <div class="header"> + <span style="font-size: 18px;">Rule Engine</span> + <div style="display:flex"> + <button mat-raised-button (click)="translateRules()" color="primary" [disabled]="store.ruleList.length === 0" style="margin-left: 20px;" + data-tests-id="btnTranslate"> + Translate + </button> + <app-bar-icons [tabName]="this.store.tabParmasForRule[0].name"></app-bar-icons> + </div> + </div> + + <div style="margin: 0rem 1rem; flex-grow: 1; overflow-y: auto;"> + + <!-- error container --> + <div *ngIf="error" style="color: white; background: red; padding: 1rem; border-radius: 5px; font-weight: bold;"> + {{ error }} + </div> + + <app-version-type-select #versionEventType [versions]="versions" [metaData]="metaData" (nodesUpdated)="handleUpdateNode($event)" + (refrashRuleList)="handlePropertyChange()"></app-version-type-select> + + <div *ngIf="targetSource && store.ruleList.length === 0" style="margin: 30px 0; display: flex; align-items: center; justify-content: center; flex-direction: column;"> + + <div style="margin: 3em 0 2em 0;"> + <div style="font-size: 1.5em;"> + Rules were not yet created + </div> + <div style="padding: 0.5em; padding-top: 1em;"> + Please create a new normalization rule + </div> + </div> + + <button mat-fab (click)="openAction()" style="background-color:#009FDB" data-tests-id="btnAddFirstRule"> + <span [innerHTML]="'plus' | feather:24"></span> + </button> + <span style="margin-top: 1rem; font-size: 14px; color: #009FDB;"> + Add First Rule + </span> + </div> + + <div *ngIf="store.ruleList.length > 0"> + <div style="padding: 10px 0;"> + Rules + </div> + <div style="display: flex; align-items: center;"> + <button mat-mini-fab color="primary" id="addMoreRule" data-tests-id="addMoreRule" style="height: 24px; width: 24px; display:flex" + (click)="openAction()"> + <mat-icon class="material-icons md-18">add</mat-icon> + </button> + <span style="color: #009FDB; display: flex; justify-content: center; padding-left: 10px">Add Rule</span> + </div> + </div> + + <div style="margin: 30px 0 10px 0;"> + + <div *ngFor="let item of store.ruleList; let index = index" data-tests-id="ruleElement" (mouseleave)="hoveredIndex=-1" (mouseover)="hoveredIndex=index" + class="item" style="display: flex;" [ngStyle]="hoveredIndex === index ? {'background-color': '#E6F6FB', 'color': '#009FDB'} : {'background-color': '#FFFFFF', 'color':'gray'}"> + <span style="width:100%; display: flex; align-items: center;"> + {{item.description}} - [{{item.uid}}] + </span> + <div style="display: flex; justify-content: flex-end;" *ngIf="index==hoveredIndex"> + <button (click)="openAction(item)" data-tests-id="editRule" class="btn-list" mat-icon-button> + <mat-icon class="md-24">mode_edit</mat-icon> + </button> + <button (click)="removeItem(item.uid)" data-tests-id="deleteRule" class="btn-list" mat-icon-button> + <mat-icon class="md-24">delete</mat-icon> + </button> + </div> + </div> + </div> + </div> +</div> diff --git a/public/src/app/rule-engine/rule-list/rule-list.component.scss b/public/src/app/rule-engine/rule-list/rule-list.component.scss new file mode 100644 index 0000000..c4aee05 --- /dev/null +++ b/public/src/app/rule-engine/rule-list/rule-list.component.scss @@ -0,0 +1,109 @@ +.container { + // margin: 1rem; + position: relative; + height: 100%; + display: flex; + flex-direction: column; + + .header { + position: relative; + display: flex; + justify-content: space-between; + align-items: center; + color: #191919; + border-bottom: 2px solid #d2d2d2; + padding-bottom: 0.5rem; + margin: 1rem; + } + + .item { + border: 1px solid #d2d2d2; + padding: 0 10px; + height: 40px; + } + + .mat-fab, + .mat-mini-fab, + .mat-raised-button { + box-shadow: none; + } +} +.my-full-screen-dialog .mat-dialog-container { + max-width: none; + width: 100vw; + height: 100vh; + padding: 0; +} + +.my-confrim-dialog .mat-dialog-container { + max-width: 600px; + width: 500px; + height: 200px; + padding: 0; +} + +.btn-list { + display: flex !important; + justify-content: center !important; + color: #d2d2d2 !important; + + &:hover { + color: #009fdb !important; + } +} + +.hr { + display: block; + margin: 10px 0 10px 0; + border-top: 1px solid rgba(0, 0, 0, 0.12); + width: 100%; +} + +.mat-fab, +.mat-mini-fab, +.mat-raised-button { + box-shadow: none; +} + +.mat-mini-fab .mat-button-wrapper { + padding: 0 !important; +} +.mat-icon { + // width: 18px; + // height: 18px; + display: flex !important; + justify-content: center !important; + align-items: center !important; +} +/* Rules for sizing the icon. */ +.material-icons.md-18 { + font-size: 18px; +} +.material-icons.md-24 { + font-size: 24px; +} +.material-icons.md-30 { + font-size: 30px; +} +.material-icons.md-36 { + font-size: 36px; +} +.material-icons.md-48 { + font-size: 48px; +} + +/* Rules for using icons as black on a light background. */ +.material-icons.md-dark { + color: rgba(0, 0, 0, 0.54); +} +.material-icons.md-dark.md-inactive { + color: rgba(0, 0, 0, 0.26); +} + +/* Rules for using icons as white on a dark background. */ +.material-icons.md-light { + color: rgba(255, 255, 255, 1); +} +.material-icons.md-light.md-inactive { + color: rgba(255, 255, 255, 0.3); +} diff --git a/public/src/app/rule-engine/rule-list/rule-list.component.ts b/public/src/app/rule-engine/rule-list/rule-list.component.ts new file mode 100644 index 0000000..45cfbd0 --- /dev/null +++ b/public/src/app/rule-engine/rule-list/rule-list.component.ts @@ -0,0 +1,197 @@ +import { Component, ViewEncapsulation, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material'; +import { ActionListComponent } from '../action-list/action-list.component'; +import { RuleEngineApiService } from '../api/rule-engine-api.service'; +import { ConfirmPopupComponent } from '../confirm-popup/confirm-popup.component'; +import { Store } from '../../store/store'; +import { isEmpty } from 'lodash'; +import { ToastrService } from 'ngx-toastr'; +import { timer } from 'rxjs/observable/timer'; + +const primaryColor = '#009fdb'; + +@Component({ + selector: 'app-rule-list', + templateUrl: './rule-list.component.html', + styleUrls: ['./rule-list.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class RuleListComponent { + @ViewChild('versionEventType') versionType; + error: Array<string>; + // list = new Array(); + schema; + targetSource; + dialogRef; + crud; + hoveredIndex; + params; + versions; + metaData; + + private errorHandler(error: any) { + this.store.loader = false; + console.log(error); + this.error = []; + if (typeof error === 'string') { + this.error.push(error); + } else { + console.log(error.notes); + const errorFromServer = Object.values(error)[0] as any; + if (Object.keys(error)[0] === 'serviceExceptions') { + this.error = errorFromServer.map(x => x.formattedErrorMessage); + } else { + this.error = errorFromServer.formattedErrorMessage; + } + } + } + + private getListOfRules() { + this._ruleApi.getListOfRules().subscribe( + response => { + console.log('res: %o', response); + if (response && Object.keys(response).length !== 0) { + this.versionType.updateData( + response.version, + response.eventType, + true + ); + this.store.updateRuleList(Object.values(response.rules)); + this.targetSource = response.schema; + } else { + this.store.resetRuleList(); + this.versionType.updateVersionTypeFlag(false); + this.targetSource = null; + // if the the list is empty then get version and domain events + this._ruleApi.getMetaData().subscribe(data => { + console.log(data); + this.versions = data.map(x => x.version); + this.metaData = data; + }); + } + this.store.loader = false; + }, + error => { + this.errorHandler(error); + } + ); + } + + constructor( + private _ruleApi: RuleEngineApiService, + public dialog: MatDialog, + private toastr: ToastrService, + public store: Store + ) { + this.store.loader = true; + this.params = { + vfcmtUuid: this.store.mcUuid, + nodeName: this.store.tabParmasForRule[0].name, + nodeId: this.store.tabParmasForRule[0].nid, + fieldName: this.store.configurationForm[0].name, + userId: 'ym903w', // this.store.sdcParmas.userId + flowType: this.store.cdump.flowType + }; + console.log('params: %o', this.params); + this.store.loader = true; + // set api params by iframe url query + this._ruleApi.setParams(this.params); + this.getListOfRules(); + } + + handlePropertyChange() { + this.store.loader = true; + this.error = null; + this.getListOfRules(); + } + + translateRules() { + this.store.loader = true; + // send translate JSON + this._ruleApi.translate().subscribe( + data => { + this.store.loader = false; + console.log(JSON.stringify(data)); + let domElementName: string; + this.store.configurationForm.forEach(property => { + console.log('mappingTarget ', this.versionType.mappingTarget); + if (property.name === this.versionType.mappingTarget) { + property.assignment.value = JSON.stringify(data); + domElementName = property.name; + console.log(property.name); + } + }); + this.toastr.success('', 'Translate succeeded'); + this.store.expandAdvancedSetting[this.store.tabIndex] = true; + const source = timer(500); + source.subscribe(val => { + const el = document.getElementById(domElementName); + const label = el.children.item(0) as HTMLElement; + label.style.color = primaryColor; + const input = el.children.item(1) as HTMLElement; + input.style.color = primaryColor; + input.style.borderColor = primaryColor; + el.scrollIntoView(); + }); + }, + error => { + this.errorHandler(error); + } + ); + } + + handleUpdateNode(data) { + this.targetSource = data.nodes; + this.store.resetRuleList(); + } + + removeItem(uid) { + this.dialogRef = this.dialog.open(ConfirmPopupComponent, { + panelClass: 'my-confrim-dialog', + disableClose: true + }); + this.dialogRef.afterClosed().subscribe(result => { + // if the user want to delete + if (result) { + // call be api + this.store.loader = true; + this._ruleApi.deleteRule(uid).subscribe( + success => { + this.store.removeRuleFromList(uid); + // if its the last rule + if (this.store.ruleList.length === 0) { + this._ruleApi.getMetaData().subscribe(data => { + console.log(data); + this.versions = data.map(x => x.version); + this.metaData = data; + this.versionType.updateVersionTypeFlag(false); + this.targetSource = null; + }); + } + this.store.loader = false; + }, + error => { + this.store.loader = false; + this.errorHandler(error); + } + ); + } + }); + } + + openAction(item): void { + this.crud = isEmpty(item) ? 'new' : 'edit'; + this._ruleApi.passDataToEditor({ + version: this.versionType.selectedVersion, + eventType: this.versionType.selectedEvent, + targetSource: this.targetSource, + item: isEmpty(item) ? null : item, + params: this.params + }); + this.store.isLeftVisible = false; + + this._ruleApi.updateVersionLock.subscribe(() => { + this.versionType.updateVersionTypeFlag(true); + }); + } +} |