diff options
16 files changed, 904 insertions, 26 deletions
diff --git a/usecaseui-portal/src/app/Directives/disable-control.directive.ts b/usecaseui-portal/src/app/Directives/disable-control.directive.ts new file mode 100644 index 00000000..85495401 --- /dev/null +++ b/usecaseui-portal/src/app/Directives/disable-control.directive.ts @@ -0,0 +1,17 @@ +import { Directive, Input } from '@angular/core'; +import { NgControl } from '@angular/forms'; + +@Directive({ + selector: '[disableControl]' +}) +export class DisableControlDirective { + + @Input() + set disableControl(condition: boolean) { + const action = condition ? 'enable' : 'disable'; + this.ngControl.control[action](); + } + + constructor(private ngControl: NgControl) { + } +}
\ No newline at end of file diff --git a/usecaseui-portal/src/app/app.module.ts b/usecaseui-portal/src/app/app.module.ts index d46f9f5e..9d14d8f9 100644 --- a/usecaseui-portal/src/app/app.module.ts +++ b/usecaseui-portal/src/app/app.module.ts @@ -16,13 +16,16 @@ import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; import { HttpClient } from '@angular/common/http'; import { NgZorroAntdModule } from 'ng-zorro-antd'; import { NZ_I18N, en_US } from 'ng-zorro-antd'; import { NgxEchartsModule } from 'ngx-echarts'; +//Custom Directive +import { DisableControlDirective } from './Directives/disable-control.directive'; + import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; export function HttpLoaderFactory(httpClient: HttpClient) { @@ -49,6 +52,8 @@ import { PerformanceVmComponent } from './views/performance/performance-vm/perfo import { CcvpnNetworkComponent } from './views/ccvpn-network/ccvpn-network.component'; import { CcvpnDetailComponent } from './views/services/services-list/ccvpn-detail/ccvpn-detail.component'; import { CcvpnCreationComponent } from './views/services/services-list/ccvpn-creation/ccvpn-creation.component'; +import { MdonsDetailComponent } from './views/services/services-list/mdons-detail/mdons-detail.component'; +import { MdonsCreationComponent } from './views/services/services-list/mdons-creation/mdons-creation.component'; import { DetailsComponent } from './shared/components/details/details.component'; import { GraphiclistComponent } from './shared/components/graphiclist/graphiclist.component'; @@ -160,11 +165,15 @@ import { BusinessOrderComponent } from './views/services/slicing-management/csmf NsiModelComponent, NssiModelComponent, CsmfSlicingBusinessManagementComponent, - BusinessOrderComponent + BusinessOrderComponent, + MdonsCreationComponent, + MdonsDetailComponent, + DisableControlDirective ], imports: [ BrowserModule, FormsModule, + ReactiveFormsModule , HttpClientModule, TranslateModule.forRoot({ loader: { @@ -183,6 +192,10 @@ import { BusinessOrderComponent } from './views/services/slicing-management/csmf SlicingBusinessModelComponent, NsiModelComponent, NssiModelComponent - ] + ], + exports: [ + FormsModule, + ReactiveFormsModule + ] }) -export class AppModule { }
\ No newline at end of file +export class AppModule { } diff --git a/usecaseui-portal/src/app/core/services/serviceList.service.ts b/usecaseui-portal/src/app/core/services/serviceList.service.ts index 1ada669f..945d60c2 100644 --- a/usecaseui-portal/src/app/core/services/serviceList.service.ts +++ b/usecaseui-portal/src/app/core/services/serviceList.service.ts @@ -17,6 +17,7 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders, HttpParams, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import { servicesTableData,baseUrl } from '../models/dataInterface'; +import { retry, catchError } from 'rxjs/operators'; @Injectable() export class ServiceListService { @@ -52,11 +53,17 @@ export class ServiceListService { pnfDetail: this.baseUrl + "/uui-sotn/getPnfInfo/", connectivity: this.baseUrl + "/uui-sotn/getConnectivityInfo/", vpnBinding: this.baseUrl + "/uui-sotn/getPinterfaceByVpnId/", + getNIList: this.baseUrl + "/uui-lcm/getAllNI/" }; //The following APIs are optimizable + //get all unni + getAllNI(type) { + return this.http.get<any>(this.url.getNIList+type); + } + // Get all customers getAllCustomers() { return this.http.get<any>(this.url.customers); @@ -89,8 +96,11 @@ export class ServiceListService { } // Create interface createInstance(requestBody, createParams) { - return this.http.post<any>(this.url.createService + createParams, requestBody); + return this.http.post<any>(this.url.createService + createParams, requestBody).pipe( + catchError(this.handleError) + ); } + // NS CreateInstance step one nsCreateInstance(requestBody) { return this.http.post<any>(this.url.ns_createService, requestBody); @@ -136,7 +146,7 @@ export class ServiceListService { inputs: "" }; return this.http.post<any>(this.url.nstemplateParameters, body); - } else if (type == "e2e") { + } else if (type == "e2e" || type == "MDONS") { let params = new HttpParams({ fromObject: {"toscaModelPath":template.toscaModelURL} }); let url = this.url.e2etemplateParameters.replace("*_*", template.uuid); return this.http.get<any>(url,{params}); @@ -209,5 +219,17 @@ export class ServiceListService { return this.http.get<any>(url); } - + + handleError(error) { + let errorMessage = ''; + if (error.error instanceof ErrorEvent) { + // client-side error + errorMessage = `Error: ${error.error.message}`; + } else { + // server-side error + errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`; + } + console.log("errorMessage : "+errorMessage); + return Observable.throw(error); + } } diff --git a/usecaseui-portal/src/app/views/services/services-list/ccvpn-creation/ccvpn-creation.component.ts b/usecaseui-portal/src/app/views/services/services-list/ccvpn-creation/ccvpn-creation.component.ts index 752fddd6..abbe6d6a 100644 --- a/usecaseui-portal/src/app/views/services/services-list/ccvpn-creation/ccvpn-creation.component.ts +++ b/usecaseui-portal/src/app/views/services/services-list/ccvpn-creation/ccvpn-creation.component.ts @@ -27,7 +27,7 @@ export class CcvpnCreationComponent implements OnInit { constructor(private myhttp: ServiceListService) { } @Input() createParams; - @Input() ccvpn_temParametersContent; + @Input() ccvpn_temParametersContent; @Output() closeCreate = new EventEmitter(); diff --git a/usecaseui-portal/src/app/views/services/services-list/create-model/create-model.component.html b/usecaseui-portal/src/app/views/services/services-list/create-model/create-model.component.html index e093b3b8..93a2bd50 100644 --- a/usecaseui-portal/src/app/views/services/services-list/create-model/create-model.component.html +++ b/usecaseui-portal/src/app/views/services/services-list/create-model/create-model.component.html @@ -26,6 +26,7 @@ <nz-option nzValue="CCVPN" nzLabel="CCVPN"></nz-option> <nz-option nzValue="E2E Service" nzLabel="E2E Service"></nz-option> <nz-option nzValue="Network Service" nzLabel="Network Service"></nz-option> + <nz-option nzValue="MDONS" nzLabel="MDONS"></nz-option> </nz-select> </div> <div class="select-list"> diff --git a/usecaseui-portal/src/app/views/services/services-list/create-model/create-model.component.ts b/usecaseui-portal/src/app/views/services/services-list/create-model/create-model.component.ts index f7cce450..72817bc2 100644 --- a/usecaseui-portal/src/app/views/services/services-list/create-model/create-model.component.ts +++ b/usecaseui-portal/src/app/views/services/services-list/create-model/create-model.component.ts @@ -6,7 +6,7 @@ import { ServiceListService } from '../../../../core/services/serviceList.servic templateUrl: './create-model.component.html', styleUrls: ['./create-model.component.less'], }) -export class CreateModelComponent implements OnInit { +export class CreateModelComponent implements OnInit { @Input()isVisible: boolean; @Input()customerList; @Input()serviceTypeList; @@ -95,7 +95,7 @@ export class CreateModelComponent implements OnInit { } handleOk(): void { - if (this.templateTypeSelected === "SOTN" || this.templateTypeSelected === "CCVPN") { + if (this.templateTypeSelected === "SOTN" || this.templateTypeSelected === "CCVPN" || this.templateTypeSelected === "MDONS") { this.createData = { commonParams: { customer: this.currentCustomer, diff --git a/usecaseui-portal/src/app/views/services/services-list/mdons-creation/mdons-creation.component.css b/usecaseui-portal/src/app/views/services/services-list/mdons-creation/mdons-creation.component.css new file mode 100644 index 00000000..934d38d4 --- /dev/null +++ b/usecaseui-portal/src/app/views/services/services-list/mdons-creation/mdons-creation.component.css @@ -0,0 +1,80 @@ +/* + Copyright (C) 2019 CMCC, Inc. and others. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +.title { + font: 700 18px/18px "思源黑体"; + color: #4c5e70; + margin-bottom: 18px; + } + hr { + border: none; + height: 2px; + background-color: #dce1e7; + margin-bottom: 10px; + } + .model { + background-color: #fff; + height: 90%; + overflow-y: auto; + } + .model .back { + position: absolute; + top: 10px; + right: 20px; + } + .model .creation { + position: relative; + width: 60%; + height: 100%; + overflow-y: auto; + border-radius: 5px; + padding: 20px; + } + .model .creation .baseparms h3 { + color: #3fa8eb; + font: 700 16px "Arial"; + } + .model .creation .baseparms h4 { + font: 700 16px "Arial"; + } + .model .creation .baseparms ul li { + margin: 3px 0; + } + .model .creation .baseparms ul li span { + display: inline-block; + width: 40%; + font: 700 14px "Arial"; + vertical-align: middle; + overflow: hidden; + text-overflow: ellipsis; + text-align: right; + } + .model .creation .baseparms ul li input { + width: 165px; + } + .model .creation .submit { + position: absolute; + top: 10px; + right: 20px; + } + .model .chart { + width: 40%; + padding: 10px; + height: 100%; + border-left: 10px solid #f3f3f3; + } + + +
\ No newline at end of file diff --git a/usecaseui-portal/src/app/views/services/services-list/mdons-creation/mdons-creation.component.html b/usecaseui-portal/src/app/views/services/services-list/mdons-creation/mdons-creation.component.html new file mode 100644 index 00000000..47e22fe9 --- /dev/null +++ b/usecaseui-portal/src/app/views/services/services-list/mdons-creation/mdons-creation.component.html @@ -0,0 +1,49 @@ +<div class="model creation-model"> + <!-- Create data --> + <div class="top-title"> + <h3 class="title fl">{{templateParameters.type}} {{"i18nTextDefine_InstanceCreation" | translate}} </h3> + <div class="fl" style="width: 20%"> + <button class="submit" [disabled]="!mdons_creation_form.valid" nz-button (click)="createService()"> + <span> {{"i18nTextDefine_Create" | translate}} </span> + </button> + <button class="back" nz-button (click)="goback()"></button> + </div> + </div> +<div [formGroup]="mdons_creation_form"> +<div class="e2ecreate-content"> + <div class="creation fl" style="width:95%"> + <div *ngIf="mdonsModelShow" class="baseparms clearfix"> + <div class="vnf-box form-group" *ngIf="templateParameters.inputs.length>0"> + <h3>{{"i18nTextDefine_templateInputs" | translate}}</h3> + <ul > + <li *ngFor="let parameter of templateParameters.inputs; let i = index;"> + <span *ngIf="parameter.isRequired.includes('true')" style="color: red;width:10px;min-width:1px;">*</span> + <span title="{{parameter.name}}">{{parameter.name}}:</span> + <input *ngIf="!(parameter.name.includes('uni_id') || parameter.name.includes('enni_id') || parameter.name.includes('date'))" formControlName="{{parameter.name}}" nz-input [(ngModel)]="parameter.value" style="margin-left: auto;"> + <!--<pre>{{mdons_creation_form.get(parameter.name).valid}}</pre>--> + <input style="margin-left: 2px;" *ngIf="parameter.name.includes('date')" type="date" formControlName="{{parameter.name}}" nz-input [(ngModel)]="parameter.value" placeholder="yyyy-MM-dd"/> + <span style="color: red;width:10px;" *ngIf="mdons_creation_form.controls[parameter.name].errors?.required && (mdons_creation_form.controls[parameter.name].dirty || mdons_creation_form.controls[parameter.name].touched)">Required</span> + <nz-dropdown class = "customclass" [nzTrigger]="'click'" [nzPlacement]="'bottomLeft'" *ngIf="(parameter.name.includes('uni_id') || parameter.name.includes('enni_id'))"> + <button style="width: 300px;" nz-button nz-dropdown><span *ngIf="parameter.name.includes('uni_id')">{{uniIdSelected.id}}</span><span *ngIf="parameter.name.includes('enni_id')">{{enniIdSelected.id}}</span> <i class="anticon anticon-down"></i> + </button> + <ul nz-menu *ngIf="parameter.name.includes('uni_id')" class="dropDownScroller"> + <li nz-menu-item (click)="chooseUni(item)" *ngFor="let item of uniList" > + <a title="{{item.id}}">{{item.id}}</a> + </li> + </ul> + <ul nz-menu *ngIf="parameter.name.includes('enni_id')" class="dropDownScroller" > + <li nz-menu-item (click)="chooseEnni(item)" *ngFor="let item of enniList" > + <a title="{{item.id}}">{{item.id}}</a> + </li> + </ul> + </nz-dropdown> + </li> + </ul> + </div> + </div> + </div> + + </div> + </div> +</div> + diff --git a/usecaseui-portal/src/app/views/services/services-list/mdons-creation/mdons-creation.component.less b/usecaseui-portal/src/app/views/services/services-list/mdons-creation/mdons-creation.component.less new file mode 100644 index 00000000..5084bb99 --- /dev/null +++ b/usecaseui-portal/src/app/views/services/services-list/mdons-creation/mdons-creation.component.less @@ -0,0 +1,175 @@ +/* + Copyright (C) 2019 CMCC, Inc. and others. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +.title { + font: 700 18px/18px "思源黑体"; + color: #4c5e70; + margin-bottom: 18px; +} +hr { + border: none; + height: 2px; + background-color: #dce1e7; + margin-bottom: 10px; +} +.dropDownScroller{ + max-height: 250px; + overflow: auto; + } +.astrixRequired{ + color: red; + width:1%; + min-width:1px; +} + +.customclass .anticon-down { + float: right +} + +.model { + background-color: #F7F8FC; + height: 100%; + overflow-y: auto; + position: relative; + .top-title{ + width: 100%; + padding: 20px; + position: relative; + display: inline-block; + } + .submit{ + position: absolute; + width:84px; + height: 35px; + top: 10px; + right: 85px; + color: #fff; + font-size: 18px; + background:linear-gradient(90deg,rgba(99,194,246,1) 0%,rgba(62,155,255,1) 100%) !important; + border-radius:4px; + border: none!important; + border-color:rgba(0,0,0,0)!important; + } + .submit:hover{ + background:linear-gradient(90deg, rgb(103, 207, 246) 0%, rgb(69, 175, 255) 100%) !important; + border: none; + } + .back,.back:hover{ + position: absolute; + top: 10px; + right: 20px; + display: inline-block; + width: 35px; + height: 35px; + background:url("../../../../../assets/images/Return-icon.png") no-repeat!important; + background-size: 100%!important; + border-radius:4px; + color: #D7D7D7; + cursor: pointer; + } + .back:hover{ + background: url("../../../../../assets/images/Return-icon-active.png")!important; + background-size: 100%!important; + } + .top-title h3.title { + height: 35px; + width: 80%; + font-size:16px; + font-family:ArialMT; + color:#3C4F8C; + line-height:35px; + display: inline-block; + } + .e2ecreate-content{ + position: relative; + width: 98%; + height: 100%; + margin-left: 30px; + box-shadow:0px 10px 15px 2px rgba(222,222,222,0.5); + background: #fff; + border-radius:2px; + } + .creation{ + position: relative; + width: 58%; + height: 100%; + overflow-y: auto; + padding: 20px; + background: #fff; + .baseparms { + h3,h4{ + color: #06A7E2; + width: 96%; + height: 40px; + line-height: 35px; + font-size: 18px; + font-weight: 500; + margin: 10px auto; + border-bottom: 2px solid; + border-image: -webkit-linear-gradient(#07A9E1,#30D9C4) 100 100; + border-image: -moz-linear-gradient(#07A9E1,#30D9C4) 100 100; + border-image: linear-gradient(#07A9E1,#30D9C4) 100 100; + border-radius:2px; + } + h4 { + font: 700 16px "Arial"; + margin-left: 25px; + } + .vnf-box{ + clear: both; + } + ul{ + margin-left: 30px; + } + ul li { + margin: 10px 0; + width: 42%; + margin-right: 5%; + float: left; + text-align: left; + span { + display: inline-block; + width: 30%; + min-width: 80px; + font: 700 14px "Arial"; + overflow: hidden; + text-align: left; + word-break: break-all; + vertical-align: top; + } + input,nz-select{ + width: 49%; + margin-left:3% + } + } + } + } + .dividing-line{ + width: 0; + height: 85%; + margin: 4% 0; + border-left: 1px #cccccc dashed; + } + .chart { + width: 38%; + padding: 10px; + height: 95%; + margin: 0 auto; + #createChart{ + height: 100%; + width: 100%; + } + } +} diff --git a/usecaseui-portal/src/app/views/services/services-list/mdons-creation/mdons-creation.component.ts b/usecaseui-portal/src/app/views/services/services-list/mdons-creation/mdons-creation.component.ts new file mode 100644 index 00000000..3123bfc8 --- /dev/null +++ b/usecaseui-portal/src/app/views/services/services-list/mdons-creation/mdons-creation.component.ts @@ -0,0 +1,160 @@ +import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { ServiceListService } from '../../../../core/services/serviceList.service'; +import { FormGroup, FormBuilder, Validators, FormArray } from '@angular/forms'; + +import * as d3 from 'd3'; + +@Component({ + selector: 'app-mdons-creation', + templateUrl: './mdons-creation.component.html', + styleUrls: ['./mdons-creation.component.less'] +}) +export class MdonsCreationComponent implements OnInit { + mdons_creation_form: FormGroup; + + uniList= []; + uniIdSelected = { id: null }; + enniList= []; + enniIdSelected = { id: null }; + templateParameters = { + invariantUUID: "", + uuid: "", + name: "", + type: "", + version: "", + description: "", + category: "", + subcategory: "", + customizationUuid: "", + inputs: [], + nestedTemplates: [] + }; + + // mdons requstbody + service = { + name: "", // <== service instance name + description: "", + serviceInvariantUuid: "", + serviceUuid: "", // uuid ?? + globalSubscriberId: "", // "customer.id", + serviceType: "", // "serviceType.value", + parameters: { + locationConstraints: [ + + ], + resources: [], + requestInputs: { + name:"", + customer:"", + service_provider:"", + due_date:"", + end_date:"", + uni_id:"", + enni_id:"" + } + } + } + + mdonsModelShow : boolean = false; + constructor(private myhttp: ServiceListService,private fb: FormBuilder) { + + + } + @Input() createParams; + @Input() mdons_temParametersContent; + @Output() mdonsCloseCreate = new EventEmitter(); + + ngOnInit() { + this.getalluni(); + this.getallenni(); + this.templateParameters=this.mdons_temParametersContent; + this.mdonsModelShow = true; + this.mdons_creation_form = this.fb.group({}); + this.buildFormArrayOfGroupsFromArr(); + console.log("Controls "+this.mdons_creation_form.controls['terms']) + } + + buildFormArrayOfGroupsFromArr() { + for(let i of this.templateParameters.inputs){ + if(i.isRequired === "true" && !(i.name.includes('uni_id') || i.name.includes('enni_id'))){ + this.mdons_creation_form.addControl(i.name, this.fb.control('', [Validators.required])) + } else { + this.mdons_creation_form.addControl(i.name, this.fb.control('')) + } + } + } + + getalluni() { + this.myhttp.getAllNI("UNI") + .subscribe((data) => { + this.uniList = data.map(item => ({id: item }) ); + if(data.length !== 0){ + this.uniIdSelected = this.uniList[0]; + } + }) +} + +getallenni() { + this.myhttp.getAllNI("NNI") + .subscribe((data) => { + this.enniList = data.map(item => ({id: item }) ); + if(data.length !== 0){ + this.enniIdSelected = this.enniList[0]; + } + }) +} + +chooseUni(item = this.uniIdSelected){ + if(this.uniIdSelected !== item) this.uniIdSelected = item; +} + +chooseEnni(item = this.enniIdSelected){ + if(this.enniIdSelected !== item) this.enniIdSelected = item; +} + + goback() { + this.mdonsCloseCreate.emit(); + } + + + + createService() { + if (this.mdons_creation_form.invalid) { + return; + } else { + this.service.serviceInvariantUuid = this.templateParameters.invariantUUID; + this.service.name = this.templateParameters.name; + this.service.description = this.templateParameters.description; + this.service.serviceUuid = this.templateParameters.uuid; + this.service.globalSubscriberId = this.createParams.commonParams.customer.id; + this.service.serviceType = this.createParams.commonParams.serviceType.name; + + this.templateParameters.inputs.forEach((ipnut) => { + this.service.parameters.requestInputs[ipnut.name] = ipnut.value == undefined ? ipnut.defaultValue : ipnut.value; + if(ipnut.name.includes('uni_id')) { + this.service.parameters.requestInputs[ipnut.name] = this.uniIdSelected.id == undefined ? ipnut.defaultValue : this.uniIdSelected.id; + } + if(ipnut.name.includes('enni_id')) { + this.service.parameters.requestInputs[ipnut.name] = this.enniIdSelected.id == undefined ? ipnut.defaultValue : this.enniIdSelected.id; + } + if(ipnut.name==='name') { + this.service.name = ipnut.value == undefined ? ipnut.defaultValue : ipnut.value; + } + }) + + console.log(this.service) + this.mdonsCloseCreate.emit({ service: this.service }); + } + } + + markFormTouched(group: FormGroup | FormArray) { + Object.keys(group.controls).forEach((key: string) => { + const control = group.controls[key]; + if (control instanceof FormGroup || control instanceof FormArray) { control.markAsTouched(); this.markFormTouched(control); } + else { control.markAsTouched(); }; + }); + }; + + + +}
\ No newline at end of file diff --git a/usecaseui-portal/src/app/views/services/services-list/mdons-detail/mdons-detail.component.html b/usecaseui-portal/src/app/views/services/services-list/mdons-detail/mdons-detail.component.html new file mode 100644 index 00000000..dd622985 --- /dev/null +++ b/usecaseui-portal/src/app/views/services/services-list/mdons-detail/mdons-detail.component.html @@ -0,0 +1,44 @@ +<div class="model creation-model"> + + <div class="top-title"> + <h3 class="title fl">{{serviceInstanceName}} Instance Detail</h3> + <div class="fl" style="width: 20%"> + <button class="back" nz-button (click)="goback()"></button> + </div> + </div> + <div class="detaildata fl"> + <div class="baseparms clearfix"> + <div class="vnf-box"> + <h3> {{"i18nTextDefine_Base" | translate}} </h3> + <ul class="clearfix"> + <li> + <span style="width:15%">Name:</span> + <span class="input-content">{{service.name}}</span> + </li> + <li> + <span style="width:25%">Description:</span> + <span class="input-content">{{service.description}}</span> + </li> + </ul> + </div> + <div class="vnf-box" *ngIf="getKeys(e2e_requestInputs).length>0"> + <h3>{{"i18nTextDefine_templateInputs" | translate}}</h3> + <ul class="clearfix"> + <li *ngFor="let key of getKeys(e2e_requestInputs);"> + <span title="{{key}}">{{key}}:</span> + <span class="input-content">{{e2e_requestInputs[key]}}</span> + </li> + </ul> + </div> + </div> +</div> + +<!-- chart --> +<div class="chart fr"> + <div id="createChart"> + <svg width="100%" height="100%"> + </svg> + </div> +</div> + +</div>
\ No newline at end of file diff --git a/usecaseui-portal/src/app/views/services/services-list/mdons-detail/mdons-detail.component.less b/usecaseui-portal/src/app/views/services/services-list/mdons-detail/mdons-detail.component.less new file mode 100644 index 00000000..9a0f1925 --- /dev/null +++ b/usecaseui-portal/src/app/views/services/services-list/mdons-detail/mdons-detail.component.less @@ -0,0 +1,143 @@ +/* + Copyright (C) 2019 CMCC, Inc. and others. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +.title { + font: 700 18px/18px "思源黑体"; + color: #4c5e70; + margin-bottom: 18px; + } + hr { + border: none; + height: 2px; + background-color: #dce1e7; + margin-bottom: 10px; + } + .creation-model{ + position: relative; + } + .model { + background-color: #F7F8FC; + height: 100%; + overflow-y: auto; + position: relative; + .top-title{ + width: 100%; + padding: 20px; + position: relative; + display: inline-block; + } + .back,.back:hover{ + position: absolute; + top: 10px; + right: 20px; + display: inline-block; + width: 35px; + height: 35px; + background:url("../../../../../assets/images/Return-icon.png") no-repeat!important; + background-size: 100%!important; + border-radius:4px; + color: #D7D7D7; + cursor: pointer; + } + .back:hover{ + background: url("../../../../../assets/images/Return-icon-active.png")!important; + background-size: 100%!important; + } + .top-title h3.title { + height: 35px; + width: 80%; + font-size:16px; + font-family:ArialMT; + color:#3C4F8C; + line-height:35px; + display: inline-block; + } + .detaildata{ + position: relative; + width: 58%; + height: 100%; + overflow-y: auto; + border-radius: 5px; + padding: 20px; + background: #fff; + margin-left: 30px; + box-shadow:0px 10px 15px 2px rgba(222,222,222,0.5); + .baseparms { + h3,h4{ + color: #06A7E2; + width: 96%; + height: 40px; + line-height: 35px; + font-size: 18px; + font-weight: 500; + margin: 10px auto; + border-bottom: 2px solid; + border-image: -webkit-linear-gradient(#07A9E1,#30D9C4) 100 100; + border-image: -moz-linear-gradient(#07A9E1,#30D9C4) 100 100; + border-image: linear-gradient(#07A9E1,#30D9C4) 100 100; + border-radius:2px; + } + h4 { + font: 700 16px "Arial"; + margin-left: 25px; + } + .vnf-box{ + clear: both; + } + ul{ + margin-left: 30px; + } + ul li { + margin: 10px 0; + width: 49%; + float: left; + text-align: left; + color:rgba(60,79,140,1); + font-size: 14px; + span { + display: inline-block; + width: 50%; + font: 700 14px "Arial"; + vertical-align: top; + overflow: hidden; + text-align: left; + color:rgba(60,79,140,0.5); + word-break: break-all; + } + span.input-content{ + width: 42%; + color: #3C4F8C; + margin-left: 5%; + word-break: break-all; + vertical-align: top; + } + } + } + } + .chart { + width: 35%; + padding: 10px; + height: 95%; + box-shadow: 0px 10px 35px 10px rgba(222, 222, 222, 0.5); + margin-right: 1%; + background:linear-gradient(180deg,rgba(183, 230, 247, 1) 0%,rgba(214, 240, 254, 1) 100%); + border-radius: 4px; + #createChart{ + height: 100%; + width: 100%; + } + } + } +
\ No newline at end of file diff --git a/usecaseui-portal/src/app/views/services/services-list/mdons-detail/mdons-detail.component.ts b/usecaseui-portal/src/app/views/services/services-list/mdons-detail/mdons-detail.component.ts new file mode 100644 index 00000000..ee4c71df --- /dev/null +++ b/usecaseui-portal/src/app/views/services/services-list/mdons-detail/mdons-detail.component.ts @@ -0,0 +1,50 @@ +import { Component, Input, Output, OnInit, EventEmitter } from '@angular/core'; +import { ServiceListService } from '../../../../core/services/serviceList.service'; + +@Component({ + selector: 'app-mdons-detail', + templateUrl: './mdons-detail.component.html', + styleUrls: ['./mdons-detail.component.less'] +}) +export class MdonsDetailComponent implements OnInit { + + constructor(private myhttp: ServiceListService) { } + + @Input() detailParams; + @Output() closeDetail = new EventEmitter(); + serviceInstanceName: any; + serviceType: any; + input_parameters: any; + e2e_requestInputs: any; + + service = { + name: "", + description: "", + }; + + getKeys(item) { + return Object.keys(item); + } + + ngOnInit() { + + console.log(this.detailParams); + this.serviceInstanceName = this.detailParams['serviceDomain'] || this.detailParams["nsName"]; + this.input_parameters = JSON.parse(this.detailParams['input-parameters']); + console.log(this.input_parameters); + this.service = { + name: this.input_parameters.service.name, + description: this.input_parameters.service.description, + }; + if (this.input_parameters.service.parameters.requestInputs != undefined && Object.keys(this.input_parameters.service.parameters.requestInputs).length > 0) { + this.e2e_requestInputs = this.input_parameters.service.parameters.requestInputs; + } + } + + goback() { + this.closeDetail.emit(); + } + + + +}
\ No newline at end of file diff --git a/usecaseui-portal/src/app/views/services/services-list/services-list.component.html b/usecaseui-portal/src/app/views/services/services-list/services-list.component.html index 1092b332..b4442747 100644 --- a/usecaseui-portal/src/app/views/services/services-list/services-list.component.html +++ b/usecaseui-portal/src/app/views/services/services-list/services-list.component.html @@ -24,7 +24,7 @@ <button nz-button nz-dropdown><span>{{customerSelected.name}}</span> <i class="anticon anticon-down"></i> </button> <ul nz-menu> - <li nz-menu-item (click)="choseCustomer(item)" *ngFor="let item of customerList"> + <li nz-menu-item (click)="choseCustomer(item)" *ngFor="let item of customerList"> <a title="{{item.name}}">{{item.name}}</a> </li> </ul> @@ -99,13 +99,13 @@ 'updating':data.statusClass==='Updating','deleting':data.statusClass==='1002','creating':data.statusClass==='1001', 'scaling':data.statusClass==='1003','healing':data.statusClass==='1004'}" *ngIf="data.tips !== 'Available' && data.tips !== 'Unavailable'">{{data.tips}}</span> - <span *ngIf="data.tips === 'Available' " class="marginLeft10"> + <span *ngIf="data.tips === 'Available' " class="marginLeft10" title = "{{data.serviceStatusInfo}}"> <img src="assets/images/wancheng-icon.png" alt="Available"> </span> - <span *ngIf="data.tips === 'Unavailable' " class="marginLeft10"> + <span *ngIf="data.tips === 'Unavailable' " class="marginLeft10" title = "{{data.serviceStatusInfo}}"> <img src="assets/images/shibai-icon.png" alt="Unavailable"> </span> - <nz-progress *ngIf="data.status === 'In Progress'" [nzPercent]="data.rate" + <nz-progress *ngIf="data.status === 'In Progress'" [nzPercent]="data.rate" title = "{{data.serviceStatusInfo}}" [nzShowInfo]="false" nzStatus="active"></nz-progress> </td> <td> @@ -205,8 +205,8 @@ <img src="assets/images/execute-inproess.png" alt="instance temination is starting"> </span> <div class="ant-notification-notice-message" - *ngIf="createData['commonParams']['templateType'] === 'CCVPN' || thisService['serviceDomain'] === 'SOTN'"> - {{ createData['commonParams']['templateType'] }} {{"i18nTextDefine_InstanceCreationStarting" | + *ngIf="thisCreateService['serviceDomain'] === 'CCVPN' || thisService['serviceDomain'] === 'SOTN' || thisService['serviceDomain'] === 'MDONS'"> + {{ thisService['serviceDomain'] }} {{"i18nTextDefine_InstanceCreationStarting" | translate}} </div> <div class="ant-notification-notice-message" @@ -246,8 +246,8 @@ *ngIf="thisCreateService.status == 'Failed'"> </span> <div class="ant-notification-notice-message" - *ngIf="(createData['commonParams']['templateType'] == 'CCVPN' || thisCreateService['serviceDomain'] == 'SOTN') && thisCreateService.status == 'Successful'"> - {{ createData['commonParams']['templateType'] }} {{"i18nTextDefine_InstanceCreatedSuccessfully" | + *ngIf="(thisCreateService['serviceDomain'] == 'CCVPN' || thisCreateService['serviceDomain'] == 'SOTN' || thisCreateService['serviceDomain'] == 'MDONS') && thisCreateService.status == 'Successful'"> + {{ thisCreateService['serviceDomain'] }} {{"i18nTextDefine_InstanceCreatedSuccessfully" | translate}} </div> <div class="ant-notification-notice-message" @@ -259,8 +259,8 @@ NS {{"i18nTextDefine_InstanceCreatedSuccessfully" | translate}} </div> <div class="ant-notification-notice-message" - *ngIf="(createData['commonParams']['templateType'] == 'CCVPN' || thisCreateService['serviceDomain'] == 'SOTN') && thisCreateService.status == 'Failed'"> - {{ createData['commonParams']['templateType'] }} {{"i18nTextDefine_InstanceCreationFailed" | + *ngIf="(thisCreateService['serviceDomain'] == 'CCVPN' || thisCreateService['serviceDomain'] == 'SOTN' || thisCreateService['serviceDomain'] == 'MDONS') && thisCreateService.status == 'Failed'"> + {{ thisCreateService['serviceDomain'] }} {{"i18nTextDefine_InstanceCreationFailed" | translate}} </div> <div class="ant-notification-notice-message" @@ -301,7 +301,7 @@ *ngIf="thisService.status == 'Failed'"> </span> <div class="ant-notification-notice-message" - *ngIf="(thisService['serviceDomain'] == 'CCVPN' || thisService['serviceDomain'] == 'SOTN') && thisService.status == 'Successful'"> + *ngIf="(thisService['serviceDomain'] == 'CCVPN' || thisService['serviceDomain'] == 'SOTN' || thisCreateService['serviceDomain'] == 'MDONS') && thisService.status == 'Successful'"> {{ thisService['serviceDomain'] }} {{"i18nTextDefine_InstanceTeminatedSuccessfully" | translate}} </div> @@ -315,7 +315,7 @@ </div> <div class="ant-notification-notice-message" - *ngIf="(thisService['serviceDomain'] == 'CCVPN' || thisService['serviceDomain'] == 'SOTN') && thisService.status == 'Failed'"> + *ngIf="(thisService['serviceDomain'] == 'CCVPN' || thisService['serviceDomain'] == 'SOTN' || thisCreateService['serviceDomain'] == 'MDONS') && thisService.status == 'Failed'"> {{ thisService['serviceDomain'] }} {{"i18nTextDefine_InstanceTeminationFailed" | translate}} </div> @@ -520,6 +520,10 @@ <app-e2e-detail [detailParams]="detailData" (closeDetail)="detailshow2 = false;listDisplay = false;"> </app-e2e-detail> </div> + <div class="detailComponent" *ngIf="detailshow2"> + <app-mdons-detail [detailParams]="detailData" (closeDetail)="detailshow2 = false;listDisplay = false;"> + </app-mdons-detail> + </div> <div class="createComponent" *ngIf="createshow"> <app-ccvpn-creation [createParams]="createData" [ccvpn_temParametersContent]="ccvpn_temParametersContent" (closeCreate)="closeCreate($event,templateCreatestarting,templateCreateSuccessFaild)"> @@ -531,9 +535,14 @@ (e2eCloseCreate)="e2eCloseCreate($event,templateCreatestarting,templateCreateSuccessFaild)"> </app-e2e-creation> </div> + <div class="createComponent" *ngIf="showCreateMDONS"> + <app-mdons-creation [createParams]="createData" [mdons_temParametersContent]="mdons_temParametersContent" + (mdonsCloseCreate)="mdonsCloseCreate($event,templateCreatestarting,templateCreateSuccessFaild)"> + </app-mdons-creation> + </div> <!--</div>--> </nz-layout> <div class="loading" *ngIf="loadingAnimateShow"> <img src="assets/images/loading-animate2.gif" alt="loading"> <p>Please wating……</p> -</div>
\ No newline at end of file +</div> diff --git a/usecaseui-portal/src/app/views/services/services-list/services-list.component.ts b/usecaseui-portal/src/app/views/services/services-list/services-list.component.ts index 6ee5c27d..adac12d1 100644 --- a/usecaseui-portal/src/app/views/services/services-list/services-list.component.ts +++ b/usecaseui-portal/src/app/views/services/services-list/services-list.component.ts @@ -61,7 +61,7 @@ export class ServicesListComponent implements OnInit { language = sessionStorage.getItem("DefaultLang"); iconMore = false; loadingAnimateShow = false; - serviceNunber = [ // top: E2E/NS/CCVPN data + serviceNunber = [ // top: E2E/NS/CCVPN/MDONS data { "serviceDomain": "E2E", "Success": 0, @@ -82,6 +82,13 @@ export class ServicesListComponent implements OnInit { "failed": 0, "InProgress": 0, "detailName": "i18nTextDefine_Cross_Domain_and_Cross_Layer_VPN" + }, + { + "serviceDomain": "MDONS", + "Success": 0, + "failed": 0, + "InProgress": 0, + "detailName": "i18nTextDefine_MDONS" } ]; @@ -157,10 +164,12 @@ export class ServicesListComponent implements OnInit { createshow: boolean = false; createshow2: boolean = false; + showCreateMDONS: boolean = false; listDisplay: boolean = false; createData: Object = {}; ccvpn_temParametersContent: any; e2e_ns_temParametersContent: any; + mdons_temParametersContent: any; createdModalShow(obj: any): void{ this.createData = obj.createData; @@ -171,6 +180,9 @@ export class ServicesListComponent implements OnInit { } else if (obj.templateType === "E2E Service" || obj.templateType === "Network Service") { this.e2e_ns_temParametersContent = obj.data; this.createshow2 = true; + } else if(obj.templateType === "MDONS"){ + this.mdons_temParametersContent = obj.data; + this.showCreateMDONS = true; } this.listDisplay = true; } @@ -231,6 +243,7 @@ export class ServicesListComponent implements OnInit { } // + item["serviceStatusInfo"] = item["orchestration-status"] if (item["operationResult"] === "2001") { item["status"] = "Available"; item["tips"] = "Available"; @@ -338,6 +351,15 @@ export class ServicesListComponent implements OnInit { this.serviceNunber[2]["InProgress"] += 1; } } + else if (item.serviceDomain === 'MDONS') { + if (item.operationResult === "2001") { + this.serviceNunber[3]["Success"] += 1; + } else if (item.operationResult === "2002") { + this.serviceNunber[3]["failed"] += 1; + } else if (item.operationResult === "2003") { + this.serviceNunber[3]["InProgress"] += 1; + } + } }) console.log(this.tableData) this.loading = false; @@ -436,6 +458,7 @@ export class ServicesListComponent implements OnInit { // show detail detailshow = false; detailshow2 = false; + detailshowMDONS = false; upDateShow = false; detailData: Object; @@ -459,7 +482,7 @@ export class ServicesListComponent implements OnInit { } else { this.upDateShow = true; } - } else if (service["serviceDomain"] === 'E2E Service' || service["serviceDomain"] === 'Network Service') { + } else if (service["serviceDomain"] === 'E2E Service' || service["serviceDomain"] === 'Network Service' || service["serviceDomain"] === 'MDONS') { this.detailshow2 = true; } this.listDisplay = true; @@ -569,6 +592,91 @@ export class ServicesListComponent implements OnInit { }) } + mdonsCloseCreate(obj, templateCreatestarting, templateCreateSuccessFaild) { + if (!obj) { + this.showCreateMDONS = false; // + this.listDisplay = false; // + return false; + } + this.showCreateMDONS = false; // + this.listDisplay = false; // + this.loadingAnimateShow = true; + console.log(obj); + let newData; // + let createParams = "?customerId=" + this.customerSelected.id + + "&serviceType=" + obj.service.serviceType + + "&serviceDomain=" + "MDONS" + + "&parentServiceInstanceId=" + + "&uuid=" + obj.service.serviceUuid + + "&invariantUuuid=" + obj.service.serviceInvariantUuid; + this.createService(obj, createParams, templateCreatestarting, templateCreateSuccessFaild).then((data) => { + console.log("mdons: "+data); + this.loadingAnimateShow = false; + + newData = { // + 'service-instance-id': data["serviceId"], + 'service-instance-name': obj.service.name, + serviceDomain: "MDONS", + childServiceInstances: [], + status: "In Progress", + statusClass: 1001, + rate: 0, + tips: "" + } + + + if (data == "FAILED") { + console.log("create ns service Failed :" + JSON.stringify(data)); + newData.status = "Failed"; + newData.tips = "Unavailable"; + this.thisCreateService = newData; + this.tableData = [newData, ...this.tableData]; + this.createNotification(templateCreateSuccessFaild); + return false; + } + + this.thisCreateService = newData; + this.tableData = [newData, ...this.tableData]; + this.createNotification(templateCreatestarting); + let updata = (prodata) => { + newData.rate = prodata.progress; + newData.tips = this.listSortMasters["operationTypes"].find((its) => { + return its["sortCode"] == newData["statusClass"] && its["language"] == this.language + })["sortValue"] + newData.rate + "%"; + if (newData["rate"] > 100) { + newData["status"] = prodata.status; + newData.tips = this.listSortMasters["operationTypes"].find((its) => { + return its["sortCode"] == newData["statusClass"] && its["language"] == this.language + })["sortValue"] + '\xa0\xa0\xa0' + newData["status"]; + } + } + let queryParams = { serviceId: data["serviceId"], operationId: data["operationId"], operationType: "1001" }; + return this.queryProgress(queryParams, updata); + }).then((data) => { + console.log(data); + if(data == false){ + return false; + } + newData.rate = 100; + newData.status = "Successful"; + this.createSuccessNotification(templateCreateSuccessFaild); + newData.tips = this.listSortMasters["operationTypes"].find((its) => { + return its["sortCode"] == newData["statusClass"] && its["language"] == this.language + })["sortValue"] + '\xa0\xa0\xa0' + this.listSortMasters["operationResults"].find((its) => { + return its["sortCode"] == 2001 && its["language"] == this.language + })["sortValue"]; + let hasUndone = this.tableData.some((item) => { + return item.rate < 100; + }) + if (!hasUndone) { + setTimeout(() => { + this.getTableData(); + }, 1000) + } + }) + + } + e2eCloseCreate(obj, templateCreatestarting, templateCreateSuccessFaild) { if (!obj) { this.createshow2 = false; // @@ -736,6 +844,7 @@ export class ServicesListComponent implements OnInit { let mypromise = new Promise((res, rej) => { this.myhttp.createInstance(requestBody, createParams) .subscribe((data) => { + console.log(data); if (data.status == "FAILED") { this.loadingAnimateShow = false; res("Failed"); @@ -743,6 +852,12 @@ export class ServicesListComponent implements OnInit { return false; } res(data.service); + }, + (error) => { + console.log('HTTP error '+error.message) + this.loadingAnimateShow = false; + res("FAILED"); + return false; }) }) return mypromise; diff --git a/usecaseui-portal/src/assets/i18n/en.json b/usecaseui-portal/src/assets/i18n/en.json index dcc1c924..9691bc68 100644 --- a/usecaseui-portal/src/assets/i18n/en.json +++ b/usecaseui-portal/src/assets/i18n/en.json @@ -138,4 +138,4 @@ "i18nTextDefine_PartnerNetwork": "Partner Network", "i18nTextDefine_HostUrl": "Host Url", "i18nTextDefine_DeleteLink": "Delete Link" -}
\ No newline at end of file +} |