diff options
author | 2018-06-03 13:12:12 +0300 | |
---|---|---|
committer | 2018-06-03 11:56:49 +0000 | |
commit | 548c5a220333c7cd666b861e737bff0b45461f18 (patch) | |
tree | 13c60b67291bd8bada498ad73c02a9e35afb5c9e /public/src/app/rule-engine | |
parent | 193095b01daf094c78f7fafacdf1c1cc31f290fe (diff) |
Update FE project
Update FE to latest version so that fe can run on docker
Change-Id: I9c5dee756b567dbe64fac6d3d6fd89362813bdcc
Issue-ID: SDC-1359
Signed-off-by: Stone, Avi (as206k) <as206k@att.com>
Diffstat (limited to 'public/src/app/rule-engine')
29 files changed, 655 insertions, 377 deletions
diff --git a/public/src/app/rule-engine/action-list/action-list.component.html b/public/src/app/rule-engine/action-list/action-list.component.html index e7879b7..1ee74df 100644 --- a/public/src/app/rule-engine/action-list/action-list.component.html +++ b/public/src/app/rule-engine/action-list/action-list.component.html @@ -1,10 +1,10 @@ <form #actionListFrm="ngForm" class="wrapper" data-tests-id="popupRuleEditor"> <div class="header"> - <div style="display: flex; justify-content: flex-end; align-items: center;"> + <div style="display: flex; justify-content: flex-end; align-items: center; margin-left: 20px;"> <a (click)="closeDialog()" data-tests-id="btnBackRule" style="cursor: pointer;text-decoration: none; color: #009fdb;"> <mat-icon fontSet="fontawesome" fontIcon="fa-angle-left" style="height: 22px; width: 22px; font-size: 22px; padding-right: 20px;"></mat-icon> </a> - <span style="font-size: 18px;">New Rule Editor</span> + <span style="font-size: 18px;">{{title}}</span> </div> <div style="display: flex; justify-content: flex-end; align-items: center; padding: 10px;"> @@ -17,7 +17,7 @@ align-items: center;" [innerHTML]="'save' | feather:22"></span> </button> - <button mat-raised-button [disabled]="actions.length === 0" style="height: 35px; margin-left: 20px;" color="primary" data-tests-id="btnDone" + <button mat-raised-button [disabled]="actions.length === 0" style="height: 35px; margin-left: 10px;" color="primary" data-tests-id="btnDone" (click)="saveAndDone()"> Done </button> @@ -62,18 +62,24 @@ <div style="display: flex;"> <select [(ngModel)]="selectedAction" name="selectedAction" style="height: 2rem; width: 150px; margin-right: 1rem;" data-tests-id="selectAction"> <option [ngValue]="null" disabled>Select Action</option> + <option value="copy">Copy</option> <option value="concat">Concat</option> <option value="map">Map</option> <option value="date formatter">Date Formatter</option> + <option value="log text">Log Text</option> + <option value="log event">Log Event</option> + <option value="replace text">Replace Text</option> + <option value="clear">Clear</option> + </select> <div style="display: flex; align-items: center;"> - <button mat-mini-fab color="primary" style="height: 24px; width: 24px; display:flex; justify-content: center;" (click)="addAction2list(selectedAction)" + <button mat-mini-fab color="primary" style="height: 16px; width: 16px; display:flex; justify-content: center;" (click)="addAction2list(selectedAction)" data-tests-id="btnAddAction"> - <span style="display: flex; justify-content: center; align-items: center" [innerHTML]="'plus' | feather:16"></span> + <span style="display: flex; justify-content: center; align-items: center" [innerHTML]="'plus' | feather:12"></span> </button> - <span style="color: #009FDB; display: flex; justify-content: center; padding-left: 10px">Add Action</span> + <span style="color: #009FDB; display: flex; justify-content: center; padding-left: 6px">Add Action</span> </div> </div> diff --git a/public/src/app/rule-engine/action-list/action-list.component.scss b/public/src/app/rule-engine/action-list/action-list.component.scss index 39b9dce..67fa048 100644 --- a/public/src/app/rule-engine/action-list/action-list.component.scss +++ b/public/src/app/rule-engine/action-list/action-list.component.scss @@ -9,7 +9,9 @@ justify-content: space-between; align-items: center; color: #191919; - border-bottom: 2px solid #d2d2d2; + border-bottom: 1px solid #d2d2d2; + padding-bottom: 0px; + margin: 0; // padding: 0.4rem 1rem; } diff --git a/public/src/app/rule-engine/action-list/action-list.component.ts b/public/src/app/rule-engine/action-list/action-list.component.ts index 40ff46d..27a74d4 100644 --- a/public/src/app/rule-engine/action-list/action-list.component.ts +++ b/public/src/app/rule-engine/action-list/action-list.component.ts @@ -1,20 +1,16 @@ import { + AfterViewInit, Component, - Inject, - ViewChildren, QueryList, - AfterViewInit, ViewChild, - Input + ViewChildren } from '@angular/core'; -import { RuleEngineApiService } from '../api/rule-engine-api.service'; -import { Subject } from 'rxjs/Subject'; -import { v1 as uuid } from 'uuid'; -import { environment } from '../../../environments/environment'; -import { ActionComponent } from '../action/action.component'; +import { NgForm } from '@angular/forms'; import { cloneDeep } from 'lodash'; +import { v1 as uuid } from 'uuid'; import { Store } from '../../store/store'; -import { NgForm } from '@angular/forms'; +import { ActionComponent } from '../action/action.component'; +import { RuleEngineApiService } from '../api/rule-engine-api.service'; @Component({ selector: 'app-action-list', @@ -22,6 +18,7 @@ import { NgForm } from '@angular/forms'; styleUrls: ['./action-list.component.scss'] }) export class ActionListComponent implements AfterViewInit { + title = ''; error: Array<string>; condition: any; eventType: string; @@ -53,8 +50,10 @@ export class ActionListComponent implements AfterViewInit { this.condition = data.item.condition; this.uid = data.item.uid; this.description = data.item.description; + this.title = this.description + ' - Rule Editor'; this.ifStatement = this.condition == null ? false : true; } else { + this.title = 'New Rule Editor'; this.actions = new Array(); this.backupActionForCancel = new Array(); this.condition = null; @@ -97,12 +96,24 @@ export class ActionListComponent implements AfterViewInit { value: '', regex: '', state: 'closed', - values: [{ value: '' }, { value: '' }] + values: [ + { + value: '' + }, + { + value: '' + } + ] }, actionType: this.selectedAction, target: '', map: { - values: [{ key: '', value: '' }], + values: [ + { + key: '', + value: '' + } + ], haveDefault: false, default: '' }, @@ -111,6 +122,18 @@ export class ActionListComponent implements AfterViewInit { toFormat: '', fromTimezone: '', toTimezone: '' + }, + replaceText: { + find: '', + replace: '' + }, + logText: { + name: '', + level: '', + text: '' + }, + logEvent: { + title: '' } }); } @@ -162,7 +185,10 @@ export class ActionListComponent implements AfterViewInit { ? item.target : item.selectedNode.id, map: item.map, - dateFormatter: item.dateFormatter + dateFormatter: item.dateFormatter, + replaceText: item.replaceText, + logText: item.logText, + logEvent: item.logEvent }; }); let conditionData2server = null; @@ -178,6 +204,7 @@ export class ActionListComponent implements AfterViewInit { return { version: this.version, eventType: this.eventType, + notifyId: this.store.notifyIdValue, uid: this.uid, description: this.description, actions: actionSetData, @@ -225,12 +252,12 @@ export class ActionListComponent implements AfterViewInit { const actionComp = this.actionsRef.toArray(); const filterInvalidActions = actionComp.filter(comp => { return ( - comp.fromInstance.fromFrm.invalid || - comp.targetInstance.targetFrm.invalid || - comp.actionFrm.invalid + // (comp.fromInstance && comp.fromInstance.fromFrm.invalid) || + // (comp.targetInstance && comp.targetInstance.targetFrm.invalid) || + comp.actionFrm && comp.actionFrm.invalid ); }); - if (this.actionListFrm.valid && filterInvalidActions.length === 0) { + if (this.actionListFrm.valid && filterInvalidActions.length == 0) { const data = this.prepareDataToSaveRule(); this.store.loader = true; this._ruleApi.modifyRule(data).subscribe( @@ -249,11 +276,10 @@ export class ActionListComponent implements AfterViewInit { } ); } else { - // scroll to first invalid element - const elId = filterInvalidActions[0].action.id; - const el = document.getElementById(elId as string); - const label = el.children.item(0) as HTMLElement; - el.scrollIntoView(); + // scroll to first invalid element const elId = + // filterInvalidActions[0].action.id; const el = document.getElementById(elId as + // string); const label = el.children.item(0) as HTMLElement; + // el.scrollIntoView(); } } diff --git a/public/src/app/rule-engine/action/action.component.html b/public/src/app/rule-engine/action/action.component.html index b41ab82..250af34 100644 --- a/public/src/app/rule-engine/action/action.component.html +++ b/public/src/app/rule-engine/action/action.component.html @@ -1,56 +1,151 @@ <form #actionFrm="ngForm" class="conatiner" id="{{action.id}}" (mouseover)="changeStyle($event)" (mouseout)="changeStyle($event)"> <div> + <div class="center-content"> <!-- type info --> <div class="action-info" [ngClass]="highlight"> {{action.actionType | uppercase}} </div> + <!-- from component --> - <app-from #from style="width: 100%" [actionType]="action.actionType" (onFromChange)="updateFrom($event)"></app-from> + <app-from [hidden]="action.actionType === 'log event' || action.actionType === 'log text'" class="center-content-item" #from + [actionType]="action.actionType" (onFromChange)="updateFrom($event)"></app-from> + <!-- target component --> - <app-target #target style="width: 100%" (onTargetChange)="updateTarget($event)" [nodes]="action.nodes"> + <app-target [hidden]="action.actionType === 'clear' || action.actionType === 'replace text' || action.actionType === 'log text' || action.actionType === 'log event'" + #target style="width: 100%" (onTargetChange)="updateTarget($event)" [nodes]="action.nodes"> </app-target> - </div> - <!-- dateFormatter --> - <div *ngIf="action.actionType === 'date formatter'" style="display: flex; flex-direction: column; margin: 1em; align-items: flex-end;"> - <div style="display: flex; margin: 0.5em 0;"> + <!-- log Event --> + <div *ngIf="action.actionType === 'log event'" class="center-content-item"> <div class="from"> - <div class="from-conatiner"> - <div style="display: flex; align-items: center;" class="label"> - <span class="label" style="padding: 0 5px; width: 100px;">From Format</span> - <input class="input-text" ngModel required name="fromFormat" [(ngModel)]="action.dateFormatter.fromFormat" type="text"> + <div class="from-container"> + <div style="display: flex; align-items: center; width: 100%;" class="label"> + <span class="label" style="padding: 0 5px; width: 100px;">Title</span> + <input required class="input-text" data-tests-id="InputLogTitle" ngModel name="title" [(ngModel)]="action.logEvent.title" + type="text" placeholder="The title for the log entry"> </div> </div> </div> + </div> + + <!-- log Text --> + <div *ngIf="action.actionType === 'log text'" class="center-content-item"> <div class="from"> - <div class="from-conatiner"> - <div style="display: flex; align-items: center;" class="label"> - <span class="label" style="padding: 0 5px; width: 100px;">To Format</span> - <input class="input-text" ngModel required name="toFormat" [(ngModel)]="action.dateFormatter.toFormat" type="text"> + <div class="from-container"> + <div style="display: flex; align-items: center; width: 100%;" class="label"> + <span class="label" style="padding: 0 5px; width: 100px;">Log Text</span> + <input required class="input-text" data-tests-id="InputLogText" ngModel name="logText" [(ngModel)]="action.logText.text" + type="text" placeholder="The title for the log entry"> </div> </div> </div> </div> - <div style="display: flex; margin: 0.5em 0;"> - <div class="from"> - <div class="from-conatiner"> - <div style="display: flex; align-items: center;" class="label"> - <span class="label" style="padding: 0 5px; width: 100px;">From Time-zone</span> - <input class="input-text" ngModel required name="fromTimezone" [(ngModel)]="action.dateFormatter.fromTimezone" type="text"> + </div> + + <!-- dateFormatter --> + <div *ngIf="action.actionType === 'date formatter'" style="flex-direction: column; margin-left: 156px; align-items: flex-end;"> + <div style="display: flex; margin: 0.5em 0; padding-left: 6px;"> + <div class="from" style="width:50%;"> + <div class="from-container"> + <div style="display: flex; align-items: center; width: 100%;" class="label"> + <span class="label" style="padding: 0 5px; width: 100px;">From Format</span> + <input data-tests-id="InputFromFormat" class="input-text" ngModel required name="fromFormat" [(ngModel)]="action.dateFormatter.fromFormat" type="text"> + </div> + </div> + </div> + <div class="from" style="width:50%; padding: 0;"> + <div class="from-container"> + <div style="display: flex; align-items: center; width: 100%;" class="label"> + <span class="label" style="padding: 0 5px; width: 100px;">To Format</span> + <input data-tests-id="InputToFormat" class="input-text" ngModel required name="toFormat" [(ngModel)]="action.dateFormatter.toFormat" type="text"> + </div> + </div> + </div> + </div> + + <div style="display: flex; margin: 0.5em 0; padding-left: 6px;"> + <div class="from" style="width:50%;"> + <div class="from-container"> + <div style="display: flex; align-items: center; width: 100%;" class="label"> + <span class="label" style="padding: 0 5px; width: 132px;">From Time-zone</span> + <input class="input-text" data-tests-id="InputFromTimezone" ngModel required name="fromTimezone" [(ngModel)]="action.dateFormatter.fromTimezone" type="text"> + </div> + </div> + </div> + <div class="from" style="width:50%; padding: 0;"> + <div class="from-container"> + <div style="display: flex; align-items: center; width: 100%;" class="label"> + <span class="label" style="padding: 0 5px; width: 100px;">To Time-zone</span> + <input class="input-text" data-tests-id="InputToTimezone" ngModel required name="toTimezone" [(ngModel)]="action.dateFormatter.toTimezone" type="text"> + </div> + </div> </div> </div> </div> - <div class="from"> - <div class="from-conatiner"> - <div style="display: flex; align-items: center;" class="label"> - <span class="label" style="padding: 0 5px; width: 100px;">To Time-zone</span> - <input class="input-text" ngModel required name="toTimezone" [(ngModel)]="action.dateFormatter.toTimezone" type="text"> + + <!-- replace text --> + <div *ngIf="action.actionType === 'replace text'" class="action-container" style="flex-direction: row; margin-left: 152px; padding: 0 0.8em;"> + + <div class="action-item"> + <div class="from" style="width:100%;"> + <div class="from-container" display="padding:0;"> + + <div class="label" style="width: 100%;"> + <span class="label" style="padding: 0 5px; width: 100px;">Find what</span> + <input data-tests-id="InputFindWhat" class="input-text" ngModel required name="findWhat" [(ngModel)]="action.replaceText.find" + type="text" placeholder="Find text"> + </div> + + </div> + </div> + + </div> + + <div class="action-item"> + <div class="from" style="width: 100%; padding: 0;"> + <div class="from-container"> + + <div class="label" style="width: 100%;"> + <span class="label" style="padding: 0 5px; width: 100px;">Replace with</span> + <input data-tests-id="InputReplaceWith" class="input-text" ngModel required name="replaceWith" [(ngModel)]="action.replaceText.replace" + type="text" placeholder="Replace with text"> + </div> + + </div> + </div> + + </div> + </div> + + <!-- log text --> + <div *ngIf="action.actionType === 'log text'" class="action-container" style="flex-direction: row; margin-left: 152px; padding: 0 0.8em;"> + + <div class="action-item"> + <div class="from" style="width: 100%;"> + <div class="from-container" display="padding:0;"> + <div class="label" style="width: 100%;"> + <span class="label" style="padding: 0 5px; width: 100px;">Log Name</span> + <input class="input-text" data-tests-id="InputLogName" ngModel name="logName" [(ngModel)]="action.logText.name" + type="text" placeholder="Enter log name"> + </div> + </div> + </div> + </div> + + <div class="action-item"> + <div class="from" style="width: 100%; padding: 0;"> + <div class="from-container"> + <div class="label" style="width: 100%;"> + <span class="label" style="padding: 0 5px; width: 100px;">Log Level</span> + <input class="input-text" data-tests-id="InputLogLevel" ngModel required name="logLevel" [(ngModel)]="action.logText.level" + type="text" placeholder="Text to log"> </div> </div> </div> </div> + </div> <!-- Map --> @@ -90,8 +185,8 @@ <input [(ngModel)]="item.value" ngModel required name="mapValue[{{index}}]" data-tests-id="value" type="text" style="width:97%; height: 100%;border: none; padding:0 5px;"> </th> <th style="height: 30px; display: flex; align-items: baseline;"> - <button mat-icon-button [ngStyle]="hoveredIndex === index ? {'opacity':'1'} : {'opacity':'0'}" class="button-remove" (click)="removeMapRow(index)" - *ngIf="action.map.values.length > 1" style="height: 24px; width: 24px; display:flex; box-shadow: none;"> + <button mat-icon-button data-tests-id="btn-remove-row" [ngStyle]="hoveredIndex === index ? {'opacity':'1'} : {'opacity':'0'}" + class="button-remove" (click)="removeMapRow(index)" *ngIf="action.map.values.length > 1" style="height: 24px; width: 24px; display:flex; box-shadow: none;"> <mat-icon class="md-24">delete</mat-icon> </button> </th> @@ -102,8 +197,9 @@ <div style="display:flex; justify-content: space-between;"> <div style="display: flex; align-items: center;"> - <button mat-mini-fab color="primary" (click)="addMapRow()" style="height: 24px; width: 24px; display:flex; box-shadow: none;"> - <mat-icon>add</mat-icon> + <button mat-mini-fab color="primary" (click)="addMapRow()" data-tests-id="btn-add-row" style="height: 16px; width: 16px; display:flex; box-shadow: none;"> + <span style="padding-left: 2px; display: flex; justify-content: center; align-items: center" [innerHTML]="'plus' | feather:12"></span> + <!-- <mat-icon>add</mat-icon> --> </button> <span style="color: #009FDB; display: flex; justify-content: center; padding-left: 6px">Add Row</span> </div> diff --git a/public/src/app/rule-engine/action/action.component.scss b/public/src/app/rule-engine/action/action.component.scss index f903db4..fc36380 100644 --- a/public/src/app/rule-engine/action/action.component.scss +++ b/public/src/app/rule-engine/action/action.component.scss @@ -4,7 +4,7 @@ width: 100%; height: 100%; justify-content: space-between; - margin: 10px 0; + margin-top: 10px; .black { color: black; } @@ -25,9 +25,12 @@ justify-content: center; min-width: 142px; } + .center-content-item { + width: 100%; + } } .map-container { - padding-left: 115px; + padding-left: 172px; .default { display: flex; width: 100%; @@ -82,7 +85,7 @@ display: flex; flex-direction: column; padding: 0 10px; - .from-conatiner { + .from-container { display: flex; flex-direction: column; align-items: flex-start; @@ -114,3 +117,17 @@ color: #009fdb; } } + +.action-container { + display: flex; + flex-direction: column; + align-items: flex-end; +} +.action-item { + width: 100%; + margin-top: 0.5em; +} +.label .action-item-label { + padding: 0 5px; + width: 110px; +} diff --git a/public/src/app/rule-engine/action/action.component.ts b/public/src/app/rule-engine/action/action.component.ts index 9c7023f..1a62e1a 100644 --- a/public/src/app/rule-engine/action/action.component.ts +++ b/public/src/app/rule-engine/action/action.component.ts @@ -27,9 +27,12 @@ export class ActionComponent implements OnInit { if (this.action.from !== '') { console.log('Action %o', this.action); this.fromInstance.updateMode(this.action.from); + } + if (this.action.target !== '') { this.targetInstance.updateMode(this.action); } } + updateFrom(data) { this.action.from = data; } diff --git a/public/src/app/rule-engine/api/rule-engine-api.service.spec.ts b/public/src/app/rule-engine/api/rule-engine-api.service.spec.ts deleted file mode 100644 index e15535b..0000000 --- a/public/src/app/rule-engine/api/rule-engine-api.service.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { TestBed, inject } from '@angular/core/testing'; -import { HttpModule } from '@angular/http'; -import { RuleEngineApiService } from './rule-engine-api.service'; - -describe('RuleEngineApiService', () => { - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [HttpModule], - providers: [RuleEngineApiService] - }); - }); - - it( - 'should be created', - inject([RuleEngineApiService], (service: RuleEngineApiService) => { - expect(service).toBeTruthy(); - }) - ); -}); diff --git a/public/src/app/rule-engine/api/rule-engine-api.service.ts b/public/src/app/rule-engine/api/rule-engine-api.service.ts index 0d7ab5e..7bf5e18 100644 --- a/public/src/app/rule-engine/api/rule-engine-api.service.ts +++ b/public/src/app/rule-engine/api/rule-engine-api.service.ts @@ -1,17 +1,17 @@ -import { Injectable, EventEmitter } from '@angular/core'; +import { Injectable } from '@angular/core'; import { - Http, - Response, Headers, + Http, RequestOptions, + Response, URLSearchParams } from '@angular/http'; -import { Observable, Subject } from 'rxjs/Rx'; +import 'rxjs/add/operator/catch'; // Import RxJs required methods import 'rxjs/add/operator/map'; -import 'rxjs/add/operator/catch'; -import { environment } from '../../../environments/environment'; +import { Observable, Subject } from 'rxjs/Rx'; import { v4 as uuid } from 'uuid'; +import { environment } from '../../../environments/environment'; @Injectable() export class RuleEngineApiService { @@ -25,6 +25,7 @@ export class RuleEngineApiService { flowType: string; editorData: Subject<any> = new Subject(); updateVersionLock: Subject<any> = new Subject(); + tabIndex: Subject<any> = new Subject(); constructor(private http: Http) { this.baseUrl = `${environment.apiBaseUrl}/rule-editor`; @@ -108,16 +109,35 @@ export class RuleEngineApiService { }); } - translate() { - const url = `${this.baseUrl}/rule/translate/${this.vfcmtUuid}/${ - this.dcaeCompName - }/${this.nid}/${this.configParam}`; + translate(nofityId) { + const url = `${this.baseUrl}/rule/translate`; + const params = { + vfcmtUuid: this.vfcmtUuid, + dcaeCompLabel: this.dcaeCompName, + nid: this.nid, + configParam: this.configParam, + flowType: this.flowType, + notifyId: nofityId + }; + this.options.headers.set('X-ECOMP-RequestID', uuid()); + // const params = new URLSearchParams(); params.append('flowType', + // this.flowType); const options = { ...this.options, params: params }; + return this.http + .post(url, params, this.options) + .map(response => response.json()) + .catch((error: any) => { + return Observable.throw(error.json().requestError || 'Server error'); + }); + } + + generateMappingRulesFileName(dcaeCompLabel, nid, vfcmtUuid) { + const url = `${ + this.baseUrl + }/getExistingRuleTargets/${vfcmtUuid}/${dcaeCompLabel}/${nid}`; this.options.headers.set('X-ECOMP-RequestID', uuid()); const params = new URLSearchParams(); - params.append('flowType', this.flowType); - const options = { ...this.options, params: params }; return this.http - .get(url, options) + .get(url, this.options) .map(response => response.json()) .catch((error: any) => { return Observable.throw(error.json().requestError || 'Server error'); @@ -131,4 +151,8 @@ export class RuleEngineApiService { callUpdateVersionLock() { this.updateVersionLock.next(); } + + callUpdateTabIndex(index) { + this.tabIndex.next(index); + } } diff --git a/public/src/app/rule-engine/condition/condition.component.html b/public/src/app/rule-engine/condition/condition.component.html index a441f55..0ff244b 100644 --- a/public/src/app/rule-engine/condition/condition.component.html +++ b/public/src/app/rule-engine/condition/condition.component.html @@ -18,7 +18,7 @@ <div style="display: flex; margin-left: auto;"> <div style="display: flex; align-items: center; padding: 0 25px;"> - <button mat-mini-fab color="primary" (click)="addConditional(tree, node)" style="height: 24px; width: 24px; display:flex; box-shadow: none;"> + <button mat-mini-fab color="primary" data-tests-id="addCondition" (click)="addConditional(tree, node)" style="height: 24px; width: 24px; display:flex; box-shadow: none;"> <mat-icon class="material-icons md-18">add</mat-icon> </button> <span class="btn-label">Add Condition @@ -36,7 +36,7 @@ </div> <div style="display: flex; align-items: center; padding: 0 5px; background: #FFFFFF;"> - <button mat-icon-button (click)="removeConditional(tree, node)" class="button-remove"> + <button data-tests-id="removeConditionNode" mat-icon-button (click)="removeConditional(tree, node)" class="button-remove"> <mat-icon class="md-24">delete</mat-icon> </button> </div> @@ -77,7 +77,7 @@ </div> <!-- remove button --> <div class="show-delete"> - <button mat-icon-button (click)="removeConditional(tree, node)" class="button-remove"> + <button mat-icon-button data-tests-id="RemoveCondition" (click)="removeConditional(tree, node)" class="button-remove"> <mat-icon class="md-24">delete</mat-icon> </button> </div> diff --git a/public/src/app/rule-engine/condition/condition.component.spec.ts b/public/src/app/rule-engine/condition/condition.component.spec.ts deleted file mode 100644 index bb0d38a..0000000 --- a/public/src/app/rule-engine/condition/condition.component.spec.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { HttpModule } from '@angular/http'; -import { - MatDialogModule, - MatButtonModule, - MatIconModule, - MatDialogRef, - MAT_DIALOG_DATA -} from '@angular/material'; - -import { ConditionComponent } from './condition.component'; - -describe('Condition Component', () => { - let component: ConditionComponent; - let fixture: ComponentFixture<ConditionComponent>; - let de: DebugElement; - let el: HTMLElement; - - beforeEach( - async(() => { - TestBed.configureTestingModule({ - imports: [ - FormsModule, - HttpModule, - MatDialogModule, - MatButtonModule, - MatIconModule - ], - providers: [], - schemas: [CUSTOM_ELEMENTS_SCHEMA], - declarations: [ConditionComponent] - }).compileComponents(); - }) - ); - - beforeEach(() => { - // create component and test fixture - fixture = TestBed.createComponent(ConditionComponent); - // get test component from the fixture - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should be created', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/public/src/app/rule-engine/confirm-popup/confirm-popup.component.html b/public/src/app/rule-engine/confirm-popup/confirm-popup.component.html index 49c800a..837e0f8 100644 --- a/public/src/app/rule-engine/confirm-popup/confirm-popup.component.html +++ b/public/src/app/rule-engine/confirm-popup/confirm-popup.component.html @@ -1,12 +1,36 @@ -<div class="container" data-tests-id="delete-popup"> +<div class="container-popup" data-tests-id="delete-popup"> <div class="header"> - Delete + <div style="display: flex; width:100%;"> + <span style="color: #CF2A2A; + padding-right: 15px; + height: 100%; + display: flex; + justify-content: center; + align-items: center;" [innerHTML]="'x-circle' | feather:28"></span> + <span style="font-family: 'Open Sans', sans-serif; + font-size: 24px; width: 100%;"> + Delete + </span> + <span style=" + height: 100%; + display: flex; + color:rgb(90, 90, 90); + justify-content: center; + align-items: center;" [innerHTML]="'x' | feather:20" (click)="close(false)"></span> + </div> </div> - <div class="content"> + <div class="content" style="padding: 0 0 20px 50px; font-family: 'Open Sans', sans-serif; font-size: 14px;"> Are you sure you want to delete? </div> <div class="buttons"> - <button mat-raised-button (click)="close(true)" data-tests-id="btnDelete" style="margin-right: 1rem;" color="primary">Delete</button> - <button mat-raised-button (click)="close(false)" data-tests-id="btnCancel" style="border: 1px solid #009FDB; color: #009FDB; background: #ffffff;">Cancel</button> + + <button mat-raised-button color="primary" style="background-color: #CF2A2A; margin-right: 10px; font-size: 14px; font-family: 'Open Sans', sans-serif; height: 36px; color:white;" + (click)="close(true)" data-tests-id="btnDelete"> + DELETE + </button> + <button mat-raised-button class="btn-secondry" style="border-color: #CF2A2A !important; color:#CF2A2A !important; font-size: 14px; font-family: 'Open Sans', sans-serif;text-align: center; height: 36px;" + (click)="close(false)" data-tests-id="btnCancel"> + CANCEL + </button> </div> </div> diff --git a/public/src/app/rule-engine/confirm-popup/confirm-popup.component.scss b/public/src/app/rule-engine/confirm-popup/confirm-popup.component.scss index 2a826ff..4e3539d 100644 --- a/public/src/app/rule-engine/confirm-popup/confirm-popup.component.scss +++ b/public/src/app/rule-engine/confirm-popup/confirm-popup.component.scss @@ -1,10 +1,19 @@ -.container { +.my-confrim-dialog .mat-dialog-container { + height: 180px; +} + +.container-popup { display: flex; justify-content: space-between; + flex-direction: column; margin: 0 !important; - border-top: solid 6px #ffb81c; + border-top: solid 6px #cf2a2a; .header { border-bottom: none; + padding-top: 15px; + padding-left: 20px; + padding-right: 12px; + padding-bottom: 0; } .content { margin: 1rem; diff --git a/public/src/app/rule-engine/confirm-popup/confirm-popup.component.ts b/public/src/app/rule-engine/confirm-popup/confirm-popup.component.ts index 23b6cee..d65cc5b 100644 --- a/public/src/app/rule-engine/confirm-popup/confirm-popup.component.ts +++ b/public/src/app/rule-engine/confirm-popup/confirm-popup.component.ts @@ -1,10 +1,11 @@ -import { Component, Inject } from '@angular/core'; +import { Component, Inject, ViewEncapsulation } from '@angular/core'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; @Component({ selector: 'app-confirm-popup', templateUrl: './confirm-popup.component.html', - styleUrls: ['./confirm-popup.component.scss'] + styleUrls: ['./confirm-popup.component.scss'], + encapsulation: ViewEncapsulation.None }) export class ConfirmPopupComponent { constructor( diff --git a/public/src/app/rule-engine/from/from.component.html b/public/src/app/rule-engine/from/from.component.html index 7af653d..df2c110 100644 --- a/public/src/app/rule-engine/from/from.component.html +++ b/public/src/app/rule-engine/from/from.component.html @@ -1,6 +1,6 @@ <form #fromFrm="ngForm" novalidate> <!-- Copy template --> - <div class="from" *ngIf="actionType === 'copy'" data-tests-id="fromComponent"> + <div class="from" *ngIf="actionType === 'copy' || actionType === 'replace text' || actionType === 'log text'" data-tests-id="fromComponent"> <div class="from-conatiner"> <div style="display: flex; align-items: center; width: 100%;" class="label"> <span class="label" style="padding: 0 5px; width: 50px;">From</span> @@ -38,6 +38,39 @@ </div> </div> + <!-- clear template --> + <div class="from" *ngIf="actionType === 'clear'" ngModelGroup="clear" #clearFrom="ngModelGroup"> + <div *ngFor="let input of from.values; let index = index;" data-tests-id="clearInputArrayFrom" (mouseleave)="hoveredIndex=-1" + (mouseover)="hoveredIndex=index" class="from-conatiner" style="margin-bottom:1rem; display: flex; flex-direction: column; align-items: flex-start;" + data-tests-id="fromComponent"> + <div style="display: flex; align-items: center; width: 100%;"> + <div style="display: flex; align-items: center; width: 100%;" class="label"> + <span class="label" style="padding: 0 5px; width: 50px;">From</span> + <input class="input-text" (ngModelChange)="modelChange(from)" [(ngModel)]="input.value" type="text" data-tests-id="valueInput" + ngModel required name="clear[{{index}}]"> + </div> + + <button mat-icon-button class="button-remove" [ngStyle]="hoveredIndex === index ? {'opacity':'1'} : {'opacity':'0'}" (click)="removeFromInput(index)" + *ngIf="from.values.length > 1" style="box-shadow: none; height: 24px; width: 24px; display:flex" data-tests-id="btnDelete"> + <mat-icon class="md-24">delete</mat-icon> + </button> + </div> + + </div> + <div style="display:flex; justify-content: space-between;"> + <div style="display: flex; align-items: center;"> + <button mat-mini-fab color="primary" (click)="addFromInput()" style="box-shadow: none; height: 16px; width: 16px; display:flex" + data-tests-id="btnAddInput"> + <span style="padding-left: 2px; display: flex; justify-content: center; align-items: center" [innerHTML]="'plus' | feather:12"></span> +<!-- + <mat-icon>add</mat-icon> --> + </button> + <span style="color: #009FDB; display: flex; justify-content: center; padding-left: 6px">Add input</span> + </div> + </div> + </div> + + <!-- Concat template --> <div class="from" *ngIf="actionType === 'concat'" ngModelGroup="concat" #concatFrom="ngModelGroup"> <div *ngFor="let input of from.values; let index = index;" data-tests-id="concatInputArrayFrom" (mouseleave)="hoveredIndex=-1" @@ -59,11 +92,12 @@ </div> <div style="display:flex; justify-content: space-between;"> <div style="display: flex; align-items: center;"> - <button mat-mini-fab color="primary" (click)="addFromInput()" style="box-shadow: none; height: 24px; width: 24px; display:flex" + <button mat-mini-fab color="primary" (click)="addFromInput()" style="box-shadow: none; height: 16px; width: 16px; display:flex" data-tests-id="btnAddInput"> - <mat-icon>add</mat-icon> + <span style="padding-left: 2px; display: flex; justify-content: center; align-items: center" [innerHTML]="'plus' | feather:12"></span> + <!-- <mat-icon>add</mat-icon> --> </button> - <span style="color: #009FDB; display: flex; justify-content: center; padding-left: 6px">Add input</span> + <span style="color: #009FDB; display: flex; justify-content: center; padding-top: 1px; padding-left: 6px;">Add input</span> </div> </div> </div> diff --git a/public/src/app/rule-engine/from/from.component.ts b/public/src/app/rule-engine/from/from.component.ts index e7c276b..bc1dedb 100644 --- a/public/src/app/rule-engine/from/from.component.ts +++ b/public/src/app/rule-engine/from/from.component.ts @@ -64,6 +64,12 @@ export class FromComponent { hoveredIndex; // public keyUp = new BehaviorSubject<string>(null); + ngOnInit(): void { + if (this.actionType === 'clear') { + this.from.values = [{ value: '' }]; + } + } + showRegex(item) { item.state = item.state === 'closed' ? 'open' : 'closed'; if (item.state === 'closed') { diff --git a/public/src/app/rule-engine/host/exit-mode.enum.ts b/public/src/app/rule-engine/host/exit-mode.enum.ts deleted file mode 100644 index 784ba3b..0000000 --- a/public/src/app/rule-engine/host/exit-mode.enum.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum ExitMode { - Done, - Cancel -} diff --git a/public/src/app/rule-engine/host/host-params.ts b/public/src/app/rule-engine/host/host-params.ts deleted file mode 100644 index f204101..0000000 --- a/public/src/app/rule-engine/host/host-params.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface HostParams { - readonly vfcmtUuid: string; - readonly nodeName: string; - readonly nodeId: string; - readonly fieldName: string; - readonly userId: string; - readonly flowType: string; -} diff --git a/public/src/app/rule-engine/host/host.service.spec.ts b/public/src/app/rule-engine/host/host.service.spec.ts deleted file mode 100644 index 048be80..0000000 --- a/public/src/app/rule-engine/host/host.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { TestBed, inject } from '@angular/core/testing'; - -import { HostService } from './host.service'; - -describe('HostService', () => { - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [HostService] - }); - }); - - it( - 'should be created', - inject([HostService], (service: HostService) => { - expect(service).toBeTruthy(); - }) - ); -}); diff --git a/public/src/app/rule-engine/host/host.service.ts b/public/src/app/rule-engine/host/host.service.ts deleted file mode 100644 index 7918d30..0000000 --- a/public/src/app/rule-engine/host/host.service.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Injectable } from '@angular/core'; -import { HostParams } from './host-params'; -import { ExitMode } from './exit-mode.enum'; - -@Injectable() -export class HostService { - /* Public Members */ - - public static getParams(): HostParams { - return this.getQueryParamsObj(window.location.search) as HostParams; - } - - public static enterModifyRule(): void { - this.postMessage('modifyRule', null); - } - - public static exitModifyRule(): void { - this.postMessage('ruleList', null); - } - - public static disableLoader(): void { - this.postMessage('disable-loader', null); - } - - public static exit(mode: ExitMode, data: string): void { - if (mode === ExitMode.Cancel) { - this.postMessage('exit', null); - } else if (mode === ExitMode.Done) { - this.postMessage('exit', data); - } - } - - /* Private Methods */ - - private static postMessage(eventName: string, data: string): void { - window.parent.postMessage( - { - type: eventName, - data: data - }, - '*' - ); - } - - private static getQueryParamsObj(query: string): object { - return query - .substring(1) // removes '?' that always appears as prefix to the query-string - .split('&') // splits query-string to "key=value" strings - .map(p => p.split('=')) // splits each "key=value" string to [key,value] array - .reduce((res, p) => { - // converts to a dictionary (object) of params - res[p[0]] = p[1]; - return res; - }, {}); - } -} 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 index c68c706..4ce6efb 100644 --- a/public/src/app/rule-engine/rule-list/rule-list.component.html +++ b/public/src/app/rule-engine/rule-list/rule-list.component.html @@ -1,8 +1,8 @@ <div class="container"> <div class="header"> - <span style="font-size: 18px;">Rule Engine</span> + <span style="font-size: 18px; margin-left:20px;">Rule Engine</span> <div style="display:flex"> - <button mat-raised-button (click)="translateRules()" color="primary" [disabled]="store.ruleList.length === 0" style="margin-left: 20px;" + <button mat-raised-button (click)="translateRules()" color="primary" [disabled]="store.ruleList.length === 0" style="margin-right: 10px; width: 113px;height: 36px;" data-tests-id="btnTranslate"> Translate </button> @@ -20,6 +20,35 @@ <app-version-type-select #versionEventType [versions]="versions" [metaData]="metaData" (nodesUpdated)="handleUpdateNode($event)" (refrashRuleList)="handlePropertyChange()"></app-version-type-select> + <!-- <div class="container-phase-notify"> + <div> + <span class="field-label required" style="margin-right: 10px;"> + phase + </span> + <select name="phase" [(ngModel)]="phase" data-tests-id="phase" style="height: 27px; padding: 0.3rem; margin-right: 18px;" + class="field-select"> + <option [ngValue]="null" disabled>Select phase</option> + </select> + </div> + + <div class="default" style="display: flex; align-items: center"> + <div class="pretty p-svg"> + <input type="checkbox" name="notifyCheckbox" data-tests-id="notifyCheckbox" /> + <div class="state"> + <svg class="svg svg-icon" viewBox="0 0 20 20"> + <path d="M7.629,14.566c0.125,0.125,0.291,0.188,0.456,0.188c0.164,0,0.329-0.062,0.456-0.188l8.219-8.221c0.252-0.252,0.252-0.659,0-0.911c-0.252-0.252-0.659-0.252-0.911,0l-7.764,7.763L4.152,9.267c-0.252-0.251-0.66-0.251-0.911,0c-0.252,0.252-0.252,0.66,0,0.911L7.629,14.566z" + style="stroke: #009fdb; fill:#009fdb;"></path> + </svg> + <label>notify OID</label> + </div> + </div> + <div class="input-wrapper"> + <input type="text" ngModel required name="notify-oid" data-tests-id="notify-oid" class="input"> + </div> + </div> + + </div> --> + <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;"> @@ -40,9 +69,6 @@ </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()"> 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 index c4aee05..6446fbd 100644 --- a/public/src/app/rule-engine/rule-list/rule-list.component.scss +++ b/public/src/app/rule-engine/rule-list/rule-list.component.scss @@ -4,30 +4,30 @@ height: 100%; display: flex; flex-direction: column; - + margin: 0; + padding: 0; .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; + border-bottom: 1px solid #d2d2d2; + padding-bottom: 5px; + margin: 8px 0; } - .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; @@ -46,7 +46,6 @@ display: flex !important; justify-content: center !important; color: #d2d2d2 !important; - &:hover { color: #009fdb !important; } @@ -68,6 +67,7 @@ .mat-mini-fab .mat-button-wrapper { padding: 0 !important; } + .mat-icon { // width: 18px; // height: 18px; @@ -75,35 +75,45 @@ 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 index 45cfbd0..2857ea2 100644 --- a/public/src/app/rule-engine/rule-list/rule-list.component.ts +++ b/public/src/app/rule-engine/rule-list/rule-list.component.ts @@ -1,12 +1,11 @@ -import { Component, ViewEncapsulation, ViewChild } from '@angular/core'; +import { Component, ViewChild, ViewEncapsulation } 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'; +import { Store } from '../../store/store'; +import { RuleEngineApiService } from '../api/rule-engine-api.service'; +import { ConfirmPopupComponent } from '../confirm-popup/confirm-popup.component'; const primaryColor = '#009fdb'; @@ -58,7 +57,11 @@ export class RuleListComponent { ); this.store.updateRuleList(Object.values(response.rules)); this.targetSource = response.schema; + this.store.notifyIdValue = response.notifyId; + this.versionType.notifyIdCheckbox = + response.notifyId !== '' ? true : false; } else { + this.versionType.notifyIdCheckbox = false; this.store.resetRuleList(); this.versionType.updateVersionTypeFlag(false); this.targetSource = null; @@ -83,20 +86,29 @@ export class RuleListComponent { 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(); + this.store.loader = false; + this._ruleApi.tabIndex.subscribe(index => { + console.log('rule index in rule-list component:', index); + const tabName = this.store.cdump.nodes[index].name; + console.log('tab name:', tabName); + + if (tabName.toLowerCase().includes('map')) { + this.params = { + vfcmtUuid: this.store.mcUuid, + nodeName: this.store.tabParmasForRule[0].name, + nodeId: this.store.tabParmasForRule[0].nid, + fieldName: this.store.tabsProperties[index][0].name, + userId: 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); + store.ruleListExistParams = this.params; + this.getListOfRules(); + } + }); } handlePropertyChange() { @@ -108,7 +120,8 @@ export class RuleListComponent { translateRules() { this.store.loader = true; // send translate JSON - this._ruleApi.translate().subscribe( + const nofityId = this.store.notifyIdValue; + this._ruleApi.translate(nofityId).subscribe( data => { this.store.loader = false; console.log(JSON.stringify(data)); @@ -116,7 +129,7 @@ export class RuleListComponent { this.store.configurationForm.forEach(property => { console.log('mappingTarget ', this.versionType.mappingTarget); if (property.name === this.versionType.mappingTarget) { - property.assignment.value = JSON.stringify(data); + property.value = JSON.stringify(data); domElementName = property.name; console.log(property.name); } diff --git a/public/src/app/rule-engine/target/target.component.html b/public/src/app/rule-engine/target/target.component.html index 7a321ef..d643ad8 100644 --- a/public/src/app/rule-engine/target/target.component.html +++ b/public/src/app/rule-engine/target/target.component.html @@ -7,7 +7,7 @@ <img src="{{imgBase}}/target.svg" alt="target"> </span> </div> - <div class="bottom-select" *ngIf="showOption" [@toggleDropdown]> + <div class="bottom-select" *ngIf="showOption"> <div class="filter-container" style="display: flex; border-bottom: 1px solid #F2F2F2;margin-bottom: 1rem; width:100%;"> <input id="filter" #filter class="filter" (keyup)="tree.treeModel.filterNodes(filter.value)" placeholder="Search..." /> <button mat-raised-button style="min-width: 18px; box-shadow: none; display: flex; justify-content: center;" (click)="tree.treeModel.clearFilter(); filter.value = ''"> diff --git a/public/src/app/rule-engine/target/target.component.spec.ts b/public/src/app/rule-engine/target/target.component.spec.ts index 6ddd8cd..e9a69c8 100644 --- a/public/src/app/rule-engine/target/target.component.spec.ts +++ b/public/src/app/rule-engine/target/target.component.spec.ts @@ -1,10 +1,9 @@ -import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA, DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MatButtonModule, MatIconModule } from '@angular/material'; +import { By } from '@angular/platform-browser'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; // component import { TargetComponent } from './target.component'; @@ -46,12 +45,28 @@ describe('TargetComponent', () => { const openTargetElement = fixture.debugElement .query(By.css('span[data-tests-id=openTargetTree]')) .nativeElement.click(); - fixture.detectChanges(); - const treeContainer = fixture.debugElement.query( By.css('.filter-container') ); expect(treeContainer).not.toBeNull(); }); + + it('should toggle target tree when clicking 2 times on button', () => { + fixture.debugElement + .query(By.css('span[data-tests-id=openTargetTree]')) + .nativeElement.click(); + fixture.detectChanges(); + fixture.debugElement + .query(By.css('span[data-tests-id=openTargetTree]')) + .nativeElement.click(); + fixture.detectChanges(); + const treeContainer = fixture.debugElement.query( + By.css('.filter-container') + ); + expect(treeContainer).toBeNull(); + }); + + // it('check when input change', () => { tree.setData({nodes: _nodes, options: + // null, events: null}); component.filterFn('liav', tree); }); }); diff --git a/public/src/app/rule-engine/target/target.component.ts b/public/src/app/rule-engine/target/target.component.ts index f17cdef..c9aa75c 100644 --- a/public/src/app/rule-engine/target/target.component.ts +++ b/public/src/app/rule-engine/target/target.component.ts @@ -7,13 +7,8 @@ import { EventEmitter } from '@angular/core'; import { TreeModel, TreeComponent, ITreeOptions } from 'angular-tree-component'; -import { - trigger, - state, - animate, - transition, - style -} from '@angular/animations'; +// import {trigger, state, animate, transition, style} from +// '@angular/animations'; import { fuzzysearch, getBranchRequierds, validation } from './target.util'; import { environment } from '../../../environments/environment'; import { NgForm } from '@angular/forms'; @@ -22,24 +17,15 @@ import { NgForm } from '@angular/forms'; selector: 'app-target', templateUrl: './target.component.html', styleUrls: ['./target.component.scss'], - encapsulation: ViewEncapsulation.None, - animations: [ - trigger('toggleDropdown', [ - transition('void => *', [ - style({ opacity: 0, offset: 0, height: 0 }), - animate('300ms cubic-bezier(0.17, 0.04, 0.03, 0.94)') - ]), - transition('* => void', [ - style({ opacity: 1, offset: 1, height: 'auto' }), - animate('100ms cubic-bezier(0.17, 0.04, 0.03, 0.94)') - ]) - ]) - ] + encapsulation: ViewEncapsulation.None }) export class TargetComponent { imgBase = environment.imagePath; showOption = false; - selectedNode = { name: '', id: '' }; + selectedNode = { + name: '', + id: '' + }; @Input() nodes; @Output() onTargetChange = new EventEmitter(); @ViewChild(TreeComponent) private tree: TreeComponent; diff --git a/public/src/app/rule-engine/target/target.validation.spec.ts b/public/src/app/rule-engine/target/target.validation.spec.ts index 71dc083..e66235f 100644 --- a/public/src/app/rule-engine/target/target.validation.spec.ts +++ b/public/src/app/rule-engine/target/target.validation.spec.ts @@ -1,8 +1,7 @@ -import { TestBed, async } from '@angular/core/testing'; -import { TreeModel, TreeComponent, ITreeOptions } from 'angular-tree-component'; -import { validation, getBranchRequierds } from './target.util'; +import { TreeModel } from 'angular-tree-component'; +import { fuzzysearch, getBranchRequierds, validation } from './target.util'; -const _nodes = [ +export const _nodes = [ { id: 1, name: 'North America', @@ -13,46 +12,68 @@ const _nodes = [ name: 'United States', requiredChildren: ['New York', 'Florida'], children: [ - { id: 111, name: 'New York' }, - { id: 112, name: 'California' }, - { id: 113, name: 'Florida' } + { + id: 111, + name: 'New York' + }, + { + id: 112, + name: 'California' + }, + { + id: 113, + name: 'Florida' + } ] }, - { id: 12, name: 'Canada' } + { + id: 12, + name: 'Canada' + } ] }, { name: 'South America', - children: [{ name: 'Argentina', children: [] }, { name: 'Brazil' }] + children: [ + { + name: 'Argentina', + children: [] + }, + { + name: 'Brazil' + } + ] }, { name: 'Europe', children: [ - { name: 'England' }, - { name: 'Germany' }, - { name: 'France' }, - { name: 'Italy' }, - { name: 'Spain' } + { + name: 'England' + }, + { + name: 'Germany' + }, + { + name: 'France' + }, + { + name: 'Italy' + }, + { + name: 'Spain' + } ] } ]; -const tree = new TreeModel(); +export const tree = new TreeModel(); describe('treeTest', () => { beforeAll(() => { - tree.setData({ - nodes: _nodes, - options: null, - events: null - }); + tree.setData({ nodes: _nodes, options: null, events: null }); }); - it('should return node branch requireds', () => { - // console.log('root', tree.getFirstRoot().data.name); - // console.log(tree.getNodeBy((node) => node.data.name === 'California').data.uuid); - // console.log(tree.getNodeBy((node) => node.data.name === 'California').id); - // console.log(tree.getNodeById(1)); + it('should return node branch requireds toBeGreaterThan 1', () => { const selectedNode = tree.getNodeBy( node => node.data.name === 'California' ); @@ -60,6 +81,14 @@ describe('treeTest', () => { const expected = [['New York', 'Florida'], ['United States']]; expect(result.length).toBeGreaterThan(1); + }); + + it('should return node branch requireds', () => { + const selectedNode = tree.getNodeBy( + node => node.data.name === 'California' + ); + const result = getBranchRequierds(selectedNode, []); + const expected = [['New York', 'Florida'], ['United States']]; expect(result).toEqual(expected); }); @@ -67,9 +96,14 @@ describe('treeTest', () => { const userSelect = ['Florida', 'New York', 'United States']; const selectedNode = tree.getNodeBy(node => node.data.name === 'New York'); const result = validation(selectedNode, userSelect); + expect(result).toEqual([]); + }); + it('should return empty array - success state lenght zero', () => { + const userSelect = ['Florida', 'New York', 'United States']; + const selectedNode = tree.getNodeBy(node => node.data.name === 'New York'); + const result = validation(selectedNode, userSelect); expect(result.length).toEqual(0); - expect(result).toEqual([]); }); it('should return validation array - missing required filed', () => { @@ -80,4 +114,29 @@ describe('treeTest', () => { expect(result).toEqual(expected); }); + + it('fuzzysearch find match one char', () => { + const search = fuzzysearch('1', '1'); + expect(search).toBe(true); + }); + + it('fuzzysearch find match string', () => { + const search = fuzzysearch('liav', 'liavEzar'); + expect(search).toBe(true); + }); + + it('fuzzysearch not find match', () => { + const search = fuzzysearch('1', '2'); + expect(search).toBe(false); + }); + + it('fuzzysearch not find match', () => { + const search = fuzzysearch('liavEzar', 'liav'); + expect(search).toBe(false); + }); + + it('fuzzysearch not find match', () => { + const search = fuzzysearch('var', 'r2f44'); + expect(search).toBe(false); + }); }); diff --git a/public/src/app/rule-engine/version-type-select/version-type-select.component.html b/public/src/app/rule-engine/version-type-select/version-type-select.component.html index 79b9eae..74c55a8 100644 --- a/public/src/app/rule-engine/version-type-select/version-type-select.component.html +++ b/public/src/app/rule-engine/version-type-select/version-type-select.component.html @@ -1,34 +1,64 @@ <div class="selected-event"> - <div style="flex:1; display: flex; align-items: center;"> + <div style="flex:1; display: flex; align-items: flex-end;"> - <span class="field-label required" style="margin-right: 10px;">Mapping Target</span> - <select name="mappingTarget" [(ngModel)]="mappingTarget" (ngModelChange)="onChangeMapping($event)" data-tests-id="mappingDdl" - style="height: 27px; padding: 0.3rem; margin-right: 18px;" class="field-select"> - <option [ngValue]="null" disabled>Select Mapping</option> - <option *ngFor="let target of advancedSetting" [value]="target.name" data-tests-id="templateOptions">{{target.name}}</option> - </select> + <div style="display:flex; flex-direction:column; margin-right: 25px;"> + <span class="field-label required space-down" style="margin-right: 10px;">Mapping Target</span> + <select name="mappingTarget" [(ngModel)]="mappingTarget" (ngModelChange)="onChangeMapping($event)" data-tests-id="mappingDdl" + style="height: 35px; padding: 0.3rem; border: 1px solid #d2d2d2" class="field-select"> + <option [ngValue]="null" disabled>Select Mapping</option> + <optgroup label="Rules Configured"> + <option *ngFor="let target of advancedSetting" [hidden]="!target.isExist" [value]="target.name" data-tests-id="templateOptionsExist">{{target.name}}</option> + </optgroup> + <optgroup label="No Mapping Configuration"> + <option *ngFor="let target of advancedSetting" [hidden]="target.isExist" [value]="target.name" data-tests-id="templateOptionsNotExist">{{target.name}}</option> + </optgroup> + </select> + </div> - <span class="field-label required" style="font-size: 13px; margin-right: 10px; display: flex; - align-items: center;" [ngClass]="{'required' : !readOnly}"> - Version - </span> - <select *ngIf="!readOnly" style="height: 27px; padding: 0.3rem; margin-right: 18px;" [(ngModel)]="selectedVersion" (ngModelChange)="onSelectVersion($event)" - data-tests-id="selectVersion"> - <option [ngValue]="null" disabled>Select Version</option> - <option *ngFor="let version of versions" [value]="version" data-tests-id="option">{{version}}</option> - </select> - <span *ngIf="readOnly" style="height: 27px; padding: 0.3rem; width:100px; margin-right: 18px; border: 1px solid #D2D2D2; display: flex; align-items: center; background: #F2F2F2">{{selectedVersion}}</span> + <div style="display:flex; flex-direction:column; margin-right: 25px;"> + <span class="field-label required space-down" style="font-size: 13px; margin-right: 10px; display: flex; + align-items: center;" [ngClass]="{'required' : !readOnly}"> + Version + </span> + <select *ngIf="!readOnly" style="height: 35px; padding: 0.3rem; border: 1px solid #d2d2d2" [(ngModel)]="selectedVersion" (ngModelChange)="onSelectVersion($event)" + data-tests-id="selectVersion"> + <option [ngValue]="null" disabled>Select Version</option> + <option *ngFor="let version of versions" [value]="version" data-tests-id="option">{{version}}</option> + </select> + <span *ngIf="readOnly" style="height: 35px; padding: 0.3rem; width:100px; border: 1px solid #D2D2D2; display: flex; align-items: center; background: #F2F2F2">{{selectedVersion}}</span> + </div> - <span class="field-label required" style="font-size: 13px; display: flex; align-items: center; width: 100px;" [ngClass]="{'required' : !readOnly}"> - Event Domain - </span> - <select *ngIf="!readOnly" style="height: 27px; padding: 0.3rem;" [(ngModel)]="selectedEvent" (ngModelChange)="onSelectEventType($event)" - data-tests-id="selectEventType"> - <option [ngValue]="null" disabled>Select Type</option> - <option *ngFor="let event of events" [value]="event" data-tests-id="option">{{event | slice:0:event.length-6}}</option> - </select> - <span *ngIf="readOnly" style="height: 27px; padding: 0.3rem; width:200px; border: 1px solid #D2D2D2; display: flex; align-items: center; background: #F2F2F2">{{selectedEvent | slice:0:selectedEvent.length-6}}</span> + <div style="display:flex; flex-direction:column; margin-right: 25px;"> + <span class="field-label required space-down" style="font-size: 13px; display: flex; align-items: center; width: 100px;" + [ngClass]="{'required' : !readOnly}"> + Event Domain + </span> + <select *ngIf="!readOnly" style="height: 35px; padding: 0.3rem; border: 1px solid #d2d2d2" [(ngModel)]="selectedEvent" (ngModelChange)="onSelectEventType($event)" + data-tests-id="selectEventType"> + <option [ngValue]="null" disabled>Select Type</option> + <option *ngFor="let event of events" [value]="event" data-tests-id="option">{{event | slice:0:event.length-6}}</option> + </select> + <span *ngIf="readOnly" style="height: 35px; padding: 0.3rem; width:200px; border: 1px solid #D2D2D2; display: flex; align-items: center; background: #F2F2F2">{{selectedEvent | slice:0:selectedEvent.length-6}}</span> + </div> + + <div class="notifyId" style="display: flex; flex-direction:column; margin-right:25px;"> + <div class="pretty p-svg space-down"> + <input type="checkbox" name="notifyIdCheckbox" data-tests-id="notifyIdCheckbox" [checked]="notifyIdCheckbox" (change)="changeNotifyId()" + /> + <div class="state"> + <!-- svg path --> + <svg class="svg svg-icon" viewBox="0 0 20 20"> + <path d="M7.629,14.566c0.125,0.125,0.291,0.188,0.456,0.188c0.164,0,0.329-0.062,0.456-0.188l8.219-8.221c0.252-0.252,0.252-0.659,0-0.911c-0.252-0.252-0.659-0.252-0.911,0l-7.764,7.763L4.152,9.267c-0.252-0.251-0.66-0.251-0.911,0c-0.252,0.252-0.252,0.66,0,0.911L7.629,14.566z" + style="stroke: #009fdb; fill:#009fdb;"></path> + </svg> + <label style="margin-left: 5px;">Notify OID</label> + </div> + </div> + <div *ngIf="notifyIdCheckbox" class="input-wrapper"> + <input type="text" ngModel required name="defaultInput" data-tests-id="defaultInput" [(ngModel)]="store.notifyIdValue" class="input"> + </div> + </div> </div> </div> diff --git a/public/src/app/rule-engine/version-type-select/version-type-select.component.scss b/public/src/app/rule-engine/version-type-select/version-type-select.component.scss index 9f7bad3..1be996e 100644 --- a/public/src/app/rule-engine/version-type-select/version-type-select.component.scss +++ b/public/src/app/rule-engine/version-type-select/version-type-select.component.scss @@ -1,7 +1,6 @@ .selected-event { display: flex; - margin: 10px 0; - // align-items: center; + // margin: 10px 0; // align-items: center; flex-direction: column; margin-bottom: 30px; } @@ -23,6 +22,20 @@ outline: none; } +.space-down { + margin-bottom: 5px; +} + +.input-wrapper { + .input { + height: 35px; + border-radius: 2px; + padding: 5px; + width: 100%; + border: 1px solid #d2d2d2; + } +} + .target-field { width: 370px; display: flex; @@ -42,5 +55,6 @@ min-width: 250px; padding: 5px 0 5px 5px; margin: 0; + border: 1px solid #d2d2d2; } } diff --git a/public/src/app/rule-engine/version-type-select/version-type-select.component.ts b/public/src/app/rule-engine/version-type-select/version-type-select.component.ts index b4170a5..ff229cd 100644 --- a/public/src/app/rule-engine/version-type-select/version-type-select.component.ts +++ b/public/src/app/rule-engine/version-type-select/version-type-select.component.ts @@ -1,6 +1,6 @@ -import { Component, Output, EventEmitter, Input } from '@angular/core'; -import { RuleEngineApiService } from '../api/rule-engine-api.service'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { Store } from '../../store/store'; +import { RuleEngineApiService } from '../api/rule-engine-api.service'; @Component({ selector: 'app-version-type-select', @@ -19,25 +19,60 @@ export class VersionTypeSelectComponent { @Input() metaData; @Output() nodesUpdated = new EventEmitter(); @Output() refrashRuleList = new EventEmitter(); - advancedSetting; + advancedSetting: Array<any>; + notifyIdCheckbox = false; constructor(private _ruleApi: RuleEngineApiService, public store: Store) { this.selectedVersion = null; this.selectedEvent = null; // set ddl with the first option value. - this.mappingTarget = this.store.configurationForm[0].name; - this.advancedSetting = this.store.configurationForm.filter(item => { - if ( - !( - item.hasOwnProperty('constraints') && - !item.assignment.value.includes('get_input') - ) - ) { - return item; + + this._ruleApi.tabIndex.subscribe(index => { + console.log('rule index:', index); + + const tabName = this.store.cdump.nodes[index].name; + console.log('tab name:', tabName); + + if (tabName.toLowerCase().includes('map')) { + this.mappingTarget = this.store.tabsProperties[index][0].name; + this.advancedSetting = this.store.tabsProperties[index].filter(item => { + if ( + !( + item.hasOwnProperty('constraints') && + !item.value.includes('get_input') + ) + ) { + return item; + } + }); + + this._ruleApi + .generateMappingRulesFileName( + this.store.ruleListExistParams.nodeName, + this.store.ruleListExistParams.nodeId, + this.store.ruleListExistParams.vfcmtUuid + ) + .subscribe(response => { + console.log('generateMappingRulesFileName response: ', response); + this.advancedSetting.forEach(element => { + if (response.includes(element.name)) { + element.isExist = true; + } else { + element.isExist = false; + } + }); + }); } }); } + changeNotifyId() { + if (!this.notifyIdCheckbox) { + this.store.notifyIdValue = ''; + } + return (this.notifyIdCheckbox = !this.notifyIdCheckbox); + } + onChangeMapping(configurationKey) { console.log('changing propertiy key:', configurationKey); this._ruleApi.setFieldName(configurationKey); @@ -78,9 +113,7 @@ export class VersionTypeSelectComponent { .subscribe(tree => { console.log('tree: ', tree); this.loader = false; - this.nodesUpdated.emit({ - nodes: tree - }); + this.nodesUpdated.emit({ nodes: tree }); }); } } |