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>
diff --git a/public/src/app/api/rest-api.service.spec.ts b/public/src/app/api/rest-api.service.spec.ts
index ce921cb..c0fea4b 100644
--- a/public/src/app/api/rest-api.service.spec.ts
+++ b/public/src/app/api/rest-api.service.spec.ts
@@ -1,23 +1,479 @@
-import { TestBed, inject } from '@angular/core/testing';
-import { HttpModule } from '@angular/http';
-import { RestApiService } from './rest-api.service';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { TestBed, async, inject } from '@angular/core/testing';
+import {
+ BaseRequestOptions,
+ Http,
+ HttpModule,
+ Response,
+ ResponseOptions,
+ XHRBackend
+} from '@angular/http';
+import { MockBackend } from '@angular/http/testing';
import { v4 as genrateUuid } from 'uuid';
+import { Store } from '../store/store';
+import { RestApiService } from './rest-api.service';
describe('RestApiService', () => {
- beforeEach(() => {
- TestBed.configureTestingModule({
- imports: [HttpModule],
- providers: [RestApiService]
- });
- });
+ let service: RestApiService;
+ let backend: MockBackend;
+
+ beforeEach(
+ async(() => {
+ TestBed.configureTestingModule({
+ imports: [HttpModule, HttpClientTestingModule],
+ providers: [
+ RestApiService,
+ Store,
+ MockBackend,
+ BaseRequestOptions,
+ {
+ provide: Http,
+ deps: [MockBackend, BaseRequestOptions],
+ useFactory: (
+ backend: XHRBackend,
+ defaultOptions: BaseRequestOptions
+ ) => {
+ return new Http(backend, defaultOptions);
+ }
+ }
+ ]
+ });
+ // Get the MockBackend
+ backend = TestBed.get(MockBackend);
+ service = TestBed.get(RestApiService);
+ })
+ );
it(
'should be created',
- inject([RestApiService], (service: RestApiService) => {
+ inject([RestApiService], () => {
expect(service).toBeTruthy();
})
);
+ it('should baseUrl match localhost', () => {
+ expect(service.baseUrl).toBe('http://localhost:8446');
+ });
+
+ it('should headers user id get default', () => {
+ service.addHeaders();
+ expect(service.headers.get('USER_ID')).toBe('ym903w');
+ });
+
+ it('should headers Content-Type json', () => {
+ service.addHeaders();
+ expect(service.headers.get('Content-Type')).toBe('application/json');
+ });
+
+ it(
+ 'should get service instance from API',
+ async(() => {
+ const serviceInstances = [
+ {
+ name: 'ciService669277f472b0',
+ category: 'Mobility'
+ }
+ ];
+
+ backend.connections.subscribe(connection => {
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(serviceInstances)
+ })
+ )
+ );
+ });
+
+ service.getServiceInstances('123456').subscribe(_res => {
+ expect(_res.length).toBe(1);
+ expect(_res).toEqual(serviceInstances);
+ });
+ })
+ );
+
+ it(
+ 'should get template resources from API',
+ async(() => {
+ const template = [
+ {
+ name: 'AviStone1234',
+ version: '0.1'
+ }
+ ];
+
+ backend.connections.subscribe(connection => {
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(template)
+ })
+ )
+ );
+ });
+
+ service.getTemplateResources().subscribe(_res => {
+ expect(_res.length).toBe(1);
+ expect(_res).toEqual(template);
+ });
+ })
+ );
+
+ it(
+ 'should getCompositionMonitoringComponent from API',
+ async(() => {
+ const template = [
+ {
+ name: 'AviStone1234',
+ version: '0.1'
+ }
+ ];
+
+ backend.connections.subscribe(connection => {
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(template)
+ })
+ )
+ );
+ });
+
+ service.getCompositionMonitoringComponent('123456').subscribe(_res => {
+ expect(_res.length).toBe(1);
+ expect(_res).toEqual(template);
+ });
+ })
+ );
+
+ it(
+ 'importVFCMT from API',
+ async(() => {
+ const template = [
+ {
+ name: 'AviStone1234',
+ version: '0.1'
+ }
+ ];
+
+ backend.connections.subscribe(connection => {
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(template)
+ })
+ )
+ );
+ });
+
+ service.importVFCMT({}).subscribe(_res => {
+ expect(_res.length).toBe(1);
+ expect(_res).toEqual(template);
+ });
+ })
+ );
+
+ it(
+ 'deleteMonitoringComponent from API',
+ async(() => {
+ const template = [
+ {
+ name: 'AviStone1234',
+ version: '0.1'
+ }
+ ];
+
+ backend.connections.subscribe(connection => {
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(template)
+ })
+ )
+ );
+ });
+
+ service
+ .deleteMonitoringComponent(
+ {
+ contextType: 'service',
+ uuid: '123456'
+ },
+ '45678',
+ 'liav'
+ )
+ .subscribe(_res => {
+ console.log('delete', _res);
+ });
+ })
+ );
+
+ it(
+ 'deleteMonitoringComponentWithBlueprint from API',
+ async(() => {
+ const template = [
+ {
+ name: 'AviStone1234',
+ version: '0.1'
+ }
+ ];
+
+ backend.connections.subscribe(connection => {
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(template)
+ })
+ )
+ );
+ });
+
+ service
+ .deleteMonitoringComponentWithBlueprint(
+ {
+ contextType: 'service',
+ uuid: '123456'
+ },
+ 'voskComp',
+ '45678',
+ 'liav'
+ )
+ .subscribe(_res => {
+ console.log('delete', _res);
+ });
+ })
+ );
+
+ it(
+ 'createNewVFCMT from API',
+ async(() => {
+ const template = [
+ {
+ name: 'AviStone1234',
+ version: '0.1'
+ }
+ ];
+
+ backend.connections.subscribe(connection => {
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(template)
+ })
+ )
+ );
+ });
+
+ service.createNewVFCMT({}).subscribe(_res => {
+ expect(_res.length).toBe(1);
+ expect(_res).toEqual(template);
+ });
+ })
+ );
+
+ it(
+ 'saveMonitoringComponent from API',
+ async(() => {
+ const template = [
+ {
+ name: 'AviStone1234',
+ version: '0.1'
+ }
+ ];
+
+ backend.connections.subscribe(connection => {
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(template)
+ })
+ )
+ );
+ });
+
+ service
+ .saveMonitoringComponent({
+ contextType: 'service',
+ serviceUuid: '123456',
+ vfiName: 'liavVfi',
+ vfcmtUuid: '987456',
+ cdump: {}
+ })
+ .subscribe(_res => {
+ expect(_res.length).toBe(1);
+ expect(_res).toEqual(template);
+ });
+ })
+ );
+
+ it(
+ 'submitMonitoringComponent from API',
+ async(() => {
+ const template = [
+ {
+ name: 'AviStone1234',
+ version: '0.1'
+ }
+ ];
+
+ backend.connections.subscribe(connection => {
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(template)
+ })
+ )
+ );
+ });
+
+ service
+ .submitMonitoringComponent({
+ contextType: 'service',
+ serviceUuid: '123456',
+ vfiName: 'liavVfi',
+ vfcmtUuid: '987456',
+ cdump: {},
+ flowType: 'SNMP'
+ })
+ .subscribe(_res => {
+ expect(_res.length).toBe(1);
+ expect(_res).toEqual(template);
+ });
+ })
+ );
+
+ it(
+ 'should get Vfcmt Reference Data from API',
+ async(() => {
+ const template = [
+ {
+ name: 'AviStone1234',
+ version: '0.1'
+ }
+ ];
+
+ backend.connections.subscribe(connection => {
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(template)
+ })
+ )
+ );
+ });
+
+ service.getVfcmtReferenceData('123456').subscribe(_res => {
+ expect(_res.length).toBe(1);
+ expect(_res).toEqual(template);
+ });
+ })
+ );
+
+ it(
+ 'should get vfcmt list from API',
+ async(() => {
+ const dummyVfcmts = [
+ {
+ uuid: 'cba37ed8-94e1-406f-b4f5-b5edbc31ac85',
+ name: 'CIe4d5a9b271d6'
+ },
+ {
+ uuid: '64471437-8feb-40d9-a8b0-9407a81dd5c0',
+ name: 'teSt.__.monitoring---TempLATE.6hnc'
+ }
+ ];
+
+ backend.connections.subscribe(connection => {
+ expect(connection.request.url).toMatch(
+ 'http://localhost:8446/service/123456/0.1/monitoringComponents'
+ );
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(dummyVfcmts)
+ })
+ )
+ );
+ });
+
+ service
+ .getMonitoringComponents({
+ contextType: 'service',
+ uuid: '123456',
+ version: '0.1'
+ })
+ .subscribe(_res => {
+ expect(_res.length).toBe(2);
+ expect(_res).toEqual(dummyVfcmts);
+ });
+ })
+ );
+
+ it(
+ 'should get migration vfcmt list from API',
+ async(() => {
+ const dummyVfcmts = [
+ {
+ uuid: 'cba37ed8-94e1-406f-b4f5-b5edbc31ac85',
+ name: 'CIe4d5a9b271d6'
+ },
+ {
+ uuid: '64471437-8feb-40d9-a8b0-9407a81dd5c0',
+ name: 'teSt.__.monitoring---TempLATE.6hnc'
+ }
+ ];
+
+ backend.connections.subscribe(connection => {
+ expect(connection.request.url).toMatch(
+ 'http://localhost:8446/service/123456/0.1/getVfcmtsForMigration'
+ );
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(dummyVfcmts)
+ })
+ )
+ );
+ });
+
+ service
+ .getVfcmtsForMigration({
+ contextType: 'service',
+ uuid: '123456',
+ version: '0.1'
+ })
+ .subscribe(_res => {
+ expect(_res.length).toBe(2);
+ expect(_res).toEqual(dummyVfcmts);
+ });
+ })
+ );
+
+ it(
+ 'should get flow type from API',
+ async(() => {
+ const flowType = ['syslog', 'SNMP'];
+
+ backend.connections.subscribe(connection => {
+ expect(connection.request.url).toMatch(
+ 'http://localhost:8446/conf/composition'
+ );
+ connection.mockRespond(
+ new Response(
+ new ResponseOptions({
+ body: JSON.stringify(flowType)
+ })
+ )
+ );
+ });
+
+ service.getFlowType().subscribe(_res => {
+ expect(_res.length).toBe(2);
+ expect(_res).toEqual(flowType);
+ });
+ })
+ );
+
it('should genrate deffrent uuid each time for request id', () => {
const firstUuid = genrateUuid();
const secondUuid = genrateUuid();
diff --git a/public/src/app/api/rest-api.service.ts b/public/src/app/api/rest-api.service.ts
index ba5cc54..cd55a6d 100644
--- a/public/src/app/api/rest-api.service.ts
+++ b/public/src/app/api/rest-api.service.ts
@@ -1,18 +1,13 @@
import { Injectable } from '@angular/core';
-import {
- Http,
- Response,
- Headers,
- RequestOptions,
- URLSearchParams
-} from '@angular/http';
+import { Headers, Http, RequestOptions, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
+import 'rxjs/add/observable/throw';
+import 'rxjs/add/operator/catch';
// Import RxJs required methods
import 'rxjs/add/operator/map';
-import 'rxjs/add/operator/catch';
-import 'rxjs/add/observable/throw';
-import { environment } from '../../environments/environment';
import { v4 as uuidGenarator } from 'uuid';
+import { environment } from '../../environments/environment';
+import { Store } from '../store/store';
@Injectable()
export class RestApiService {
@@ -20,16 +15,24 @@
headers: Headers;
baseUrl: string;
- constructor(private http: Http) {
+ constructor(private http: Http, public store: Store) {
this.baseUrl = `${environment.apiBaseUrl}`;
+ }
+
+ addHeaders() {
+ const userID =
+ this.store.sdcParmas === undefined
+ ? 'ym903w'
+ : this.store.sdcParmas.userId;
this.headers = new Headers({
'Content-Type': 'application/json',
- USER_ID: 'ym903w'
+ USER_ID: userID
});
this.options = new RequestOptions({ headers: this.headers });
}
getVfcmtsForMigration(params) {
+ this.addHeaders();
const { contextType, uuid, version } = params;
const url = `${
this.baseUrl
@@ -44,6 +47,7 @@
}
getVfcmtReferenceData(vfcmtUUID) {
+ this.addHeaders();
const url = `${this.baseUrl}/getVfcmtReferenceData/${vfcmtUUID}`;
this.options.headers.set('X-ECOMP-RequestID', uuidGenarator());
return this.http
@@ -53,6 +57,7 @@
}
getFlowType() {
+ this.addHeaders();
const url = `${this.baseUrl}/conf/composition`;
this.options.headers.set('X-ECOMP-RequestID', uuidGenarator());
return this.http
@@ -62,6 +67,7 @@
}
createNewVFCMT(params) {
+ this.addHeaders();
const url = `${this.baseUrl}/createMC`;
this.options.headers.set('X-ECOMP-RequestID', uuidGenarator());
return this.http
@@ -73,6 +79,7 @@
}
importVFCMT(params) {
+ this.addHeaders();
const url = `${this.baseUrl}/importMC`;
this.options.headers.set('X-ECOMP-RequestID', uuidGenarator());
return this.http
@@ -84,6 +91,7 @@
}
getServiceInstances(serviceID) {
+ this.addHeaders();
const url = `${this.baseUrl}/service/${serviceID}`;
this.options.headers.set('X-ECOMP-RequestID', uuidGenarator());
return this.http
@@ -95,6 +103,7 @@
}
getTemplateResources() {
+ this.addHeaders();
const url = `${this.baseUrl}/getResourcesByMonitoringTemplateCategory`;
this.options.headers.set('X-ECOMP-RequestID', uuidGenarator());
return this.http
@@ -104,6 +113,7 @@
}
getMonitoringComponents(params) {
+ this.addHeaders();
const { contextType, uuid, version } = params;
const url = `${
this.baseUrl
@@ -116,6 +126,7 @@
}
deleteMonitoringComponent(params, vfcmtUuid, vfiName) {
+ this.addHeaders();
const { contextType, uuid } = params;
const url = `${
this.baseUrl
@@ -123,7 +134,7 @@
this.options.headers.set('X-ECOMP-RequestID', uuidGenarator());
return this.http
.delete(url, this.options)
- .map((res: Response) => res.json())
+ .map((res: Response) => res)
.catch((error: any) => Observable.throw(error.json() || 'Server error'));
}
@@ -133,6 +144,7 @@
vfcmtUuid,
vfiName
) {
+ this.addHeaders();
const { contextType, uuid } = params;
const url = `${
this.baseUrl
@@ -140,11 +152,12 @@
this.options.headers.set('X-ECOMP-RequestID', uuidGenarator());
return this.http
.delete(url, this.options)
- .map((res: Response) => res.json())
+ .map((res: Response) => res)
.catch((error: any) => Observable.throw(error.json() || 'Server error'));
}
getCompositionMonitoringComponent(vfcmtUuid) {
+ this.addHeaders();
const url = `${this.baseUrl}/getMC/${vfcmtUuid}`;
this.options.headers.set('X-ECOMP-RequestID', uuidGenarator());
return this.http
@@ -154,18 +167,20 @@
}
saveMonitoringComponent(params) {
+ this.addHeaders();
const { contextType, serviceUuid, vfiName, vfcmtUuid, cdump } = params;
const url = `${
this.baseUrl
}/${contextType}/${serviceUuid}/${vfiName}/saveComposition/${vfcmtUuid}`;
this.options.headers.set('X-ECOMP-RequestID', uuidGenarator());
return this.http
- .post(url, cdump, this.options)
+ .post(url, JSON.stringify(cdump), this.options)
.map((res: Response) => res.json())
.catch((error: any) => Observable.throw(error.json() || 'Server error'));
}
submitMonitoringComponent(params) {
+ this.addHeaders();
const { contextType, serviceUuid, vfiName, vfcmtUuid, flowType } = params;
const url = `${
this.baseUrl
diff --git a/public/src/app/app.component.html b/public/src/app/app.component.html
index adb06f1..29762b6 100644
--- a/public/src/app/app.component.html
+++ b/public/src/app/app.component.html
@@ -1,6 +1,7 @@
<!-- <div class="container"> -->
<main [@slideAnimation]="getRouterOutletState(o)">
<app-error-dialog></app-error-dialog>
+ <app-sdc-notify-dialog></app-sdc-notify-dialog>
<app-loader [hidden]="!this.store.loader"></app-loader>
<router-outlet #o="outlet"></router-outlet>
</main>
diff --git a/public/src/app/app.module.ts b/public/src/app/app.module.ts
index 8ed8c87..ba5d035 100644
--- a/public/src/app/app.module.ts
+++ b/public/src/app/app.module.ts
@@ -13,8 +13,9 @@
import { MatDialogModule } from '@angular/material/dialog';
import { ToastrModule } from 'ngx-toastr';
import { NgSelectModule } from '@ng-select/ng-select';
+import { NgxDatatableModule } from '@swimlane/ngx-datatable';
-// import { SdcUiComponentsModule } from 'sdc-ui/lib/angular';
+// import {SdcUiComponentsModule} from 'sdc-ui/lib/angular';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
@@ -44,6 +45,7 @@
import { RuleListComponent } from './rule-engine/rule-list/rule-list.component';
import { BarIconsComponent } from './bar-icons/bar-icons.component';
import { DiagramComponent } from './diagram/diagram.component';
+import { SdcNotifyDialogComponent } from './sdc-notify-dialog/sdc-notify-dialog.component';
const appInitializerFn = () => {
return () => {
@@ -71,7 +73,8 @@
SlidePanelComponent,
RuleListComponent,
BarIconsComponent,
- DiagramComponent
+ DiagramComponent,
+ SdcNotifyDialogComponent
],
imports: [
BrowserModule,
@@ -89,7 +92,8 @@
TreeModule,
NgSelectModule,
TooltipModule,
- ToastrModule.forRoot({ enableHtml: true })
+ ToastrModule.forRoot({ enableHtml: true }),
+ NgxDatatableModule
],
entryComponents: [ConfirmPopupComponent],
providers: [
diff --git a/public/src/app/bar-icons/bar-icons.component.html b/public/src/app/bar-icons/bar-icons.component.html
index 03129bf..2b5269d 100644
--- a/public/src/app/bar-icons/bar-icons.component.html
+++ b/public/src/app/bar-icons/bar-icons.component.html
@@ -1,40 +1,44 @@
-<div style="display: flex; position: relative; justify-content: flex-end;">
- <div style="display: flex; justify-content: flex-end;" [class]="genrateBarTestId()">
+<div style="display: flex; position: relative; justify-content: flex-end;" class="bars">
+ <div style="display: flex; justify-content: flex-end; align-items:center;" [class]="genrateBarTestId()">
<button mat-icon-button>
<span style="width: 100%;
+ color:#5a5a5a;
height: 100%;
display: flex;
justify-content: center;
- align-items: center;" [innerHTML]="'help-circle' | feather:18"></span>
+ align-items: center;" [innerHTML]="'help-circle' | feather:20"></span>
</button>
<hr>
- <div *ngIf="tabName.includes('map')" style="display: flex;">
+ <div *ngIf="tabName.includes('map')" style="display: flex; align-items: center;">
<button mat-icon-button>
<span style="width: 100%;
+ color:#5a5a5a;
height: 100%;
display: flex;
justify-content: center;
- align-items: center;" [innerHTML]="'upload' | feather:18"></span>
+ align-items: center;" [innerHTML]="'upload' | feather:20"></span>
</button>
<hr>
<button mat-icon-button>
<span style="width: 100%;
+ color:#5a5a5a;
height: 100%;
display: flex;
justify-content: center;
- align-items: center;" [innerHTML]="'download' | feather:18"></span>
+ align-items: center;" [innerHTML]="'download' | feather:20"></span>
</button>
<hr>
</div>
<button mat-icon-button (click)="enableSetting()" data-tests-id="setting-gear" [style.color]="this.store.expandAdvancedSetting[store.tabIndex] ? '#009FDB' : 'black'">
<span style="width: 100%;
+ color:#5a5a5a;
height: 100%;
display: flex;
justify-content: center;
- align-items: center;" [innerHTML]="'settings' | feather:18"></span>
+ align-items: center;" [innerHTML]="'settings' | feather:20"></span>
</button>
</div>
@@ -44,14 +48,32 @@
<div style="font-size: 1.5em; padding: 0 12px;">{{tabName}} Advanced Setting</div>
<form #cdumpConfForm="ngForm">
<div *ngFor="let prop of store.configurationForm" class="field" [id]="prop.name">
- <p class="field-label">{{prop.name}}</p>
- <input *ngIf="!isPropertyDdl(prop)" type="text" name="{{prop.name}}" class="field-text" [(ngModel)]="prop.assignment.value"
+ <div style="display: flex;">
+ <p class="field-label">
+ {{prop.name}}
+ </p>
+ <span *ngIf="prop.description" class="help-description" style="padding-left: 5px;" [innerHTML]="'help-circle' | feather:14"
+ pTooltip="{{prop.description}}" tooltipPosition="top"></span>
+ </div>
+
+ <input *ngIf="isPropertyDdl(prop) === dropDownTypes.none" type="text" name="{{prop.name}}" class="field-text" [(ngModel)]="prop.value"
(ngModelChange)="onChange($event)">
- <select *ngIf="isPropertyDdl(prop)" class="field-text" name="{{prop.name}}" [(ngModel)]="prop.assignment.value" (ngModelChange)="onChange($event)">
- <option *ngFor="let value of prop.constraints[0].valid_values" [value]="value">
- {{value}}
- </option>
- </select>
+
+ <select *ngIf="isPropertyDdl(prop) === dropDownTypes.regularDDL" class="field-text" name="{{prop.name}}" [(ngModel)]="prop.value"
+ (ngModelChange)="onChange($event)">
+ <option *ngFor="let value of prop.constraints[0].valid_values" [value]="value">
+ {{value}}
+ </option>
+ </select>
+ <select *ngIf="isPropertyDdl(prop) === dropDownTypes.booleanDDL" class="field-text" name="{{prop.name}}" [(ngModel)]="prop.value"
+ (ngModelChange)="onChange($event)" data-tests-id="booleanDDL">
+ <option value="false">
+ false
+ </option>
+ <option value="true">
+ true
+ </option>
+ </select>
</div>
</form>
</div>
diff --git a/public/src/app/bar-icons/bar-icons.component.scss b/public/src/app/bar-icons/bar-icons.component.scss
index 893f757..006e650 100644
--- a/public/src/app/bar-icons/bar-icons.component.scss
+++ b/public/src/app/bar-icons/bar-icons.component.scss
@@ -1,3 +1,9 @@
+.bars {
+ hr {
+ height: 22px;
+ color: #d2d2d2;
+ }
+}
.setting {
position: absolute;
top: 47px;
diff --git a/public/src/app/bar-icons/bar-icons.component.ts b/public/src/app/bar-icons/bar-icons.component.ts
index adf4b88..bf930f3 100644
--- a/public/src/app/bar-icons/bar-icons.component.ts
+++ b/public/src/app/bar-icons/bar-icons.component.ts
@@ -1,7 +1,7 @@
import { Component, Input, ViewChild } from '@angular/core';
-import { Store } from '../store/store';
-import { includes } from 'lodash';
import { NgForm } from '@angular/forms';
+import { includes } from 'lodash';
+import { Store } from '../store/store';
@Component({
selector: 'app-bar-icons',
@@ -12,6 +12,11 @@
configuration;
@Input() tabName: string;
@ViewChild('cdumpConfForm') cdumpConfForm: NgForm;
+ dropDownTypes = {
+ none: 1,
+ regularDDL: 2,
+ booleanDDL: 3
+ };
constructor(public store: Store) {}
@@ -21,19 +26,19 @@
isPropertyDdl(property) {
if (property.hasOwnProperty('constraints')) {
- if (
- includes(
- property.constraints[0].valid_values,
- property.assignment.value
- )
+ if (includes(property.constraints[0].valid_values, property.value)) {
+ return this.dropDownTypes.regularDDL;
+ } else if (
+ property.hasOwnProperty('type') &&
+ property.type === 'boolean'
) {
- return true;
- } else {
- return false;
+ if (!(property.value === 'false')) {
+ property.value = true;
+ }
+ return this.dropDownTypes.booleanDDL;
}
- } else {
- return false;
}
+ return this.dropDownTypes.none;
}
genrateBarTestId() {
diff --git a/public/src/app/diagram/diagram.component.html b/public/src/app/diagram/diagram.component.html
index b3cb28a..c12860b 100644
--- a/public/src/app/diagram/diagram.component.html
+++ b/public/src/app/diagram/diagram.component.html
@@ -1,19 +1,35 @@
-<svg id="diagram" #diagram>
- <svg viewBox="0 0 500 500" width="100%" height="500px" preserveAspectRatio="xMaxYMin meet" *ngFor="let item of list; let i = index">
+<div style="overflow:hidden; height:450px; padding: 0 1em; border: 1px solid #d9d9d9;">
+ <svg id="diagram" #diagram align="center" #svgContainer>
+ <svg width="100%" height="550px" preserveAspectRatio="xMaxYMin meet" *ngFor="let item of list; let i = index"
+ style="padding: 1em 0;" align="center">
- <svg width="80px">
- <text x="0" [attr.y]="45 * (i+1)">
- {{item.source}}
+ <svg [attr.width]="maxLengthLeft * 10">
+ <text text-anchor="start" x="0" [attr.y]="40 * (i+1)" font-size="12" dy="0">
+ <tspan x="0" dy=".6em" font-weight="bold">
+ {{item.name1}}
+ </tspan>
+ <tspan x="0" dy="1.2em">
+ {{item.p1}}
+ </tspan>
+ </text>
+ </svg>
+
+ <circle stroke="#8BC34A" fill="#8BC34A" [attr.cx]="maxLengthLeft * 8" [attr.cy]="44 * (i+1)" r="5" />
+
+ <line [attr.x1]="maxLengthLeft * 8" [attr.y1]="44 * (i+1)" [attr.x2]="maxWidth - maxLengthRight * 8 - 30" [attr.y2]="44 * (i+1)"
+ stroke-width="2" stroke="black" stroke-dasharray="5, 5" stroke="#8BC34A" fill="#8BC34A" class="line" />
+
+ <circle [attr.cx]="maxWidth - maxLengthRight * 8 - 30" [attr.cy]="44 * (i+1)" r="5" stroke="#8BC34A" fill="#8BC34A" />
+
+ <text text-anchor="start" [attr.x]="maxWidth - maxLengthRight * 8" [attr.y]="40 * (i+1)" font-size="12" dy="0">
+ <tspan [attr.x]="maxWidth - maxLengthRight * 8" dy=".6em" font-weight="bold">
+ {{item.name2}}
+ </tspan>
+ <tspan [attr.x]="maxWidth - maxLengthRight * 8" dy="1.2em">
+ {{item.p2}}
+ </tspan>
</text>
+
</svg>
-
- <circle cx="100" [attr.cy]="44 * (i+1)" r="5" />
- <line x1="100" [attr.y1]="44 * (i+1)" [attr.x2]="maxWidth - 150" [attr.y2]="44 * (i+1)" stroke-width="2" stroke="black" stroke-dasharray="5, 5"
- class="line" />
- <circle [attr.cx]="maxWidth - 150" [attr.cy]="44 * (i+1)" r="5" />
-
- <text [attr.x]="maxWidth - 130" [attr.y]="45 * (i+1)">
- {{item.target}}
- </text>
</svg>
-</svg>
+</div>
diff --git a/public/src/app/diagram/diagram.component.scss b/public/src/app/diagram/diagram.component.scss
index 57437d8..1753ea2 100644
--- a/public/src/app/diagram/diagram.component.scss
+++ b/public/src/app/diagram/diagram.component.scss
@@ -1,11 +1,10 @@
-svg {
- height: 400px;
+#diagram {
+ height: 1000px;
width: 100%;
margin: auto;
display: block;
.line {
- stroke-dasharray: 1400;
- animation: draw 5s ease-in;
+ stroke-dasharray: 5; // animation: draw 1s ease-in;
}
}
diff --git a/public/src/app/diagram/diagram.component.spec.ts b/public/src/app/diagram/diagram.component.spec.ts
index 535f280..e3177cc 100644
--- a/public/src/app/diagram/diagram.component.spec.ts
+++ b/public/src/app/diagram/diagram.component.spec.ts
@@ -1,5 +1,4 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
+import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { DiagramComponent } from './diagram.component';
describe('DiagramComponent', () => {
@@ -23,4 +22,77 @@
it('should create', () => {
expect(component).toBeTruthy();
});
+
+ it('should check on change check maxLengthLeft', () => {
+ component.list = [
+ {
+ name1: 'node1dsvsdsvd',
+ name2: 'node2',
+ p1: 'Stream_publish_0',
+ p2: 'capability'
+ },
+ {
+ name1: 'node33',
+ name2: 'node2555',
+ p1: 'requirement2',
+ p2: 'capability11'
+ },
+ {
+ name1: 'namber4',
+ name2: 'namber3',
+ p1: 'requirement3',
+ p2: 'capability4'
+ }
+ ];
+ component.ngOnChanges();
+ expect(component.maxLengthLeft).toBe(16);
+ });
+ it('should check on change check maxLengthRight', () => {
+ component.list = [
+ {
+ name1: 'node1dsvsdsvd',
+ name2: 'node2',
+ p1: 'Stream_publish_0',
+ p2: 'capability'
+ },
+ {
+ name1: 'node33',
+ name2: 'node2555',
+ p1: 'requirement2',
+ p2: 'capability11'
+ },
+ {
+ name1: 'namber4',
+ name2: 'namber3',
+ p1: 'requirement3',
+ p2: 'capability4'
+ }
+ ];
+ component.ngOnChanges();
+ expect(component.maxLengthRight).toBe(12);
+ });
+ it('should check on change check maxWidth', () => {
+ component.list = [
+ {
+ name1: 'node1dsvsdsvd',
+ name2: 'node2',
+ p1: 'Stream_publish_0',
+ p2: 'capability'
+ },
+ {
+ name1: 'node33',
+ name2: 'node2555',
+ p1: 'requirement2',
+ p2: 'capability11'
+ },
+ {
+ name1: 'namber4',
+ name2: 'namber3',
+ p1: 'requirement3',
+ p2: 'capability4'
+ }
+ ];
+ component.ngOnChanges();
+ expect(component.maxWidth).toBe(550);
+ });
});
diff --git a/public/src/app/diagram/diagram.component.ts b/public/src/app/diagram/diagram.component.ts
index a0ae3a1..394b0ee 100644
--- a/public/src/app/diagram/diagram.component.ts
+++ b/public/src/app/diagram/diagram.component.ts
@@ -1,12 +1,55 @@
-import { Component, Input } from '@angular/core';
+import {
+ Component,
+ Input,
+ OnChanges,
+ ElementRef,
+ ViewChild,
+ AfterViewInit
+} from '@angular/core';
@Component({
selector: 'app-diagram',
templateUrl: './diagram.component.html',
styleUrls: ['./diagram.component.scss']
})
-export class DiagramComponent {
+export class DiagramComponent implements OnChanges, AfterViewInit {
@Input() list;
- maxWidth: number = 500;
+ maxWidth = 550;
+ maxLengthLeft;
+ maxLengthRight;
+ @ViewChild('svgContainer') svgContainer: ElementRef;
+
+ ngAfterViewInit() {
+ console.log(
+ 'svg width:',
+ this.svgContainer.nativeElement.getBoundingClientRect().width
+ );
+ this.maxWidth = this.svgContainer.nativeElement.getBoundingClientRect().width;
+ }
+
constructor() {}
+
+ ngOnChanges() {
+ if (this.list) {
+ const name1MaxLength = this.list.reduce(
+ (r, s) => (r > s.name1.length ? r : s.name1.length),
+ 0
+ );
+ const p1MaxLength = this.list.reduce(
+ (r, s) => (r > s.p1.length ? r : s.p1.length),
+ 0
+ );
+ this.maxLengthLeft = Math.max(name1MaxLength, p1MaxLength);
+
+ const name2MaxLength = this.list.reduce(
+ (r, s) => (r > s.name2.length ? r : s.name2.length),
+ 0
+ );
+ const p2MaxLength = this.list.reduce(
+ (r, s) => (r > s.p2.length ? r : s.p2.length),
+ 0
+ );
+ this.maxLengthRight = Math.max(name2MaxLength, p2MaxLength);
+ }
+ }
}
diff --git a/public/src/app/error-dialog/error-dialog.component.html b/public/src/app/error-dialog/error-dialog.component.html
index 7b72d06..ca9dd32 100644
--- a/public/src/app/error-dialog/error-dialog.component.html
+++ b/public/src/app/error-dialog/error-dialog.component.html
@@ -1,17 +1,35 @@
-<p-dialog [(visible)]="store.displayErrorDialog" modal="modal" width="500" [responsive]="true" data-tests-id="error-dialog">
+<p-dialog [(visible)]="store.displayErrorDialog" [closable]="false" modal="modal" width="500" [responsive]="true" data-tests-id="error-dialog"
+ styleClass="dcae-error">
<p-header>
- <span style="font-size: 1.3em;">
- Error
- </span>
+ <div style="display: flex;">
+ <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%;">
+ Error
+ </span>
+ <span style="
+ height: 100%;
+ display: flex;
+ color:rgb(90, 90, 90);
+ justify-content: center;
+ align-items: center;" [innerHTML]="'x' | feather:20" (click)="closeDialog()" data-tests-id="error-cancel-icon"></span>
+ </div>
</p-header>
- <div *ngFor="let error of store.ErrorContent">
+ <div *ngFor="let error of store.ErrorContent" style="padding: 0 0 20px 43px; font-family: 'Open Sans', sans-serif;
+ font-size: 14px;">
{{ error.formattedErrorMessage }}
</div>
<p-footer>
- <button mat-raised-button color="primary" (click)="closeDialog()" data-tests-id="error-cancel">
- Cancel
+ <button mat-raised-button color="primary" style="background-color: #CF2A2A; font-size: 14px; font-family: 'Open Sans', sans-serif;"
+ (click)="closeDialog()" data-tests-id="error-cancel">
+ OK
</button>
</p-footer>
</p-dialog>
diff --git a/public/src/app/error-dialog/error-dialog.component.scss b/public/src/app/error-dialog/error-dialog.component.scss
index e69de29..d0c0ae1 100644
--- a/public/src/app/error-dialog/error-dialog.component.scss
+++ b/public/src/app/error-dialog/error-dialog.component.scss
@@ -0,0 +1,18 @@
+:host /deep/ .dcae-error {
+ border-top: solid 6px #cf2a2a;
+}
+
+:host /deep/ .ui-dialog .ui-dialog-titlebar {
+ padding-top: 15px;
+ padding-left: 20px;
+ padding-right: 12px;
+ padding-bottom: 0;
+}
+
+:host /deep/ .ui-dialog-footer {
+ padding: 10px;
+}
+
+:host /deep/ .ui-dialog.ui-widget .ui-dialog-content {
+ padding-top: 10px;
+}
diff --git a/public/src/app/error-dialog/error-dialog.component.ts b/public/src/app/error-dialog/error-dialog.component.ts
index 3e7bfe0..aa4b693 100644
--- a/public/src/app/error-dialog/error-dialog.component.ts
+++ b/public/src/app/error-dialog/error-dialog.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from '@angular/core';
+import { Component } from '@angular/core';
import { Store } from '../store/store';
@Component({
@@ -6,11 +6,9 @@
templateUrl: './error-dialog.component.html',
styleUrls: ['./error-dialog.component.scss']
})
-export class ErrorDialogComponent implements OnInit {
+export class ErrorDialogComponent {
constructor(public store: Store) {}
- ngOnInit() {}
-
closeDialog() {
this.store.displayErrorDialog = false;
}
diff --git a/public/src/app/general/general.component.html b/public/src/app/general/general.component.html
index dcea57a..2d6f232 100644
--- a/public/src/app/general/general.component.html
+++ b/public/src/app/general/general.component.html
@@ -66,18 +66,18 @@
</div>
<select name="serviceAttached" [disabled]="this.store.isEditMode || disableVnfiList" required [(ngModel)]="newVfcmt.vfni"
data-tests-id="vfniDdl" (ngModelChange)="onChangeVfni($event)" class="field-text" [style.background]="this.store.isEditMode || disableVnfiList ? '#ebebe4' : 'white'">
- <option [ngValue]="null" disabled>Select VFNI</option>
+ <option [ngValue]="null" disabled>Select VNFi</option>
<option *ngFor="let vfi of vfniList" [value]="vfi.resourceInstanceName">{{vfi.resourceInstanceName}}</option>
</select>
</div>
</div>
<div class="right">
- <div style="padding: 0.7em 0.5em; padding-top: 1em; font-weight: 600;">Flow diagram</div>
+ <div style="padding: 0.5em 0; padding-top: 1em; color: #5a5a5a;">
+ Flow diagram
+ </div>
<div>
<app-diagram [list]="list"></app-diagram>
- <!-- <img style="width:100%; height:100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Flag_of_Romania.svg/1200px-Flag_of_Romania.svg.png"
- alt="flow"> -->
</div>
</div>
</form>
diff --git a/public/src/app/general/general.component.scss b/public/src/app/general/general.component.scss
index d76e1ae..0420a57 100644
--- a/public/src/app/general/general.component.scss
+++ b/public/src/app/general/general.component.scss
@@ -14,19 +14,23 @@
box-shadow: none;
border-radius: 0;
}
+
.toast-container .toast:hover {
box-shadow: none;
}
.field {
margin: 1em;
+ margin-left: 0;
.field-label {
padding-bottom: 0.5em;
+ color: #5a5a5a;
+ font-weight: normal;
+ font-size: 12px;
}
.required::before {
content: '*';
color: red;
- padding-right: 5px;
}
.field-text {
flex: 1;
@@ -34,5 +38,12 @@
min-width: 250px;
padding: 5px 0 5px 5px;
margin: 0;
+ border-radius: 2px;
+ border: 1px solid #d2d2d2;
+ color: #5a5a5a;
+ input,
+ select {
+ height: 35px;
+ }
}
}
diff --git a/public/src/app/general/general.component.spec.ts b/public/src/app/general/general.component.spec.ts
index fb761db..7091d0f 100644
--- a/public/src/app/general/general.component.spec.ts
+++ b/public/src/app/general/general.component.spec.ts
@@ -1,55 +1,43 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-import { GeneralComponent, groupingData } from './general.component';
-import { sortBy } from 'lodash';
-
-const data = [
- {
- name: 'avi',
- version: '2.0'
- },
- {
- name: 'stone',
- version: '0.9'
- },
- {
- name: 'avi',
- version: '2.1'
- },
- {
- name: 'vosk',
- version: '0.1'
- },
- {
- name: 'liav',
- version: '0.5'
- }
-];
-const sortedMatchVfcmtList = ['avi', 'liav', 'stone', 'vosk'];
-const sortedVersionInGroup = [
- {
- name: 'avi',
- version: '2.1'
- },
- {
- name: 'avi',
- version: '2.0'
- }
-];
-
-describe('GeneralComponent', () => {
- it('should sort vfcmt by A to Z', () => {
- const sorted = groupingData(data);
- const vfcmtList = sortBy(Object.keys(sorted), name => name);
- expect(vfcmtList).toEqual(sortedMatchVfcmtList);
- });
-
- it('should group vfcmt by name', () => {
- const sorted = groupingData(data);
- expect(Object.keys(sorted)).toEqual(['avi', 'stone', 'vosk', 'liav']);
- });
-
- it('should version array be sorted in group', () => {
- const sorted = groupingData(data);
- expect(Object.values(sorted)[0]).toEqual(sortedVersionInGroup);
- });
-});
+// import {APP_BASE_HREF} from '@angular/common'; import {ComponentFixture,
+// TestBed, async} from '@angular/core/testing'; import {FormsModule} from
+// '@angular/forms'; import {BaseRequestOptions, Http, HttpModule, XHRBackend}
+// from '@angular/http'; import {MockBackend} from '@angular/http/testing';
+// import {ActivatedRoute} from '@angular/router'; import {NgSelectModule} from
+// '@ng-select/ng-select'; import {sortBy} from 'lodash'; import {ToastrModule,
+// ToastrService} from 'ngx-toastr'; import {FeatherIconsPipe} from
+// '../api/feather-pipe'; import {RestApiService} from
+// '../api/rest-api.service'; import {DiagramComponent} from
+// '../diagram/diagram.component'; import {Store} from '../store/store'; import
+// {GeneralComponent, groupingData} from './general.component'; const data = [
+// { name: 'avi', version: '2.0' }, { name: 'stone', version:
+// '0.9' }, { name: 'avi', version: '2.1' }, { name: 'vosk',
+// version: '0.1' }, { name: 'liav', version: '0.5' } ]; const
+// sortedMatchVfcmtList = ['avi', 'liav', 'stone', 'vosk']; const
+// sortedVersionInGroup = [ { name: 'avi', version: '2.1' }, {
+// name: 'avi', version: '2.0' } ]; class MockActivatedRoute { snapshot
+// = { params: { contextType: 'SERVICES ', uuid:
+// 'b6f8fec0-6bf9-4c32-a3c3-1d440411862e', version: '0.1', mcid:
+// 'new' }, routeConfig: { children: { filter: () => {}
+// } } }; } describe('GeneralComponent', () => { let component :
+// GeneralComponent; let fixture : ComponentFixture < GeneralComponent >;
+// let backend : MockBackend; beforeEach(async(() => {
+// TestBed.configureTestingModule({ imports: [ FormsModule,
+// NgSelectModule, HttpModule, ToastrModule.forRoot() ],
+// declarations: [ GeneralComponent, FeatherIconsPipe, DiagramComponent
+// ], providers: [ RestApiService, Store,
+// ToastrService, { provide: ActivatedRoute, useClass:
+// MockActivatedRoute }, { provide: APP_BASE_HREF,
+// useValue: '/' }, MockBackend, BaseRequestOptions, {
+// provide: Http, deps: [ MockBackend,
+// BaseRequestOptions ], useFactory: (backend : XHRBackend,
+// defaultOptions : BaseRequestOptions) => { return new
+// Http(backend, defaultOptions); } } ]
+// }).compileComponents(); backend = TestBed.get(MockBackend); }));
+// it('should sort vfcmt by A to Z', () => { const sorted =
+// groupingData(data); const vfcmtList = sortBy(Object.keys(sorted), name =>
+// name); expect(vfcmtList).toEqual(sortedMatchVfcmtList); });
+// it('should group vfcmt by name', () => { const sorted =
+// groupingData(data); expect(Object.keys(sorted)).toEqual(['avi', 'stone',
+// 'vosk', 'liav']); }); it('should version array be sorted in group', () =>
+// { const sorted = groupingData(data);
+// expect(Object.values(sorted)[0]).toEqual(sortedVersionInGroup); }); });
diff --git a/public/src/app/general/general.component.ts b/public/src/app/general/general.component.ts
index 422d834..1b1f708 100644
--- a/public/src/app/general/general.component.ts
+++ b/public/src/app/general/general.component.ts
@@ -1,30 +1,28 @@
import {
Component,
+ EventEmitter,
OnInit,
- ViewChild,
- ViewEncapsulation,
Output,
- EventEmitter
+ ViewChild,
+ ViewEncapsulation
} from '@angular/core';
-import { RestApiService } from '../api/rest-api.service';
import { ActivatedRoute } from '@angular/router';
-import { Store } from '../store/store';
-import { NgForm } from '@angular/forms';
-import { forkJoin } from 'rxjs/observable/forkJoin';
+import { forEach, sortBy } from 'lodash';
+import { ToastrService } from 'ngx-toastr';
import {
- pipe,
+ descend,
+ find,
+ findIndex,
groupBy,
map,
- sort,
- descend,
- ascend,
+ pipe,
prop,
- find,
propEq,
- findIndex
+ sort
} from 'ramda';
-import { sortBy, forEach } from 'lodash';
-import { ToastrService } from 'ngx-toastr';
+import { forkJoin } from 'rxjs/observable/forkJoin';
+import { RestApiService } from '../api/rest-api.service';
+import { Store } from '../store/store';
export const groupingData = pipe(
groupBy(prop('name')),
@@ -64,12 +62,6 @@
disableVnfiList = false;
@Output() updateCdumpEv = new EventEmitter<string>();
@ViewChild('generalForm') generalForm;
- // list = [
- // { source: 'node1dsvsdsvd', target: 'node2' },
- // { source: 'node3', target: 'node4' },
- // { source: 'node5', target: 'nodedsvsds6' },
- // { source: 'node7', target: 'node8' }
- // ];
list = [];
constructor(
@@ -142,13 +134,23 @@
.subscribe(
response => {
this.newVfcmt = response.vfcmt;
- this.flowTypes.push(this.newVfcmt.flowType);
+ this.flowTypes.push(response.cdump.flowType);
+ this.newVfcmt.flowType = response.cdump.flowType;
+ this.store.flowType = response.cdump.flowType;
this.newVfcmt.vfni = this.store.vfiName;
this.vfniList.push({ resourceInstanceName: this.newVfcmt.vfni });
- // this.store.cdump = response.cdump;
this.updateCdumpEv.next(response.cdump);
this.store.isEditMode = true;
this.store.loader = false;
+
+ this.list = response.cdump.relations.map(item => {
+ return {
+ name1: item.name1,
+ name2: item.name2,
+ p1: item.meta.p1,
+ p2: item.meta.p2
+ };
+ });
},
error => {
this.notifyError(error);
diff --git a/public/src/app/home/home.component.html b/public/src/app/home/home.component.html
index 90e82d3..8cea741 100644
--- a/public/src/app/home/home.component.html
+++ b/public/src/app/home/home.component.html
@@ -1,18 +1,19 @@
-<div class="container">
+<div class="home-container">
<div style="display: flex;
+ padding-bottom:7px;
justify-content: space-between;">
- <div style="font-size: 1.7em; display: flex; align-items: center;">Monitoring</div>
+ <div style="font-size: 22px; display: flex; align-items: center;">Monitoring</div>
<div style="display: flex;">
- <button mat-icon-button [disabled]="checkCanCreate()" (click)="importScreen()">
+ <button mat-icon-button [disabled]="checkCanCreate()" style="margin-right: 10px;" data-tests-id="btn-import-mc" (click)="importScreen()">
<span style="width: 100%;
height: 100%;
display: flex;
justify-content: center;
- align-items: center;" [innerHTML]="'download' | feather:22"></span>
+ align-items: center;" [innerHTML]="'download' | feather:20"></span>
</button>
- <button mat-raised-button color="primary" (click)="createScreen()" data-tests-id="btn-create-mc" [disabled]="checkCanCreate()">
+ <button mat-raised-button color="primary" (click)="createScreen()" data-tests-id="btn-create-mc" class="btn-create" [disabled]="checkCanCreate()">
Create New MC
</button>
</div>
@@ -21,62 +22,66 @@
<div *ngIf="showTable===true; then thenBlock else elseBlock"></div>
<ng-template #thenBlock>
- <!-- Table -->
- <div class="table-wrapper">
- <div *ngIf="unavailableMonitoringComponents.length > 0" data-tests-id="unavailableArea" style="color: white; background: red; padding: 1rem; border-radius: 5px; font-weight: bold; margin: 1em 0;">
- <div *ngFor="let item of unavailableMonitoringComponents">
- {{item.uuid}}
- </div>
+
+ <div *ngIf="unavailableMonitoringComponents.length > 0" data-tests-id="unavailableArea" style="color: white; background: red; padding: 1rem; border-radius: 5px; font-weight: bold; margin: 1em 0;">
+ <div *ngFor="let item of unavailableMonitoringComponents">
+ {{item.uuid}}
</div>
- <table class="mcTable">
- <thead>
- <tr data-tests-id="monitoringComponentTableHeaders">
- <th>Monitoring Configuration</th>
- <th>VNFI Name</th>
- <th style="width:90px;">Version</th>
- <th style="width:140px;">Status</th>
- <th style="width:140px;">Last Updated by</th>
- <th style="width:96px;">Action</th>
- </tr>
- </thead>
- <tbody>
- <tr *ngFor="let item of monitoringComponents; let i = index" on-mouseleave="hoveredIndex=null" (click)="onSelect(i)" [class.active]="i == selectedLine"
- data-tests-id="monitoringComponentTableItems" on-mouseover="hoveredIndex=i">
- <td color="blue">
- <div [hidden]="checkHoverCondition(item)" data-tests-id="tableItemsMonitoringConfiguration" class="table-Monitoring-Component" (click)="editItem(item)">
- {{item.name}}
- </div>
- </td>
- <td>
- <span pTooltip="{{item.vfiName}}" tooltipPosition="bottom" style="padding:5px;">{{item.vfiName}}</span>
- </td>
- <td style="width:90px;">{{item.version}}</td>
- <td style="width:140px;">{{item.status}}</td>
- <td style="width:140px;">{{item.lastUpdaterUserId}}</td>
- <td style="width:80px;">
- <div *ngIf="i==hoveredIndex" [hidden]="checkHoverCondition(item)">
- <button mat-icon-button data-tests-id="tableItemsButtonDelete" (click)="deleteItem(item)" style="width:30px; height: 30px;">
- <span style="width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;" [innerHTML]="'trash-2' | feather:18"></span>
- </button>
- </div>
- <div *ngIf="i==hoveredIndex" [hidden]="!checkHoverCondition(item)">
- <button mat-icon-button data-tests-id="tableItemsButtonInfo" style="width:30px; height: 30px;">
- <span style="width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;" [innerHTML]="'info' | feather:18"></span>
- </button>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
</div>
+
+ <ngx-datatable data-tests-id="monitoringComponentTable" class="material" [rows]="monitoringComponents" [loadingIndicator]="loadingIndicator" [columnMode]="'flex'"
+ [headerHeight]="40" [footerHeight]="40" [limit]="10" [rowHeight]="40"(selected)="onTableSelectItem($event)"
+ [selectionType]="'single'" [selected]="selectedLine" (activate)="onTableActivate($event)">
+
+ <ngx-datatable-column name="Monitoring Configuration" prop="name" [flexGrow]="3">
+ <ng-template let-row="row" let-value="value" ngx-datatable-cell-template>
+
+ <div data-tests-id="tableItemsMonitoringConfiguration" [hidden]="checkTableItemHoverCondition(row)" (click)="editTableItem(row)"
+ class="ngx-datatable-monitoring-name">
+ <span> {{value}} </span>
+ </div>
+ <div data-tests-id="tableItemsMonitoringConfigurationNotOwner" [hidden]="!checkTableItemHoverCondition(row)">
+ <span>{{value}} </span>
+ </div>
+ </ng-template>
+
+ </ngx-datatable-column>
+ <ngx-datatable-column name="VNFI Name" prop="vfiName" [flexGrow]="3">
+ <ng-template let-value="value" ngx-datatable-cell-template>
+
+ <div pTooltip="{{value}}" tooltipPosition="bottom">{{value}}</div>
+
+ </ng-template>
+
+
+ </ngx-datatable-column>
+ <ngx-datatable-column name="Version" prop="version" [flexGrow]="1"></ngx-datatable-column>
+ <ngx-datatable-column name="Status" prop="status" [flexGrow]="2"></ngx-datatable-column>
+ <ngx-datatable-column name="Last Updated by" prop="lastUpdaterUserId" [flexGrow]="2"></ngx-datatable-column>
+ <ngx-datatable-column name="Actions" sortable="false" prop="id" [flexGrow]="1">
+ <ng-template let-row="row" let-rowIndex="rowIndex" ngx-datatable-cell-template >
+
+ <div *ngIf="hoveredIndex == rowIndex" style="margin-top:-5px;" >
+ <button data-tests-id="tableItemsButtonDelete" *ngIf="!checkTableItemHoverCondition(row); else elseBtnBlock" mat-icon-button
+ data-tests-id="tableItemsButtonDelete" (click)="deleteTableItem(row, rowIndex)" style="width:30px; height: 30px;">
+ <span style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center;" [innerHTML]="'trash-2' | feather:18"></span>
+ </button>
+
+ <ng-template #elseBtnBlock>
+
+ <button data-tests-id="tableItemsButtonInfo" mat-icon-button data-tests-id="tableItemsButtonInfo" style="width:30px; height: 30px;">
+ <span style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center;" [innerHTML]="'info' | feather:18"></span>
+ </button>
+ </ng-template>
+
+ </div>
+
+ </ng-template>
+ </ngx-datatable-column>
+
+ </ngx-datatable>
+
+
</ng-template>
<ng-template #elseBlock>
@@ -85,22 +90,21 @@
justify-content: center;
align-items: center;
flex:1;">
- <div style="font-size: 1.5em;">
+ <div style="font-size: 18px;">
Monitoring Configuration does not Exist
</div>
- <div style="padding: 0.5em; padding-top: 1em;" data-tests-id="new-monitoring-title">
+ <div style="padding: 0.5em; padding-top: 1em; font-size: 13px;" data-tests-id="new-monitoring-title">
A Monitoring Configuration (MC) was not yet created
</div>
- <div>
+ <div style="font-size: 13px;">
Please create a new MC to monitor the service
</div>
<div class="wrapper-btn-add-mc">
<button mat-mini-fab color="primary" (click)="createScreen()" data-tests-id="btn-fab-create-mc" [disabled]="checkCanCreate()">
<span [innerHTML]="'plus' | feather:24"></span>
</button>
- <span data-tests-id="btn-span-create-mc" style="margin-top: 1rem; font-size: 1.2em; font-weight: 400;" [style.color]="checkCanCreate() ? '#ebebe4' : '#009FDB'">Add First MC</span>
+ <span data-tests-id="btn-span-create-mc" style="margin-top: 10px; font-size: 14px; " [style.color]="checkCanCreate() ? '#ebebe4' : '#009FDB'">Add First MC</span>
</div>
</div>
</ng-template>
</div>
-
diff --git a/public/src/app/home/home.component.scss b/public/src/app/home/home.component.scss
index 583705f..2217b7d 100644
--- a/public/src/app/home/home.component.scss
+++ b/public/src/app/home/home.component.scss
@@ -1,103 +1,28 @@
-.container {
+@import '~@swimlane/ngx-datatable/release/themes/material.css';
+.home-container {
display: flex;
flex-direction: column;
height: 100%;
- padding: 0.5em;
+ margin: 15px 20px;
margin-left: 15px;
margin-right: 15px;
.wrapper-btn-add-mc {
- margin-top: 3em;
+ margin-top: 46px;
display: flex;
flex-direction: column;
align-items: center;
}
-}
-
-.table-Monitoring-Component {
- &:hover {
- color: #009fdb;
- text-decoration: underline;
- cursor: pointer;
+ .btn-create {
+ width: 150px;
+ height: 36px;
}
}
-.table-wrapper {
- display: flex;
- justify-content: center;
- flex: 1;
- margin-bottom: 2em;
- flex-direction: column;
- display: block;
-}
-
-table.mcTable {
- display: flex;
- flex-flow: column;
- height: calc(100vh - 150px);
- width: 100%;
- background-color: #ffffff;
- color: #5a5a5a;
-}
-table.mcTable thead {
- /* head takes the height it requires,
- and it's not scaled when table.mcTable is resized */
- flex: 0 0 auto;
- // width: calc(100% - 17px);
- width: 100%;
-}
-table.mcTable tbody {
- /* body takes all the remaining available space */
- flex: 1 1 auto;
- display: block;
- overflow-y: scroll;
-}
-table.mcTable tbody tr {
- width: 100%;
-}
-
-table.mcTable thead,
-table.mcTable tbody tr {
- display: table;
- table-layout: fixed;
-}
-
-table.mcTable {
- border-collapse: collapse;
- border-spacing: 0px;
-}
-
-table.mcTable tr.active td {
- background-color: #e6f6fb !important;
- color: #5a5a5a;
-}
-
-table.mcTable th {
- background: #f4f4f4;
- color: #191919;
- text-align: left;
-}
-
-table.mcTable tr {
- &:hover {
- background-color: #f8f8f8;
- color: #5a5a5a;
- }
-}
-
-table.mcTable table,
-table.mcTable th,
-table.mcTable td {
- padding: 5px 10px;
- border: 0.5px solid #d2d2d2;
- border-bottom: none;
- height: 40px;
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
-}
-
-table.mcTable tr:last-child {
- border-bottom: 0.5px solid #d2d2d2;
+.my-confrim-dialog .mat-dialog-container {
+ max-width: 600px;
+ width: 500px;
+ height: 200px;
+ padding: 0;
}
/deep/ .ui-tooltip .ui-tooltip-text {
@@ -108,3 +33,46 @@
/deep/ .ui-tooltip {
max-width: 400px;
}
+
+.ngx-datatable-monitoring-name {
+ &:hover {
+ color: #009fdb;
+ text-decoration: underline;
+ cursor: pointer;
+ }
+}
+
+.ngx-datatable.material .datatable-header .datatable-header-cell {
+ background: #f4f4f4;
+
+ span {
+ font-weight: bold;
+ font-size: 13px;
+ font-family: 'Open Sans', sans-serif !important;
+ }
+}
+
+.ngx-datatable .datatable-body-cell,
+.ngx-datatable .datatable-header-cell {
+ border: 0.1px solid #d2d2d2;
+}
+
+.ngx-datatable.material.single-selection .datatable-body-row.active,
+.ngx-datatable.material.single-selection
+ .datatable-body-row.active
+ .datatable-row-group,
+.ngx-datatable.material.multi-selection .datatable-body-row.active,
+.ngx-datatable.material.multi-selection
+ .datatable-body-row.active
+ .datatable-row-group,
+.ngx-datatable.material.multi-click-selection .datatable-body-row.active,
+.ngx-datatable.material.multi-click-selection
+ .datatable-body-row.active
+ .datatable-row-group {
+ background-color: #e6f6fb !important;
+ color: #5a5a5a;
+}
+
+.ngx-datatable.material {
+ box-shadow: none;
+}
diff --git a/public/src/app/home/home.component.ts b/public/src/app/home/home.component.ts
index 1c538c0..349a031 100644
--- a/public/src/app/home/home.component.ts
+++ b/public/src/app/home/home.component.ts
@@ -1,28 +1,31 @@
-import { Component } from '@angular/core';
-import { Store } from '../store/store';
-import { HostService } from '../host/host.service';
-import { ActivatedRoute, Router } from '@angular/router';
-import { RestApiService } from '../api/rest-api.service';
-import { NgIf } from '@angular/common';
-import { ConfirmPopupComponent } from '../rule-engine/confirm-popup/confirm-popup.component';
+import { ChangeDetectorRef, Component, ViewEncapsulation } from '@angular/core';
import { MatDialog } from '@angular/material';
+import { ActivatedRoute, Router } from '@angular/router';
import { ToastrService } from 'ngx-toastr';
-import { ChangeDetectorRef } from '@angular/core';
+import { RestApiService } from '../api/rest-api.service';
+import { HostService } from '../host/host.service';
+import { ConfirmPopupComponent } from '../rule-engine/confirm-popup/confirm-popup.component';
+import { PluginPubSub } from '../sdc/plugin-pubsub';
+import { Store } from '../store/store';
+import { NgxDatatableModule } from '@swimlane/ngx-datatable';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
- styleUrls: ['./home.component.scss']
+ styleUrls: ['./home.component.scss'],
+ encapsulation: ViewEncapsulation.None
})
export class HomeComponent {
linkToMain: string;
- currentUserId: string;
showTable = true;
- selectedLine;
+ selectedLine = [];
monitoringComponents = new Array();
unavailableMonitoringComponents = new Array();
- hoveredIndex = null;
+ hoveredIndex = 1;
dialogRef;
+ deleteRow: number;
+
+ loadingIndicator = true;
constructor(
private activeRoute: ActivatedRoute,
@@ -37,14 +40,58 @@
this.activeRoute.queryParams.subscribe(params => {
console.log('params: %o', params);
this.store.sdcParmas = params;
+
+ console.log('init comunication with sdc');
+ const eventsToWaitFor = [
+ 'WINDOW_OUT',
+ 'VERSION_CHANGE',
+ 'CHECK_IN',
+ 'CHECK_OUT',
+ 'SUBMIT_FOR_TESTING',
+ 'UNDO_CHECK_OUT'
+ ];
+ this.store.ifrmaeMessenger = new PluginPubSub(
+ this.store.sdcParmas.eventsClientId,
+ this.store.sdcParmas.parentUrl,
+ eventsToWaitFor
+ );
+ console.log('send ready to sdc');
+ this.store.ifrmaeMessenger.notify('READY');
+
+ this.store.ifrmaeMessenger.on((eventData, event) => {
+ console.log('eventData', eventData);
+ console.log('event', event);
+ if (
+ eventData.type === 'WINDOW_OUT' ||
+ eventData.type === 'CHECK_IN' ||
+ eventData.type === 'SUBMIT_FOR_TESTING'
+ ) {
+ const currentUrl = this.route.url;
+ if (currentUrl.includes('main')) {
+ if (this.store.cdumpIsDirty) {
+ this.store.displaySDCDialog = true;
+ } else {
+ this.store.ifrmaeMessenger.notify('ACTION_COMPLETED');
+ }
+ } else {
+ this.store.ifrmaeMessenger.notify('ACTION_COMPLETED');
+ }
+ } else {
+ this.store.ifrmaeMessenger.notify('ACTION_COMPLETED');
+ }
+ });
+
this.linkToMain = `/main/${params.contextType}/${params.uuid}/${
params.version
}/`;
+ this.loadingIndicator = true;
+
this._restApi.getMonitoringComponents(params).subscribe(
response => {
console.log('response: ', response);
if (response.hasOwnProperty('monitoringComponents')) {
this.monitoringComponents = response.monitoringComponents;
+ this.loadingIndicator = false;
}
if (response.hasOwnProperty('unavailable')) {
this.unavailableMonitoringComponents = response.unavailable;
@@ -83,8 +130,11 @@
}
}
- checkHoverCondition(item: any): boolean {
+ // Monitoring Table logic
+
+ checkTableItemHoverCondition(item: any): boolean {
if (
+ this.store.sdcParmas !== undefined &&
this.store.sdcParmas.userId === item.lastUpdaterUserId &&
this.store.sdcParmas.lifecycleState === 'NOT_CERTIFIED_CHECKOUT'
) {
@@ -94,12 +144,19 @@
}
}
- editItem(item: any): void {
+ onTableActivate(event: any): void {
+ this.hoveredIndex = this.monitoringComponents.findIndex(
+ s => s == event.row
+ );
+ console.log('selected : ');
+ }
+
+ editTableItem(item: any): void {
this.store.vfiName = item.vfiName;
this.route.navigate([this.linkToMain + '/' + item.uuid]);
}
- onSelect(item: any): void {
+ onTableSelectItem(item: any): void {
this.selectedLine = item;
console.log('selected : ', item);
}
@@ -107,17 +164,17 @@
deleteEnable(item: any): boolean {
console.log(
'delete enable: ',
- item.isOwner && item.Lifecycle == 'NOT_CERTIFIED_CHECKOUT'
+ item.isOwner && item.Lifecycle === 'NOT_CERTIFIED_CHECKOUT'
);
const { userId, lifecycleState } = this.store.sdcParmas;
return (
- item.lastUpdaterUserId == userId &&
- lifecycleState == 'NOT_CERTIFIED_CHECKOUT'
+ item.lastUpdaterUserId === userId &&
+ lifecycleState === 'NOT_CERTIFIED_CHECKOUT'
);
}
- deleteItem(item: any): void {
- let deleteRow = this.hoveredIndex;
+ deleteTableItem(item: any, index: any): void {
+ this.deleteRow = index;
this.dialogRef = this.dialog.open(ConfirmPopupComponent, {
panelClass: 'my-confrim-dialog',
disableClose: true
@@ -125,7 +182,7 @@
this.dialogRef.afterClosed().subscribe(result => {
// if the user want to delete
if (result) {
- if (item.status == 'submitted') {
+ if (item.status === 'Submitted') {
this._restApi
.deleteMonitoringComponentWithBlueprint(
this.store.sdcParmas,
@@ -135,15 +192,15 @@
)
.subscribe(
response => {
- this.itemDeletedRemoveAndNotify(deleteRow);
+ this.itemDeletedRemoveAndNotify(this.deleteRow);
},
error => {
if (error.messageId === 'SVC6118') {
- this.monitoringComponents.splice(deleteRow, 1);
+ this.monitoringComponents.splice(this.deleteRow, 1);
this.changeDetectorRef.detectChanges();
}
const errorMsg = Object.values(error.requestError) as any;
- this.toastr.error('', errorMsg[0]);
+ this.toastr.error('', errorMsg[0].formattedErrorMessage);
}
);
} else {
@@ -155,7 +212,7 @@
)
.subscribe(
response => {
- this.itemDeletedRemoveAndNotify(deleteRow);
+ this.itemDeletedRemoveAndNotify(this.deleteRow);
},
error => {
const errorMsg = Object.values(error.requestError) as any;
@@ -175,14 +232,4 @@
'Monitoring Configuration was successfully deleted'
);
}
-
- // convertFile(fileInput: any) {
- // // read file from input
- // const fileReaded = fileInput.target.files[0];
- // Papa.parse(fileReaded, {
- // complete: function(results) {
- // console.log('Finished:', results.data);
- // }
- // });
- // }
}
diff --git a/public/src/app/loader/loader.component.spec.ts b/public/src/app/loader/loader.component.spec.ts
index 7c82913..2159e0d 100644
--- a/public/src/app/loader/loader.component.spec.ts
+++ b/public/src/app/loader/loader.component.spec.ts
@@ -1,8 +1,7 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
+import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { LoaderComponent } from './loader.component';
-describe('LoaderComponent', () => {
+describe('DiagramComponent', () => {
let component: LoaderComponent;
let fixture: ComponentFixture<LoaderComponent>;
diff --git a/public/src/app/main/main.component.html b/public/src/app/main/main.component.html
index d54b27b..4c71a37 100644
--- a/public/src/app/main/main.component.html
+++ b/public/src/app/main/main.component.html
@@ -1,4 +1,4 @@
-<div class="container">
+<div class="main-container">
<div style="padding: .25em; display: flex;
justify-content: space-between;
@@ -6,16 +6,18 @@
<div>
<a (click)="goBack()" data-tests-id="btn-back-home" style="display: flex; cursor: pointer;text-decoration: none; color: #009fdb;">
<mat-icon fontSet="fontawesome" fontIcon="fa-angle-left" style="height: 17px; width: 12px; font-size: 17px;"></mat-icon>
- <span style="display: flex; align-items: center;">Back to Monitoring</span>
+ <span style="display: flex; align-items: center; font-size: 12px;">
+ Back to Monitoring
+ </span>
</a>
<div style="margin:10px 0;" data-tests-id="new-monitorying-titie">
- <span style="font-size: 2em;" *ngIf='store.generalflow === "new"'>
+ <span style="font-size: 22px;" *ngIf='store.generalflow === "new"'>
New
</span>
- <span style="font-size: 2em;" *ngIf='store.generalflow === "import"'>
+ <span style="font-size: 22px;" *ngIf='store.generalflow === "import"'>
Import
</span>
- <span style="font-size: 2em;">
+ <span style="font-size: 22px;">
Monitoring Configuration
</span>
</div>
@@ -24,7 +26,9 @@
<div>
<div *ngIf='store.generalflow === "new" || store.generalflow === "edit"'>
<button *ngIf="!this.store.isEditMode" mat-raised-button color="primary" [disabled]="this.generalComponent.generalForm.invalid"
- data-tests-id="createMonitoring" (click)="createMC(this.generalComponent.generalForm.value)">Create</button>
+ style="width: 95px;height: 36px;" data-tests-id="createMonitoring" (click)="createMC(this.generalComponent.generalForm.value)">
+ Create
+ </button>
<div *ngIf="this.store.isEditMode" style="display: flex;">
<button mat-icon-button (click)="saveCDUMP()" [disabled]="!store.cdumpIsDirty">
@@ -35,12 +39,12 @@
justify-content: center;
align-items: center;" [innerHTML]="'save' | feather:22"></span>
</button>
- <button mat-raised-button color="primary" (click)="saveAndCreateBlueprint()">Submit</button>
+ <button mat-raised-button color="primary" style="width: 95px; height: 36px; border-radius: 2px;" (click)="saveAndCreateBlueprint()">Submit</button>
</div>
</div>
<div *ngIf='store.generalflow === "import"'>
<button mat-raised-button color="primary" (click)="importMC(this.generalComponent.newVfcmt)" [disabled]="this.generalComponent.generalForm.invalid"
- data-tests-id="importMonitoring">Import</button>
+ data-tests-id="importMonitoring" style="width: 95px;height: 36px;">Import</button>
</div>
</div>
</div>
@@ -53,7 +57,7 @@
<app-general (updateCdumpEv)="updateCdump($event)"></app-general>
</div>
</p-tabPanel>
- <p-tabPanel *ngFor="let item of nodes" [header]="item.name">
+ <p-tabPanel *ngFor="let item of nodes;" [header]="item.name">
<app-rule-frame [tabName]="item.name"></app-rule-frame>
</p-tabPanel>
</p-tabView>
diff --git a/public/src/app/main/main.component.scss b/public/src/app/main/main.component.scss
index 402a56a..47f1bd9 100644
--- a/public/src/app/main/main.component.scss
+++ b/public/src/app/main/main.component.scss
@@ -1,7 +1,6 @@
-.container {
+.main-container {
display: flex;
- flex-direction: column;
- // height: 100%;
+ flex-direction: column; // height: 100%;
margin: 1em;
}
@@ -16,11 +15,12 @@
.ui-tabview .ui-tabview-nav li {
margin: 0;
+ border-radius: 0;
}
.ui-tabview .ui-tabview-nav li.ui-tabview-selected {
color: #009fdb;
- border-top: 4px solid #009fdb;
+ border-top: 2px solid #009fdb;
border-bottom: none;
}
diff --git a/public/src/app/main/main.component.ts b/public/src/app/main/main.component.ts
index fdbb077..a3f2271 100644
--- a/public/src/app/main/main.component.ts
+++ b/public/src/app/main/main.component.ts
@@ -1,12 +1,11 @@
-import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
-import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
-import { RestApiService } from '../api/rest-api.service';
-import { Store } from '../store/store';
-import { RuleFrameComponent } from '../rule-frame/rule-frame.component';
-import { GeneralComponent } from '../general/general.component';
+import { Component, ViewChild, ViewEncapsulation } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
import { ToastrService } from 'ngx-toastr';
-import { forkJoin } from 'rxjs/observable/forkJoin';
+import { RestApiService } from '../api/rest-api.service';
+import { GeneralComponent } from '../general/general.component';
+import { RuleEngineApiService } from '../rule-engine/api/rule-engine-api.service';
+import { Store } from '../store/store';
@Component({
selector: 'app-main',
@@ -18,11 +17,13 @@
cdump;
nodes = [];
@ViewChild(GeneralComponent) generalComponent: GeneralComponent;
- // @ViewChildren(RuleFrameComponent) ruleFrameRef: QueryList<RuleFrameComponent>;
+ // @ViewChildren(RuleFrameComponent) ruleFrameRef:
+ // QueryList<RuleFrameComponent>;
constructor(
private route: ActivatedRoute,
private restApi: RestApiService,
+ private _ruleApi: RuleEngineApiService,
private toastr: ToastrService,
public store: Store,
private location: Location
@@ -39,6 +40,8 @@
createMC(params) {
console.log('newVfcmt: %o', params);
this.store.loader = true;
+ this.store.vfiName = params.serviceAttached;
+ this.store.flowType = 'default';
this.restApi
.createNewVFCMT({
name: params.name,
@@ -55,6 +58,7 @@
this.store.mcUuid = success.vfcmt.uuid;
console.log(this.cleanProperty(success));
this.store.cdump = success.cdump;
+ this.diagramRelationsFromCdump(success);
this.nodes = this.store.cdump.nodes;
this.store.setTabsProperties(this.nodes);
this.setDataFromMapToRuleEngine(success.cdump);
@@ -70,6 +74,17 @@
);
}
+ private diagramRelationsFromCdump(success: any) {
+ this.generalComponent.list = success.cdump.relations.map(item => {
+ return {
+ name1: item.name1,
+ name2: item.name2,
+ p1: item.meta.p1,
+ p2: item.meta.p2
+ };
+ });
+ }
+
updateCdump(cdump) {
this.store.cdump = cdump;
this.nodes = this.store.cdump.nodes;
@@ -81,6 +96,8 @@
console.log('importVfcmt: %o', params);
this.generalComponent.importCompleted = true;
this.store.loader = true;
+ this.store.vfiName = params.serviceAttached;
+ this.store.flowType = params.flowType;
this.restApi
.importVFCMT({
name: params.name,
@@ -96,11 +113,13 @@
.subscribe(
success => {
console.log(success);
+
this.location.path();
// this.location.go();
this.store.mcUuid = success.vfcmt.uuid;
console.log(this.cleanProperty(success));
this.store.cdump = success.cdump;
+ this.diagramRelationsFromCdump(success);
this.nodes = this.store.cdump.nodes;
this.store.setTabsProperties(this.nodes);
this.setDataFromMapToRuleEngine(success.cdump);
@@ -119,12 +138,9 @@
setDataFromMapToRuleEngine(cdump) {
this.store.tabParmasForRule = cdump.nodes
- .filter(x => x.name.includes('map'))
+ .filter(x => x.name.toLowerCase().includes('map'))
.map(y => {
- return {
- name: y.name,
- nid: y.nid
- };
+ return { name: y.name, nid: y.nid };
});
}
@@ -139,7 +155,6 @@
}
saveCDUMP() {
- debugger;
this.store.loader = true;
this.restApi
.saveMonitoringComponent({
@@ -167,7 +182,6 @@
}
saveAndCreateBlueprint() {
- debugger;
this.store.loader = true;
if (this.store.cdumpIsDirty) {
this.restApi
@@ -210,6 +224,7 @@
.subscribe(
success => {
this.store.loader = false;
+
this.toastr.success('', 'Save succeeded');
},
error => {
@@ -223,6 +238,7 @@
}
handleChange(e) {
+ this._ruleApi.callUpdateTabIndex(e.index - 1);
this.store.setTabIndex(e.index - 1);
}
}
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 {
- Component,
- Inject,
- ViewChildren,
- QueryList,
AfterViewInit,
+ Component,
+ QueryList,
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 { cloneDeep } from 'lodash';
-import { Store } from '../../store/store';
import { NgForm } from '@angular/forms';
+import { cloneDeep } from 'lodash';
+import { v1 as uuid } from 'uuid';
+import { Store } from '../../store/store';
+import { ActionComponent } from '../action/action.component';
+import { RuleEngineApiService } from '../api/rule-engine-api.service';
@Component({
selector: 'app-action-list',
@@ -22,6 +18,7 @@
styleUrls: ['./action-list.component.scss']
})
export class ActionListComponent implements AfterViewInit {
+ title = '';
error: Array<string>;
condition: any;
eventType: string;
@@ -53,8 +50,10 @@
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 @@
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 @@
toFormat: '',
fromTimezone: '',
toTimezone: ''
+ },
+ replaceText: {
+ find: '',
+ replace: ''
+ },
+ logText: {
+ name: '',
+ level: '',
+ text: ''
+ },
+ logEvent: {
+ title: ''
}
});
}
@@ -162,7 +185,10 @@
? 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 @@
return {
version: this.version,
eventType: this.eventType,
+ notifyId: this.store.notifyIdValue,
uid: this.uid,
description: this.description,
actions: actionSetData,
@@ -225,12 +252,12 @@
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 @@
}
);
} 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>
+
+ <!-- log Event -->
+ <div *ngIf="action.actionType === 'log event'" class="center-content-item">
+ <div class="from">
+ <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-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>
- <!-- 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;">
- <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">
+ <!-- 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 Format</span>
- <input class="input-text" ngModel required name="toFormat" [(ngModel)]="action.dateFormatter.toFormat" 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 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>
- </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">
+ <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 @@
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 @@
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 @@
});
}
- 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 @@
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 @@
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 @@
);
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
@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 @@
.subscribe(tree => {
console.log('tree: ', tree);
this.loader = false;
- this.nodesUpdated.emit({
- nodes: tree
- });
+ this.nodesUpdated.emit({ nodes: tree });
});
}
}
diff --git a/public/src/app/rule-frame/rule-frame.component.html b/public/src/app/rule-frame/rule-frame.component.html
index 10f3032..e0afa3d 100644
--- a/public/src/app/rule-frame/rule-frame.component.html
+++ b/public/src/app/rule-frame/rule-frame.component.html
@@ -1,16 +1,16 @@
<div style="position: relative; display: flex; justify-content: flex-end; height: 100%;">
- <div *ngIf="!tabName.includes('map')" style="margin: 1em;">
+ <div *ngIf="!tabName.toLowerCase().includes('map')" style="margin: 1em;">
<app-bar-icons [tabName]="tabName"></app-bar-icons>
</div>
<!-- rule engine -->
- <div style="width: 100%;" *ngIf="tabName.includes('map')">
+ <div style="width: 100%;" *ngIf="tabName.toLowerCase().includes('map')">
<app-slide-panel [activePane]="store.isLeftVisible ? 'left' : 'right'">
<div leftPane style="height: 100%; overflow: auto;">
<app-rule-list></app-rule-list>
</div>
- <div rightPane style="height: 100%; overflow: auto;">
+ <div rightPane style="height: 100%; overflow: scroll;">
<app-action-list></app-action-list>
</div>
</app-slide-panel>
diff --git a/public/src/app/rule-frame/rule-frame.component.ts b/public/src/app/rule-frame/rule-frame.component.ts
index 4d5f999..2729c14 100644
--- a/public/src/app/rule-frame/rule-frame.component.ts
+++ b/public/src/app/rule-frame/rule-frame.component.ts
@@ -1,6 +1,5 @@
-import { Component, OnDestroy, Input, ViewChild } from '@angular/core';
+import { Component, Input, OnDestroy } from '@angular/core';
import { Store } from '../store/store';
-import { BarIconsComponent } from '../bar-icons/bar-icons.component';
@Component({
selector: 'app-rule-frame',
diff --git a/public/src/app/sdc-notify-dialog/sdc-notify-dialog.component.html b/public/src/app/sdc-notify-dialog/sdc-notify-dialog.component.html
new file mode 100644
index 0000000..f8d51fe
--- /dev/null
+++ b/public/src/app/sdc-notify-dialog/sdc-notify-dialog.component.html
@@ -0,0 +1,39 @@
+<p-dialog [style]="{'border-top-color':'#ffb81c'}" [closable]="false" [(visible)]="store.displaySDCDialog" modal="modal" styleClass="dcae-notify"
+ width="500" [responsive]="true" data-tests-id="sdc-dialog">
+ <p-header>
+ <div style="display: flex;">
+ <span style="color: #ffb81c;
+ padding-right: 15px;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;" [innerHTML]="'alert-triangle' | feather:28"></span>
+ <span style="font-family: 'Open Sans', sans-serif;
+ font-size: 24px; width: 100%;">
+ Exit from DCAE
+ </span>
+ <span style="
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ color:rgb(90, 90, 90);
+ align-items: center;" [innerHTML]="'x' | feather:20
+ " (click)="closeforChange()"></span>
+ </div>
+ </p-header>
+
+ <div style="padding: 0 0 20px 43px; font-family: 'Open Sans', sans-serif;
+ font-size: 14px;">
+ Do you want to save?
+ </div>
+
+ <p-footer>
+ <button mat-raised-button color="primary" style="background-color: #FFB81C; margin-right: 10px; font-size: 14px; font-family: 'Open Sans', sans-serif; height: 36px;" (click)="closeDialog()" data-tests-id="error-cancel">
+ SAVE
+ </button>
+ <button mat-raised-button class="btn-secondry" style="border-color: #FFB81C !important; color:#FFB81C !important; font-size: 14px; font-family: 'Open Sans', sans-serif;text-align: center; height: 36px;" (click)="closeforChange()"
+ data-tests-id="error-cancel">
+ DISCARD
+ </button>
+ </p-footer>
+</p-dialog>
diff --git a/public/src/app/sdc-notify-dialog/sdc-notify-dialog.component.scss b/public/src/app/sdc-notify-dialog/sdc-notify-dialog.component.scss
new file mode 100644
index 0000000..a775398
--- /dev/null
+++ b/public/src/app/sdc-notify-dialog/sdc-notify-dialog.component.scss
@@ -0,0 +1,17 @@
+:host /deep/ .dcae-notify {
+ border-top: solid 6px #ffb81c;
+}
+:host /deep/ .ui-dialog .ui-dialog-titlebar {
+ padding-top: 15px;
+ padding-left: 20px;
+ padding-right: 12px;
+ padding-bottom: 0;
+}
+
+:host /deep/ .ui-dialog-footer {
+ padding: 10px;
+}
+
+:host /deep/ .ui-dialog.ui-widget .ui-dialog-content {
+ padding-top: 10px;
+}
diff --git a/public/src/app/sdc-notify-dialog/sdc-notify-dialog.component.ts b/public/src/app/sdc-notify-dialog/sdc-notify-dialog.component.ts
new file mode 100644
index 0000000..7572012
--- /dev/null
+++ b/public/src/app/sdc-notify-dialog/sdc-notify-dialog.component.ts
@@ -0,0 +1,72 @@
+import { Component, ElementRef, ViewChild } from '@angular/core';
+import { Router } from '@angular/router';
+import { RestApiService } from '../api/rest-api.service';
+import { MainComponent } from '../main/main.component';
+import { Store } from '../store/store';
+
+@Component({
+ selector: 'app-sdc-notify-dialog',
+ templateUrl: './sdc-notify-dialog.component.html',
+ styleUrls: ['./sdc-notify-dialog.component.scss']
+})
+export class SdcNotifyDialogComponent {
+ @ViewChild(MainComponent) mainComponent: ElementRef;
+
+ constructor(
+ public store: Store,
+ private router: Router,
+ private _restApi: RestApiService
+ ) {}
+
+ closeDialog() {
+ const currentUrl = this.router.url;
+ if (currentUrl.includes('main')) {
+ if (this.store.cdumpIsDirty) {
+ this.saveCDUMP();
+ } else {
+ this.completeAndClose();
+ }
+ } else {
+ this.completeAndClose();
+ }
+ }
+
+ saveCDUMP() {
+ this.store.loader = true;
+ this._restApi
+ .saveMonitoringComponent({
+ contextType: this.store.sdcParmas.contextType,
+ serviceUuid: this.store.sdcParmas.uuid,
+ vfiName: this.store.vfiName,
+ vfcmtUuid: this.store.mcUuid,
+ flowType: this.store.flowType,
+ cdump: this.store.cdump
+ })
+ .subscribe(
+ success => {
+ this.store.loader = false;
+ this.store.mcUuid = success.uuid;
+ this.store.ifrmaeMessenger.notify('ACTION_COMPLETED');
+ },
+ error => {
+ this.store.loader = false;
+ console.log(error.notes);
+ this.store.ifrmaeMessenger.notify('ACTION_COMPLETED');
+ this.store.ErrorContent = Object.values(error.requestError);
+ this.store.displayErrorDialog = true;
+ },
+ () => {
+ this.store.ifrmaeMessenger.notify('ACTION_COMPLETED');
+ }
+ );
+ }
+
+ private completeAndClose() {
+ this.store.ifrmaeMessenger.notify('ACTION_COMPLETED');
+ this.store.displaySDCDialog = false;
+ }
+
+ closeforChange() {
+ this.completeAndClose();
+ }
+}
diff --git a/public/src/app/sdc/base-pubsub.ts b/public/src/app/sdc/base-pubsub.ts
new file mode 100644
index 0000000..f7fcadc
--- /dev/null
+++ b/public/src/app/sdc/base-pubsub.ts
@@ -0,0 +1,124 @@
+declare const window: Window;
+
+export interface IPubSubEvent {
+ type: string;
+ originId: string;
+ data: any;
+}
+
+export interface ISubscriber {
+ window: Window;
+ locationUrl: string;
+}
+
+export class BasePubSub {
+ subscribers: Map<string, ISubscriber>;
+ eventsCallbacks: Array<Function>;
+ clientId: string;
+ eventsToWait: Map<string, Array<string>>;
+
+ constructor(pluginId: string) {
+ this.subscribers = new Map<string, ISubscriber>();
+ this.eventsCallbacks = [];
+ this.eventsToWait = new Map<string, Array<string>>();
+ this.clientId = pluginId;
+ this.onMessage = this.onMessage.bind(this);
+
+ window.addEventListener('message', this.onMessage);
+ }
+
+ public register(
+ subscriberId: string,
+ subscriberWindow: Window,
+ subscriberUrl: string
+ ) {
+ const subscriber = {
+ window: subscriberWindow,
+ locationUrl: subscriberUrl || subscriberWindow.location.href
+ };
+
+ this.subscribers.set(subscriberId, subscriber);
+ }
+
+ public unregister(subscriberId: string) {
+ this.subscribers.delete(subscriberId);
+ }
+
+ public on(callback: Function) {
+ const functionExists = this.eventsCallbacks.find((func: Function) => {
+ return callback.toString() === func.toString();
+ });
+
+ if (!functionExists) {
+ this.eventsCallbacks.push(callback);
+ }
+ }
+
+ public off(callback: Function) {
+ const index = this.eventsCallbacks.indexOf(callback);
+ this.eventsCallbacks.splice(index, 1);
+ }
+
+ public notify(eventType: string, eventData?: any) {
+ const eventObj = {
+ type: eventType,
+ data: eventData,
+ originId: this.clientId
+ };
+
+ this.subscribers.forEach(
+ (subscriber: ISubscriber, subscriberId: string) => {
+ subscriber.window.postMessage(eventObj, subscriber.locationUrl);
+ }
+ );
+
+ return {
+ subscribe: function(callbackFn) {
+ if (this.subscribers.size !== 0) {
+ const subscribersToNotify = Array.from(this.subscribers.keys());
+
+ const checkNotifyComplete = (subscriberId: string) => {
+ const index = subscribersToNotify.indexOf(subscriberId);
+ subscribersToNotify.splice(index, 1);
+
+ if (subscribersToNotify.length === 0) {
+ callbackFn();
+ }
+ };
+
+ this.subscribers.forEach(
+ (subscriber: ISubscriber, subscriberId: string) => {
+ if (
+ this.eventsToWait.has(subscriberId) &&
+ this.eventsToWait.get(subscriberId).indexOf(eventType) !== -1
+ ) {
+ const actionCompletedFunction = (
+ eventData,
+ subId = subscriberId
+ ) => {
+ if (eventData.type === 'ACTION_COMPLETED') {
+ checkNotifyComplete(subId);
+ }
+ this.off(actionCompletedFunction);
+ };
+ this.on(actionCompletedFunction);
+ } else {
+ checkNotifyComplete(subscriberId);
+ }
+ }
+ );
+ } else {
+ callbackFn();
+ }
+ }.bind(this)
+ };
+ }
+
+ protected onMessage(event: any) {
+ if (this.subscribers.has(event.data.originId)) {
+ this.eventsCallbacks.forEach((callback: Function) => {
+ callback(event.data, event);
+ });
+ }
+ }
+}
diff --git a/public/src/app/sdc/plugin-pubsub.ts b/public/src/app/sdc/plugin-pubsub.ts
new file mode 100644
index 0000000..848c7d2
--- /dev/null
+++ b/public/src/app/sdc/plugin-pubsub.ts
@@ -0,0 +1,32 @@
+import { BasePubSub } from './base-pubsub';
+
+declare const window: Window;
+
+export class PluginPubSub extends BasePubSub {
+ constructor(
+ pluginId: string,
+ parentUrl: string,
+ eventsToWait?: Array<string>
+ ) {
+ super(pluginId);
+ this.register('sdc-hub', window.parent, parentUrl);
+ this.subscribe(eventsToWait);
+ }
+
+ public subscribe(eventsToWait?: Array<string>) {
+ const registerData = {
+ pluginId: this.clientId,
+ eventsToWait: eventsToWait || []
+ };
+
+ this.notify('PLUGIN_REGISTER', registerData);
+ }
+
+ public unsubscribe() {
+ const unregisterData = {
+ pluginId: this.clientId
+ };
+
+ this.notify('PLUGIN_UNREGISTER', unregisterData);
+ }
+}
diff --git a/public/src/app/store/store.ts b/public/src/app/store/store.ts
index a9f2431..b075699 100644
--- a/public/src/app/store/store.ts
+++ b/public/src/app/store/store.ts
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
-import { observable, computed, action, toJS, reaction } from 'mobx';
import { findIndex } from 'lodash';
+import { action, computed, observable, toJS } from 'mobx';
@Injectable()
export class Store {
@@ -16,6 +16,10 @@
@observable expandAdvancedSetting = [];
@observable generalflow;
@observable vfiName;
+ @observable flowType;
+ @observable ifrmaeMessenger;
+ @observable waitForSave = false;
+ @observable displaySDCDialog = false;
// error dialog
@observable displayErrorDialog = false;
@observable ErrorContent = [];
@@ -23,9 +27,11 @@
// rule-engine
@observable tabParmasForRule;
@observable ruleList = new Array();
+ @observable ruleListExistParams;
@observable ruleEditorInitializedState;
@observable isLeftVisible;
@observable inprogress;
+ @observable notifyIdValue = '';
@action
updateRuleInList(rule) {
@@ -82,6 +88,13 @@
} else if (typeof x.assignment.value === 'object') {
x.assignment.value = JSON.stringify(x.assignment.value);
}
+ if (x.value) {
+ if (typeof x.value === 'object') {
+ x.value = JSON.stringify(x.value);
+ }
+ } else if (!x.value) {
+ x.value = x.assignment.value;
+ }
return x;
});
});
diff --git a/public/src/environments/environment.prod.ts b/public/src/environments/environment.prod.ts
index bc3ac4b..84965a9 100644
--- a/public/src/environments/environment.prod.ts
+++ b/public/src/environments/environment.prod.ts
@@ -1,5 +1,5 @@
export const environment = {
production: true,
- apiBaseUrl: 'dcae/dcaeProxy',
- imagePath: 'dcae_fe/assets/images'
+ apiBaseUrl: 'dcaed/dcaeProxy',
+ imagePath: 'dcaed/assets/images'
};
diff --git a/public/src/polyfills.ts b/public/src/polyfills.ts
index d68672f..5db0ca6 100644
--- a/public/src/polyfills.ts
+++ b/public/src/polyfills.ts
@@ -19,48 +19,39 @@
*/
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
-// import 'core-js/es6/symbol';
-// import 'core-js/es6/object';
-// import 'core-js/es6/function';
-// import 'core-js/es6/parse-int';
-// import 'core-js/es6/parse-float';
-// import 'core-js/es6/number';
-// import 'core-js/es6/math';
-// import 'core-js/es6/string';
-// import 'core-js/es6/date';
-// import 'core-js/es6/array';
-// import 'core-js/es6/regexp';
-// import 'core-js/es6/map';
-// import 'core-js/es6/weak-map';
-// import 'core-js/es6/set';
-
+import 'core-js/es6/array';
+import 'core-js/es6/date';
+import 'core-js/es6/function';
+import 'core-js/es6/map';
+import 'core-js/es6/math';
+import 'core-js/es6/number';
+import 'core-js/es6/object';
+import 'core-js/es6/parse-float';
+import 'core-js/es6/parse-int';
+import 'core-js/es6/regexp';
+import 'core-js/es6/set';
+import 'core-js/es6/string';
+import 'core-js/es6/symbol';
+import 'core-js/es6/weak-map';
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
-
/** IE10 and IE11 requires the following for the Reflect API. */
// import 'core-js/es6/reflect';
-
-
/** Evergreen browsers require these. **/
-// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
+// Used for reflect-metadata in JIT. If you use AOT (and only Angular
+// decorators), you can remove.
import 'core-js/es7/reflect';
-
-
+/***************************************************************************************************
+ * APPLICATION IMPORTS
+ */
+import 'intl';
+import 'intl/locale-data/jsonp/en';
/**
* Required to support Web Animations `@angular/platform-browser/animations`.
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
**/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
-
-
-
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
-import 'zone.js/dist/zone'; // Included with Angular CLI.
-
-
-
-/***************************************************************************************************
- * APPLICATION IMPORTS
- */
+import 'zone.js/dist/zone'; // Included with Angular CLI.
diff --git a/public/src/stories/diagram.stories.ts b/public/src/stories/diagram.stories.ts
index 00dd922..682fa6d 100644
--- a/public/src/stories/diagram.stories.ts
+++ b/public/src/stories/diagram.stories.ts
@@ -13,10 +13,24 @@
},
props: {
list: array('list', [
- { source: 'node1dsvsdsvd', target: 'node2' },
- { source: 'node3', target: 'node4' },
- { source: 'node5', target: 'nodedsvsds6' },
- { source: 'node7', target: 'node8' }
+ {
+ name1: 'node1dsvsdsvd',
+ name2: 'node2',
+ p1: 'Stream_publish_0',
+ p2: 'capability'
+ },
+ {
+ name1: 'node33',
+ name2: 'node2555',
+ p1: 'requirement2',
+ p2: 'capability11'
+ },
+ {
+ name1: 'namber4',
+ name2: 'namber3',
+ p1: 'requirement3',
+ p2: 'capability4'
+ }
])
}
}));
diff --git a/public/src/styles.css b/public/src/styles.css
index 4b1d433..a56199a 100644
--- a/public/src/styles.css
+++ b/public/src/styles.css
@@ -1,8 +1,13 @@
/* You can add global styles to this file, and also import other style files */
-@import '@angular/material/prebuilt-themes/indigo-pink.css';
+@import '@angular/material/prebuilt-themes/indigo-pink.css';
@font-face {
font-family: 'Open Sans';
+ src: url('./assets/fonts/OpenSans-Regular.ttf') format('ttf');
+}
+
+@font-face {
+ font-family: 'Open Sans-SemiBold';
src: url('./assets/fonts/OpenSans-SemiBold.ttf') format('ttf');
}
@@ -19,28 +24,31 @@
app-root,
app-home {
height: 100%;
- font-family: 'Open Sans', sans-serif;
+ font-family: 'Open Sans', sans-serif !important;
font-size: 13px;
/* height: 100vh; */
}
+select,
+input,
+textarea {
+ font-family: 'Open Sans', sans-serif !important;
+}
+
div,
span {
font-weight: 400;
}
-div .field-label,
-span .field-label,
-div .field-label > span {
- font-weight: 600;
-}
-
/* form input validation border */
-textarea.ng-touched.ng-invalid:not(form),input.ng-touched.ng-invalid:not(form) {
+
+textarea.ng-touched.ng-invalid:not(form),
+input.ng-touched.ng-invalid:not(form) {
border: 1px solid #cf2a2a !important;
}
/** reset button **/
+
.mat-fab.mat-primary,
.mat-mini-fab.mat-primary,
.mat-raised-button.mat-primary {
@@ -60,7 +68,13 @@
box-shadow: none !important;
}
+.mat-raised-button.mat-primary[disabled] {
+ background-color: #979797;
+ color: white;
+}
+
/* Astrix required */
+
.required::before {
content: '*';
color: red;
@@ -68,9 +82,11 @@
}
/** overide dialog **/
-.ui-dialog {
+
+/* .ui-dialog {
border-top: solid 6px #cf2a2a;
-}
+} */
+
.ui-dialog-titlebar {
background: white;
}