diff options
author | cyuamber <xuranyjy@chinamobile.com> | 2019-08-22 16:55:57 +0800 |
---|---|---|
committer | cyuamber <xuranyjy@chinamobile.com> | 2019-08-22 16:56:09 +0800 |
commit | d0f5347dc16b5aa9fc95eb520fbc9a1c7b672b09 (patch) | |
tree | b3891d8de290d755d7f0f00d35bb77d3b89ad747 /usecaseui-portal/src/app/views/services/onboard-vnf-vm | |
parent | 56923755c761897cc86ca2457667fcc3e6a0e43f (diff) |
feat: change the project structure and add mock data function
Change-Id: I381845bff5eb37d1fab3eba8cf1ae7838df523b7
Issue-ID: USECASEUI-307
Signed-off-by: cyuamber <xuranyjy@chinamobile.com>
Diffstat (limited to 'usecaseui-portal/src/app/views/services/onboard-vnf-vm')
5 files changed, 1275 insertions, 0 deletions
diff --git a/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.css b/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.css new file mode 100644 index 00000000..4e80750c --- /dev/null +++ b/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.css @@ -0,0 +1,67 @@ +/* + 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: 20px; +} +.list { + background-color: #fff; + border-radius: 5px; + padding: 10px; +} +.list nz-table tbody td span.onboarding { + font-size: 12px; + color: #147dc2; +} +.list nz-table tbody td span.onboarded { + font-size: 14px; + color: #147dc2; +} +.list nz-table tbody td span.updating { + font-size: 12px; + color: blue; +} +.list nz-table tbody td span.deleting { + font-size: 12px; + color: red; +} +.list nz-table tbody td span.invalid { + font-size: 14px; + color: purple; +} +.list nz-table tbody td i.anticon { + cursor: pointer; + font-size: 18px; + padding: 2px; +} +.list nz-table tbody td i.anticon:hover { + color: #147dc2; +} +.list nz-table tbody td .cannotclick { + pointer-events: none; + color: #aaa; + opacity: 0.6; +} +.list nz-table tbody td .fileIcon{ + display: none; +}
\ No newline at end of file diff --git a/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.html b/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.html new file mode 100644 index 00000000..70ee81c0 --- /dev/null +++ b/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.html @@ -0,0 +1,333 @@ +<!-- + 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. +--> +<nz-tabset [nzTabPosition]="'top'" [nzType]="'card'"> + <nz-tab *ngFor="let tab of tabs" [nzTitle]="tab" (nzClick)="handleTabChange(tab)"> + <!-- nsList --> + <div class="list" *ngIf="tab === 'NS'"> + <!-- <h3 class="title"> Onboard {{tabTitle}} </h3> --> + <div style="width:100%;height: 30%;margin-bottom: 1%"> + <div class="listupload"> + <nz-upload nzType="drag" [(nzFileList)]="fileListNS" [nzBeforeUpload]="beforeUploadNS"> + <p class="ant-upload-drag-icon"> + <i nz-icon type="inbox" class="anticon anticon-inbox"></i> + </p> + <p class="ant-upload-text"> {{"i18nTextDefine_Click_CSAR_File" | translate}} </p> + <p class="ant-upload-hint"></p> + </nz-upload> + <button nz-button [nzLoading]="nsuploading" (click)="onClick(tab)" [disabled]="fileListNS.length == 0" + style="margin-top: 16px;margin-left: 55px;color: #FFFFFF;font-size: 13px;background-color: #3E9BFF;font-family: ArialMT;"> + {{ nsuploading ? 'Uploading' : 'Start Upload' }} + </button> + </div> + <div class="listlin"></div> + <div class="listfile"> + <div style="color: rgba(66,84,143,1);font-family:ArialMT;padding-bottom: 15px;height: 15%"> {{"i18nTextDefine_Uploaded_files" | translate}} </div> + <div class="nouploadfile">{{"i18nTextDefine_Nofileuploading" | translate}}</div> + <div style="height:80%;overflow: auto"> + <div class="listfilebgc" *ngFor="let itemns of nsRightList"> + <div> + <i class="anticon anticon-link"></i> + </div> + <div class="color" [ngClass]="{'progress':itemns.status == true}">{{itemns.name}}</div> + <div class="color" *ngIf="itemns.status"> + <nz-progress [nzPercent]="itemns.progress" [nzShowInfo]="false"></nz-progress> + </div> + <div class="color" *ngIf="!itemns.status"> + <span *ngIf="itemns.success == 0">{{"i18nTextDefine_File_upload_completed" | translate}}</span> + <span *ngIf="itemns.success == 1">{{"i18nTextDefine_File_upload_failed" | translate}}</span> + </div> + <div *ngIf="!itemns.status"> + <i class="anticon anticon-check-circle" *ngIf="itemns.success == 0" style="color:#7BC7F3!important;"></i> + <i class="anticon anticon-exclamation-circle" *ngIf="itemns.success == 1" style="color:#fb5c5c!important;"></i> + </div> + </div> + </div> + </div> + </div> + <nz-spin [nzSpinning]="isSpinning" style="height: 69%"> + <div class="mask" *ngIf="isSpinning"></div> + <nz-table #nzTable [nzData]="nstableData" nzShowSizeChanger [nzFrontPagination]="true" + [nzShowQuickJumper]="true" [nzPageSizeOptions]="[5,10,15,20]" [nzTotal]='total' [(nzPageSize)]="nspageSize" + [(nzPageIndex)]='nspageIndex' [nzLoading]="loading" nzSize="middle"> + <thead (nzSortChange)="sort($event)" nzSingleSort> + <tr> + <th nzWidth="15%"> {{"i18nTextDefine_NO" | translate}} </th> + <th nzWidth="15%" nzShowSort nzSortKey="name"> {{"i18nTextDefine_Name" | translate}} </th> + <th nzWidth="15%"> {{"i18nTextDefine_Version" | translate}} </th> + <th nzWidth="15%"> {{"i18nTextDefine_OnboardingState" | translate}} </th> + <th nzWidth="15%"> {{"i18nTextDefine_OperationalState" | translate}} </th> + <th nzWidth="10%"> {{"i18nTextDefine_UsageState" | translate}} </th> + <th nzWidth="15%"> {{"i18nTextDefine_Operationbutton" | translate}} </th> + </tr> + </thead> + <tbody> + <tr *ngFor="let item of nzTable.data; let i = index; "> + <td>{{i+1}}</td> + <!--<td *ngIf="item.uuid">{{item.uuid}}</td>--> + + <td *ngIf="item.nsdName">{{item.nsdName}}</td> + <td *ngIf="item.nsdName === null || item.nsdName === ''"> </td> + <td *ngIf="item.name">{{item.name}}</td> + <td *ngIf="item.name===null || item.name=== ''"> </td> + <td *ngIf="item.nsdVersion">{{item.nsdVersion}}</td> + <td *ngIf="item.nsdVersion === null || item.nsdVersion === ''"> </td> + <td *ngIf="item.version">{{item.version}}</td> + <td *ngIf="item.version === null || item.version === ''"> </td> + <td> + <span *ngIf="item.nsdOnboardingState">{{item.nsdOnboardingState}}</span> + <span *ngIf="item.nsdOnboardingState === null || item.nsdOnboardingState === ''"> </span> + <span *ngIf="item.uuid">{{status}}</span> + + <!-- <span *ngIf="item.uuid" [ngClass]="{'active':data.status=='Active','closed':data.status=='Closed','onboarding':data.status=='Onboarding', + 'updating':data.status=='Updating','deleting':data.status=='Deleting','creating':data.status=='Creating', + 'scaling':data.status=='Scaling','healing':data.status=='Healing'}">{{data.status || "Active"}}</span> + <nz-progress *ngIf="item.uuid" *ngIf="data.status == 'Creating' || data.status == 'Deleting' || data.status == 'Scaling' || data.status == 'Healing' " [nzPercent]="data.rate"></nz-progress> --> + </td> + <td>{{item.nsdOperationalState}}</td> + <td>{{item.nsdUsageState}}</td> + <td> + <i [ngClass]="{'cannotclick':onboardData.status == 'onboarding' && i == currentIndex}" + class="anticon anticon-upload upicon" #upload_icon (click)="updataNsService(item.uuid,i,notificationModel)" + *ngIf="item.uuid"></i> + <i class="anticon anticon-delete" nzType="info" (click)="showConfirm(i,item.id,tab,notificationModel)" + *ngIf="item.id"></i> + <!--<span *ngIf="item.id" [ngClass]="{'fileIcon':OnboardFile == 'disNone'}">--> + <!--<span *ngIf="item.id && item.sameid == undefined">--> + <!--<nz-upload [(nzFileList)]="fileList" [nzBeforeUpload]="beforeUpload">--> + <!--<i class="anticon anticon-file" type="upload" (click)="onClickId(item.id,tab)"></i>--> + <!--</nz-upload>--> + <!--<button nz-button [nzLoading]="nsuploading" (click)="onClick(tab)" [disabled]="fileList.length == 0"--> + <!--style="margin-top: 16px" *ngIf="item.id==nsdInfoId">--> + <!--{{ nsuploading ? 'Uploading' : 'Start Upload' }}--> + <!--</button>--> + <!--</span>--> + + </td> + </tr> + </tbody> + </nz-table> + </nz-spin> + <!-- <div style="margin-top:8px;"> + Loading state: + <nz-switch [(ngModel)]="isSpinning"></nz-switch> + </div> --> + + </div> + <!-- VNFList --> + <div class="list" *ngIf="tab === 'VNF'"> + <!-- <h3 class="title"> Onboard {{tabTitle}} </h3> --> + <div style="width:100%;height: 30%;margin-bottom: 1%"> + <div class="listupload"> + <nz-upload nzType="drag" [(nzFileList)]="fileListVNF" [nzBeforeUpload]="beforeUploadVNF"> + <p class="ant-upload-drag-icon"> + <i nz-icon type="inbox" class="anticon anticon-inbox"></i> + </p> + <p class="ant-upload-text">Click or drag CSAR File here</p> + <p class="ant-upload-hint"></p> + </nz-upload> + <button nz-button [nzLoading]="vnfuploading" (click)="onClick(tab)" [disabled]="fileListVNF.length == 0" + style="margin-top: 16px;margin-left: 55px;color: #FFFFFF;font-size: 13px;background-color: #3E9BFF;font-family: ArialMT;"> + {{ vnfuploading ? 'Uploading' : 'Start Upload' }} + </button> + </div> + <div class="listlin"></div> + <div class="listfile"> + <div style="color: rgba(66,84,143,1);font-family:ArialMT;padding-bottom: 15px;height: 15%"> {{"i18nTextDefine_Uploaded_files" | translate}} </div> + <div class="nouploadfile">{{"i18nTextDefine_Nofileuploading" | translate}}</div> + <div style="height:80%;overflow: auto"> + <div class="listfilebgc" *ngFor="let itemns of vnfRightList"> + <div> + <i class="anticon anticon-link"></i> + </div> + <div class="color" [ngClass]="{'progress':itemns.status == true}">{{itemns.name}}</div> + <div class="color" *ngIf="itemns.status"> + <nz-progress [nzPercent]="itemns.progress" [nzShowInfo]="false"></nz-progress> + </div> + <div class="color" *ngIf="!itemns.status"> + <span *ngIf="itemns.success == 0">{{"i18nTextDefine_File_upload_completed" | translate}}</span> + <span *ngIf="itemns.success == 1">{{"i18nTextDefine_File_upload_failed" | translate}}</span> + </div> + <div *ngIf="!itemns.status"> + <i class="anticon anticon-check-circle" *ngIf="itemns.success == 0" style="color:#7BC7F3!important;"></i> + <i class="anticon anticon-exclamation-circle" *ngIf="itemns.success == 1" style="color:#fb5c5c!important;"></i> + </div> + </div> + </div> + </div> + </div> + <nz-spin [nzSpinning]="isSpinning" style="height: 69%"> + <div class="mask" *ngIf="isSpinning"></div> + <nz-table #nzTable [nzData]="vnftableData" nzShowSizeChanger [nzFrontPagination]="true" + [nzShowQuickJumper]="true" [nzPageSizeOptions]="[5,10,15,20]" [nzTotal]='total' [(nzPageSize)]="vnfpageSize" + [(nzPageIndex)]='vnfpageIndex' [nzLoading]="loading" nzSize="middle"> + <thead (nzSortChange)="sort($event)" nzSingleSort> + <tr> + <th nzWidth="15%"> {{"i18nTextDefine_NO" | translate}} </th> + <th nzWidth="15%" nzShowSort nzSortKey="name"> {{"i18nTextDefine_Name" | translate}} </th> + <th nzWidth="15%"> {{"i18nTextDefine_Version" | translate}} </th> + <th nzWidth="15%"> {{"i18nTextDefine_OnboardingState" | translate}} </th> + <th nzWidth="15%"> {{"i18nTextDefine_OperationalState" | translate}} </th> + <th nzWidth="10%"> {{"i18nTextDefine_UsageState" | translate}} </th> + <th nzWidth="15%"> {{"i18nTextDefine_Operationbutton" | translate}} </th> + </tr> + </thead> + <tbody> + <tr *ngFor="let item of nzTable.data; let i = index; "> + <td>{{i+1}}</td> + <!--<td *ngIf="item.uuid">{{item.uuid}}</td>--> + <td *ngIf="item.vnfProductName">{{item.vnfProductName}}</td> + <td *ngIf="item.vnfProductName === null || item.vnfProductName === ''"> </td> + <td *ngIf="item.name">{{item.name}}</td> + <td *ngIf="item.vnfdVersion">{{item.vnfdVersion}}</td> + <td *ngIf="item.vnfdVersion === null || item.vnfdVersion === ''"> </td> + <td *ngIf="item.version">{{item.version}}</td> + <td>{{item.onboardingState}}</td> + <td>{{item.operationalState}}</td> + <td>{{item.usageState}}</td> + <td> + <i [ngClass]="{'cannotclick':onboardData.status == 'onboarding' && i == currentIndex}" + class="anticon anticon-upload upicon" #upload_icon (click)="updataVnfService(item.uuid,i,notificationModel)" + *ngIf="item.uuid"></i> + <i class="anticon anticon-delete" nzType="info" (click)="showConfirm(i,item.id,tab,notificationModel)" + *ngIf="item.id"></i> + <!--<span *ngIf="item.id && item.sameid == undefined">--> + <!--<nz-upload [(nzFileList)]="fileList" [nzBeforeUpload]="beforeUpload">--> + <!--<!– <button nz-button> –>--> + <!--<i class="anticon anticon-file" type="upload" (click)="onClickId(item.id,tab)"></i>--> + <!--<!– <span >upload</span> –>--> + <!--<!– </button> –>--> + + <!--</nz-upload>--> + <!--<button nz-button [nzLoading]="nsuploading" (click)="onClick(tab)" [disabled]="fileList.length == 0"--> + <!--style="margin-top: 16px;margin-left: 55px;color: #FFFFFF;font-size: 13px;background-color: #3E9BFF;font-family: ArialMT;"--> + <!--*ngIf="item.id==vnfPkgId">--> + <!--{{ nsuploading ? 'Uploading' : 'Start Upload' }}--> + <!--</button>--> + <!--</span>--> + </td> + </tr> + </tbody> + </nz-table> + </nz-spin> + + </div> + <!-- PNFList --> + <div class="list" *ngIf="tab === 'PNF'"> + <!-- <h3 class="title"> Onboard {{tabTitle}} </h3> --> + <div style="width:100%;height: 30%;margin-bottom: 1%"> + <div class="listupload"> + <nz-upload nzType="drag" [(nzFileList)]="fileListPNF" [nzBeforeUpload]="beforeUploadPNF"> + <p class="ant-upload-drag-icon"> + <i nz-icon type="inbox" class="anticon anticon-inbox"></i> + </p> + <p class="ant-upload-text">Click or drag CSAR File here</p> + <p class="ant-upload-hint"></p> + </nz-upload> + <button nz-button [nzLoading]="pnfuploading" (click)="onClick(tab)" [disabled]="fileListPNF.length == 0" + style="margin-top: 16px;margin-left: 55px;color: #FFFFFF;font-size: 13px;background-color: #3E9BFF;font-family: ArialMT;"> + {{ pnfuploading ? 'Uploading' : 'Start Upload' }} + </button> + </div> + <div class="listlin"></div> + <div class="listfile"> + <div style="color: rgba(66,84,143,1);font-family:ArialMT;padding-bottom: 15px;height: 15%"> {{"i18nTextDefine_Uploaded_files" | translate}} </div> + <div class="nouploadfile">{{"i18nTextDefine_Nofileuploading" | translate}}</div> + <div style="height:80%;overflow: auto"> + <div class="listfilebgc" *ngFor="let itemns of pnfRightList"> + <div> + <i class="anticon anticon-link"></i> + </div> + <div class="color" [ngClass]="{'progress':itemns.status == true}">{{itemns.name}}</div> + <div class="color" *ngIf="itemns.status"> + <nz-progress [nzPercent]="itemns.progress" [nzShowInfo]="false"></nz-progress> + </div> + <div class="color" *ngIf="!itemns.status"> + <span *ngIf="itemns.success == 0">{{"i18nTextDefine_File_upload_completed" | translate}}</span> + <span *ngIf="itemns.success == 1">{{"i18nTextDefine_File_upload_failed" | translate}}</span> + </div> + <div *ngIf="!itemns.status"> + <i class="anticon anticon-check-circle" *ngIf="itemns.success == 0" style="color:#7BC7F3!important;"></i> + <i class="anticon anticon-exclamation-circle" *ngIf="itemns.success == 1" style="color:#fb5c5c!important;"></i> + </div> + </div> + </div> + </div> + </div> + <nz-spin [nzSpinning]="isSpinning" style="height: 69%"> + <div class="mask" *ngIf="isSpinning"></div> + <nz-table #nzTable [nzData]="pnftableData" nzShowSizeChanger [nzFrontPagination]="true" + [nzShowQuickJumper]="true" [nzPageSizeOptions]="[5,10,15,20]" [nzTotal]='total' [(nzPageSize)]="pnfpageSize" + [(nzPageIndex)]='pnfpageIndex' [nzLoading]="loading" nzSize="middle"> + <thead (nzSortChange)="sort($event)" nzSingleSort> + <tr> + <th nzWidth="15%"> {{"i18nTextDefine_NO" | translate}} </th> + <th nzWidth="15%" nzShowSort nzSortKey="name"> {{"i18nTextDefine_Name" | translate}} </th> + <th nzWidth="15%"> {{"i18nTextDefine_Version" | translate}} </th> + <th nzWidth="15%"> {{"i18nTextDefine_OnboardingState" | translate}} </th> + <th nzWidth="10%"> {{"i18nTextDefine_UsageState" | translate}} </th> + <th nzWidth="15%"> {{"i18nTextDefine_Operationbutton" | translate}} </th> + </tr> + </thead> + <tbody> + <tr *ngFor="let item of nzTable.data; let i = index; "> + <td>{{i+1}}</td> + <td>{{item.pnfdName}}</td> + <td>{{item.pnfdVersion}}</td> + <td>{{item.pnfdOnboardingState}}</td> + <td>{{item.pnfdUsageState}}</td> + <td> + <i class="anticon anticon-delete" nzType="info" (click)="showConfirm(i,item.id,tab,notificationModel)"></i> + <!--<span *ngIf="item.id" [ngClass]="{'fileIcon':OnboardFile == 'disNone'}">--> + <!--<nz-upload [(nzFileList)]="fileList" [nzBeforeUpload]="beforeUpload">--> + <!--<i class="anticon anticon-file" type="upload" (click)="onClickId(item.id,tab)"></i>--> + <!--</nz-upload>--> + <!--<button nz-button [nzLoading]="nsuploading" (click)="onClick(tab)" [disabled]="fileList.length == 0"--> + <!--style="margin-top: 16px;margin-left: 55px;color: #FFFFFF;font-size: 13px;background-color: #3E9BFF;font-family: ArialMT;"--> + <!--*ngIf="item.id==vnfPkgId">--> + <!--{{ nsuploading ? 'Uploading' : 'Start Upload' }}--> + <!--</button>--> + <!--</span>--> + </td> + </tr> + </tbody> + </nz-table> + </nz-spin> + + </div> + </nz-tab> + <!--2019.08.14 add notification--> + <ng-template #notificationModel > + <div class="ant-notification-notice-content"> + <div class="ant-notification-notice-with-icon"> + <span class="ant-notification-notice-icon"> + <img src="{{notificationAttributes.imgPath}}" alt="{{notificationAttributes.status}}"> + </span> + <div class="ant-notification-notice-message"> + {{notificationAttributes.title}} + {{"i18nTextDefine_"+notificationAttributes.action | translate}} {{"i18nTextDefine_"+notificationAttributes.status | translate}} + </div> + <div class="ant-notification-notice-description"> + <div class="notificationlist"> + <p>{{notificationAttributes.title}} id: </p> + <span>{{ notificationAttributes.id }}</span> + </div> + </div> + <div class="close-icons">{{"i18nTextDefine_Close" | translate}}</div> + </div> + </div> + </ng-template> +</nz-tabset> + diff --git a/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.less b/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.less new file mode 100644 index 00000000..c31409c9 --- /dev/null +++ b/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.less @@ -0,0 +1,182 @@ +/* + 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: 20px; +} +.switch_btn { + position: absolute; + right: 6%; + top: 18px; + border: 1px solid #3fa8eb; + width: 8%; + border-radius: 10px; + margin-bottom: 18px; + span { + display: block; + float: left; + text-align: center; + width: 50%; + color: #3fa8eb; + font-weight: 700; + cursor: pointer; + } + span:first-child { + border-radius: 10px 0 0 10px; + } + span:last-child { + border-radius: 0 10px 10px 0; + } + span.left_b { + border-left: 1px solid #3fa8eb; + } + span.active { + color: #fff; + background: #3fa8eb; + } +} + +.list { + // background-color: #fff; + border-radius: 5px; + // padding: 10px; + .listupload { + width: 22%; + vertical-align: top; + display: inline-block; + margin-left: 13%; + } + .listlin { + vertical-align: top; + display: inline-block; + width: 1%; + margin-left: 10%; + height: 177px; + margin-bottom: 30px; + border-right: 2px solid #EEEEEE; + } + .listfile { + width: 43%; + height: 100%; + vertical-align: top; + display: inline-block; + margin-left: 10%; + .nouploadfile{ + height: 80%; + width: 100%; + text-align: center; + font-size: 22px; + margin-top: 5%; + } + .listfilebgc { + background-color: #fff; + border-bottom: 8px solid #F7F8FC; + } + .listfilebgc { + background-color: #fff; + height: 30px; + border-radius: 2px; + line-height: 2; + color: #42548F; + border-bottom: 4px solid #F7F8FC; + >div { + float: left; + } + :first-child { + width: 6%; + margin-left: 5px; + } + :nth-child(2){ + width:20%; + } + :nth-child(3){ + width: 60%; + text-align: center; + } + :nth-child(4){ + padding-left: 4%; + } + .color { + color:rgba(66,84,143,1); + span{ + color:rgba(66,84,143,0.7); + } + } + .progress{ + color:rgba(66,84,143,0.7); + } + } + } + nz-table { + tbody { + td { + span.onboarding { + font-size: 12px; + color: #147dc2; + } + span.onboarded { + font-size: 14px; + color: #147dc2; + } + span.updating { + font-size: 12px; + color: blue; + } + span.deleting { + font-size: 12px; + color: red; + } + span.invalid { + font-size: 14px; + color: purple; + } + i.anticon { + cursor: pointer; + font-size: 18px; + padding: 2px; + &:hover{ + color: #147dc2; + } + } + .cannotclick { + pointer-events: none; + color: #aaa; + opacity: 0.6; + } + .fileIcon{ + display: none; + } + } + } + } +} +.mask { + top: 0; + left: 0; + position: fixed; + width: 100%; + height: 100%; + opacity: 0.1; + background: black; + z-index: 1049; +}
\ No newline at end of file diff --git a/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.spec.ts b/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.spec.ts new file mode 100644 index 00000000..0e49f656 --- /dev/null +++ b/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OnboardVnfVmComponent } from './onboard-vnf-vm.component'; + +describe('OnboardVnfVmComponent', () => { + let component: OnboardVnfVmComponent; + let fixture: ComponentFixture<OnboardVnfVmComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ OnboardVnfVmComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(OnboardVnfVmComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.ts b/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.ts new file mode 100644 index 00000000..4899aed8 --- /dev/null +++ b/usecaseui-portal/src/app/views/services/onboard-vnf-vm/onboard-vnf-vm.component.ts @@ -0,0 +1,668 @@ +/* + 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. +*/ +import { HttpClient, HttpRequest, HttpResponse } from '@angular/common/http'; +import { Component, OnInit, HostBinding, TemplateRef } from '@angular/core'; +import { NzNotificationService } from 'ng-zorro-antd'; +// import { MyhttpService } from '../../myhttp.service'; +import { onboardService } from '../../../core/services/onboard.service'; +import { slideToRight } from '../../../animates'; +import { NzMessageService, UploadFile, NzModalRef, NzModalService } from 'ng-zorro-antd'; +import { filter } from 'rxjs/operators'; +import { Title } from '@angular/platform-browser'; + +@Component({ + selector: 'app-onboard-vnf-vm', + templateUrl: './onboard-vnf-vm.component.html', + styleUrls: ['./onboard-vnf-vm.component.less'], + animations: [slideToRight] +}) +export class OnboardVnfVmComponent implements OnInit { + @HostBinding('@routerAnimate') routerAnimateState; + + // delete Modal + confirmModal: NzModalRef; + nsdInfoId = ''; + vnfPkgId = ''; + pnfdInfoId = ''; + tabTitle = "NS"; + nsuploading = false; + vnfuploading = false; + pnfloading = false; + fileList: UploadFile[] = []; + fileListNS: UploadFile[] = []; + fileListVNF: UploadFile[] = []; + fileListPNF: UploadFile[] = []; + // onboard initial value + status = "Onboard Available"; + jobId = ''; + //url + url = { + // line up + ns: '/api/nsd/v1/ns_descriptors/*_*/nsd_content', + vnf: '/api/vnfpkgm/v1/vnf_packages/*_*/package_content', + pnf: '/api/nsd/v1/pnf_descriptors/*_*/pnfd_content' + // line local + //ns: 'https://jsonplaceholder.typicode.com/posts/', + //vnf: 'https://jsonplaceholder.typicode.com/posts/', + //pnf: 'https://jsonplaceholder.typicode.com/posts/', + }; + constructor( + private myhttp: onboardService, + private http: HttpClient, + private msg: NzMessageService, + private titleService: Title, + private modal: NzModalService, + private modalService: NzModalService, + private notification: NzNotificationService + ) { } + //default Call ns data by default + ngOnInit() { + this.getTableData(); + } + + //Tabular data + nstableData: any; + vnftableData: any; + pnftableData: any; + nssdcData: any; + nsvfcData: any; + + vnfsdcData: any; + vnfvfcData: any; + nspageIndex = 1; + nspageSize = 10; + vnfpageIndex = 1; + vnfpageSize = 10; + pnfpageIndex = 1; + pnfpageSize = 10; + total; + nsloading = false; + sortName = null; + sortValue = null; + tabs = ['NS', 'VNF', 'PNF']; + isSpinning = false; + + //2019.08.14 add + notificationAttributes = { + "title": this.tabs[0], + "imgPath": "../../../../assets/images/execute-inproess.png", + "action": "OnboardingState", + "status": "InProgress", + "id": null + }; + notificationModelShow(template: TemplateRef<{}>): void { + this.notification.template(template); + } + notificationSuccess(notificationModel) { + this.notificationAttributes.imgPath = "../../../../assets/images/execute-success.png"; + this.notificationAttributes.status = "Success"; + this.notificationModelShow(notificationModel); + } + notificationFailed(notificationModel) { + this.notificationAttributes.imgPath = "../../../../assets/images/execute-faild.png"; + this.notificationAttributes.status = "Failed"; + this.notificationModelShow(notificationModel); + } + // Handling tab switching request data + handleTabChange(tab) { + this.tabTitle = tab; + switch (tab) { + case 'NS': + this.nstableData = []; + this.getTableData(); + this.fileList = []; //Empty uploaded files when switching + break + case 'VNF': + this.vnftableData = []; + this.getTableVnfData() + this.fileList = []; + break + case 'PNF': + this.pnftableData = []; + this.getTablePnfData() + this.fileList = []; + break + } + } + + + //before put create--Drag and drop files to the page before uploading + requestBody = { + "userDefinedData": { + "additionalProp1": "", + "additionalProp2": "", + "additionalProp3": "" + } + } + + //NS/VNF List add file + beforeUpload = (file: UploadFile): boolean => { + this.fileList.push(file); + return false; + } + + // ns beforeUpload + beforeUploadNS = (file: UploadFile): boolean => { + this.fileListNS.push(file); + this.myhttp.getCreatensData("createNetworkServiceData", this.requestBody)//on-line + // this.myhttp.getCreatensData("creatensDataNS") //local + .subscribe((data) => { + this.nsdInfoId = data["id"]; + }, (err) => { + console.log(err); + }) + return false; + } + + //vnf beforeUpload + beforeUploadVNF = (file: UploadFile): boolean => { + this.fileListVNF.push(file); + this.myhttp.getCreatensData("createVnfData", this.requestBody)//on-line + // this.myhttp.getCreatensData("creatensDataVNF") //local + .subscribe((data) => { + this.vnfPkgId = data["id"]; + }, (err) => { + console.log(err); + }) + return false; + } + + // //pnf eforeUpload + beforeUploadPNF = (file: UploadFile): boolean => { + this.fileListPNF.push(file); + this.myhttp.getCreatensData("createPnfData", this.requestBody) //on-line + // this.myhttp.getCreatensData("creatensDataPNF") //local + .subscribe((data) => { + this.pnfdInfoId = data["id"]; + }, (err) => { + console.log(err); + }) + return false; + } + + //Get list list id + onClickId(id, tab) { + switch (tab) { + case 'NS': + this.nsdInfoId = id; + break + case 'VNF': + this.vnfPkgId = id; + break + case 'PNF': + this.pnfdInfoId = id; + break + } + } + + //Drag and drop and click the upload button + onClick(tab) { + switch (tab) { + case 'NS': + // this.handleUpload('/api/nsd/v1/ns_descriptors/'+this.nsdInfoId+'/nsd_content',tab); + this.handleUpload(this.url.ns.replace("*_*", this.nsdInfoId), tab); + this.getTableData(); + break + case 'VNF': + // this.handleUpload('/api/vnfpkgm/v1/vnf_packages/'+this.vnfPkgId+'/package_content',tab); + this.handleUpload(this.url.vnf.replace("*_*", this.vnfPkgId), tab); + this.getTableVnfData() + break + case 'PNF': + // this.handleUpload('/api/nsd/v1/pnf_descriptors/'+this.pnfdInfoId+'/pnfd_content',tab); + this.handleUpload(this.url.pnf.replace("*_*", this.pnfdInfoId), tab); + this.getTablePnfData(); + break + } + } + + nsRightList = []; + nsNum = 0; + vnfRightList = []; + vnfNum = 0; + pnfRightList = []; + pnfNum = 0; + //put Upload Upload + handleUpload(url, tab): void { + const formData = new FormData(); + // tslint:disable-next-line:no-any + switch (tab) { + case "NS": + this.fileListNS.forEach((file: any) => { + formData.append('file', file); + }); + this.nsuploading = true; + let lastNs = this.fileListNS[this.fileListNS.length - 1]; + let nsfile = { + name: lastNs.name, + uid: lastNs.uid, + progress: 0, + status: true, + success: 0 + }; + this.nsNum += 1; + this.nsRightList.push(nsfile); + let requeryNs = (nsfile) => { + setTimeout(() => { + nsfile.progress += 2; + if (nsfile.progress < 100) { + requeryNs(nsfile) + } else { + nsfile.progress = 100; + nsfile.status = false; + } + }, 100) + }; + requeryNs(nsfile); + break + case "VNF": + this.fileListVNF.forEach((file: any) => { + formData.append('file', file); + }); + this.vnfuploading = true; + let lastVnf = this.fileListVNF[this.fileListVNF.length - 1]; + let vnffile = { + name: lastVnf.name, + uid: lastVnf.uid, + progress: 0, + status: true, + success: 0 + }; + this.vnfNum += 1; + this.vnfRightList.push(vnffile); + let requeryVnf = (vnffile) => { + setTimeout(() => { + vnffile.progress += 2; + if (vnffile.progress < 100) { + requeryVnf(vnffile) + } else { + vnffile.progress = 100; + vnffile.status = false; + } + }, 100) + }; + requeryVnf(vnffile); + break + case "PNF": + this.fileListPNF.forEach((file: any) => { + formData.append('file', file); + }); + this.pnfloading = true; + let lastPnf = this.fileListPNF[this.fileListPNF.length - 1]; + let pnffile = { + name: lastPnf.name, + uid: lastPnf.uid, + progress: 0, + status: true, + success: 0 + }; + this.pnfNum += 1; + this.pnfRightList.push(pnffile); + let requeryPnf = (pnffile) => { + setTimeout(() => { + pnffile.progress += 2; + if (pnffile.progress < 100) { + requeryPnf(pnffile) + } else { + pnffile.progress = 100; + pnffile.status = false; + } + }, 100) + }; + requeryPnf(pnffile); + break + } + // line PUT + const req = new HttpRequest('PUT', url, formData, { + reportProgress: true, + withCredentials: true + }); + //Upload pre-empty array + this.fileList = []; + this.fileListNS = []; + this.fileListVNF = []; + this.fileListPNF = []; + this.http.request(req) + .pipe(filter(e => e instanceof HttpResponse)) + .subscribe( + (event: {}) => { + if (tab == "NS") { + this.nsRightList[this.nsNum - 1].progress = 100; + this.nsRightList[this.nsNum - 1].status = false; + this.nsRightList[this.nsNum - 1].success = 0; + } + if (tab == "VNF") { + this.vnfRightList[this.vnfNum - 1].progress = 100; + this.vnfRightList[this.vnfNum - 1].status = false; + this.vnfRightList[this.vnfNum - 1].success = 0; + } + if (tab == "PNF") { + this.pnfRightList[this.pnfNum - 1].progress = 100; + this.pnfRightList[this.pnfNum - 1].status = false; + this.pnfRightList[this.pnfNum - 1].success = 0; + } + this.changeUploadingSta(tab); + this.msg.success('upload successfully.'); + }, + err => { + if (tab == "NS") { + this.nsRightList[this.nsNum - 1].progress = 100; + this.nsRightList[this.nsNum - 1].status = false; + this.nsRightList[this.nsNum - 1].success = 1; + } + if (tab == "VNF") { + this.vnfRightList[this.vnfNum - 1].progress = 100; + this.vnfRightList[this.vnfNum - 1].status = false; + this.vnfRightList[this.vnfNum - 1].success = 1; + } + if (tab == "PNF") { + this.pnfRightList[this.pnfNum - 1].progress = 100; + this.pnfRightList[this.pnfNum - 1].status = false; + this.pnfRightList[this.pnfNum - 1].success = 1; + } + this.changeUploadingSta(tab); + this.msg.error('upload failed.'); + } + ); + } + + // Control the status of uploading + changeUploadingSta(tab) { + switch (tab) { + case "NS": + this.nsuploading = false; + break + case "VNF": + this.vnfuploading = false; + break + case "PNF": + this.pnfloading = false; + } + } + + //---------------------------------------------------------------------------------------------- + + // Get the NS list + getTableData() { + this.isSpinning = true; + //ns vfc lists + this.myhttp.getOnboardTableData() + .subscribe((data) => { + this.nsvfcData = data; + this.nstableData = this.nsvfcData; + //ns sdc list + this.myhttp.getSDC_NSTableData() + .subscribe((data) => { + this.isSpinning = false; //loading hide + this.nssdcData = data; + this.nsvfcData.map((nsvfc) => { nsvfc.sameid = this.nssdcData.find((nssdc) => { return nsvfc.id == nssdc.uuid }) && nsvfc.id; return nsvfc; }); + let sameData = this.nssdcData.filter((nssdc) => { return !this.nsvfcData.find((nsvfc) => { return nsvfc.id == nssdc.uuid }) }); + this.nstableData = this.nstableData.concat(sameData); + }, (err) => { + console.log(err); + this.isSpinning = false; + }) + }, (err) => { + console.log(err); + this.isSpinning = false; + }) + + } + + // Get the vnf list + getTableVnfData() { + this.isSpinning = true; + //vnf vfc lists + this.myhttp.getOnboardTableVnfData() + .subscribe((data) => { + this.vnfvfcData = data; + this.vnftableData = this.vnfvfcData; + //vnf sdc lists + this.myhttp.getSDC_VNFTableData() + .subscribe((data) => { + this.isSpinning = false; //loading hide + this.vnfsdcData = data; + this.vnfvfcData.map((vnfvfc) => { vnfvfc.sameid = this.vnfsdcData.find((nssdc) => { return vnfvfc.id == nssdc.uuid }) && vnfvfc.id; return vnfvfc; }); + let sameData = this.vnfsdcData.filter((vnfsdc) => { return !this.vnfvfcData.find((vnfvfc) => { return vnfvfc.id == vnfsdc.uuid }) }); + this.vnftableData = this.vnftableData.concat(sameData); + }, (err) => { + console.log(err); + }) + + }, (err) => { + console.log(err); + }) + } + + // Get pnf list + getTablePnfData() { + this.isSpinning = true; + this.myhttp.getOnboardTablePnfData() + .subscribe((data) => { + this.pnftableData = data; + this.isSpinning = false; //loading hide + }, (err) => { + console.log(err); + }) + } + + //----------------------------------------------------------------------------------- + /* onboard */ + //Successful frame + success(tab): void { + const modal = this.modalService.success({ + nzTitle: 'This is an success message', + nzContent: 'Package Onboard Completed.' + }); + switch (tab) { + case "NS": + this.getTableData(); + break + case "VNF": + this.getTableVnfData(); + break + } + } + + //Failure frame + error(): void { + this.modalService.error({ + nzTitle: 'This is an error message', + nzContent: 'Package Onboard Failed!' + }); + } + + //onboard status + onboardData = { + status: "onboard", + progress: 0, + } + currentIndex = 0; + // ns onboard Upload button + updataNsService(id, index, notificationModel) { + this.currentIndex = index; + this.onboardData.status = "onboarding"; //Disabled + this.onboardData.progress = 0; + let requestBody = { + "csarId": id + }; + this.notificationAttributes = { + "title": this.tabs[0], + "imgPath": "../../../../assets/images/execute-inproess.png", + "action": "OnboardingState", + "status": "InProgress", + "id": id + }; + this.notificationModelShow(notificationModel); + this.myhttp.getNsonboard(requestBody) + .subscribe((data) => { + if (data.status == "failed") { + this.onboardData.status = "Failed"; + this.notificationFailed(notificationModel); + this.error(); + return false + } else if (data.status == "success") { + this.success("NS"); + this.onboardData.status = "onboarded"; + this.notificationSuccess(notificationModel); + } + }, (err) => { + console.log(err); + }) + } + + // vnf onboard Upload button + updataVnfService(id, index, notificationModel) { + this.currentIndex = index; + this.onboardData.status = "onboarding"; //Disabled button + this.onboardData.progress = 0; + + + let requestBody = { + "csarId": id + }; + this.notificationAttributes = { + "title": this.tabs[1], + "imgPath": "../../../../assets/images/execute-inproess.png", + "action": "OnboardingState", + "status": "InProgress", + "id": id + }; + this.notificationModelShow(notificationModel); + this.myhttp.getVnfonboard(requestBody) + .subscribe((data) => { + this.jobId = data.jobId; + this.queryProgress(this.jobId, 0, notificationModel); //vnf Need to query progress interface + }, (err) => { + console.log(err); + }) + } + + //Progress Progress inquiry + queryProgress(jobId, responseId, notificationModel) { + let mypromise = new Promise((res) => { + this.myhttp.getProgress(jobId, responseId) + .subscribe((data) => { + if (data.responseDescriptor == null || data.responseDescriptor == "null" || data.responseDescriptor.progress == undefined || data.responseDescriptor.progress == null) { + this.onboardData.status = "onboarding"; + setTimeout(() => { + this.queryProgress(this.jobId, 0, notificationModel); + }, 10000) + return false + } + if (data.responseDescriptor.progress > 100) { + this.onboardData.status = "Failed"; + this.notificationFailed(notificationModel); + this.error(); + return false + } + if (data.responseDescriptor.progress < 100) { + this.onboardData.status = "onboarding"; + setTimeout(() => { + this.queryProgress(this.jobId, 0, notificationModel); + }, 5000) + } else if (data.responseDescriptor.progress == 100) { + res(data); + this.success("VNF"); + this.onboardData.status = "onboarded"; + this.notificationSuccess(notificationModel); + } + return false + }) + }) + return mypromise; + } + + //-------------------------------------------------------------------------------- + /* delete button */ + showConfirm(index, pkgid, tab, notificationModel): void { + this.notificationAttributes = { + "title": this.tabs[0], + "imgPath": "../../../../assets/images/execute-inproess.png", + "action": "OnboardingState", + "status": "InProgress", + "id": pkgid + }; + this.confirmModal = this.modal.confirm({ + nzTitle: 'Do you Want to delete these items?', + nzContent: 'Do you Want to delete these items?', + nzOkText: 'Yes', + nzCancelText: 'No', + nzOnOk: () => new Promise((resolve, reject) => { + switch (tab) { + case 'NS': + this.notificationAttributes.title = this.tabs[0]; + this.notificationModelShow(notificationModel); + this.deleteNsService(index, pkgid, notificationModel); + setTimeout(Math.random() > 0.5 ? resolve : reject, 2000); + break + case 'VNF': + this.notificationAttributes.title = this.tabs[1]; + this.notificationModelShow(notificationModel); + this.deleteVnfService(index, pkgid, notificationModel); + setTimeout(Math.random() > 0.5 ? resolve : reject, 2000); + break + case 'PNF': + this.notificationAttributes.title = this.tabs[2]; + this.notificationModelShow(notificationModel); + this.deletePnfService(index, pkgid, notificationModel); + setTimeout(Math.random() > 0.5 ? resolve : reject, 2000); + break + } + }).catch(() => console.log('Oops errors!')) + }); + } + + //delete nsItem + deleteNsService(index, pkgid, notificationModel) { + this.myhttp.deleteNsIdData(pkgid) + .subscribe((data) => { + this.notificationSuccess(notificationModel); + //refresh list after successful deletion + this.getTableData(); + }, (err) => { + console.log(err); + this.notificationFailed(notificationModel); + }) + } + + //delete vnfItem + deleteVnfService(index, pkgid, notificationModel) { + this.myhttp.deleteVnfIdData(pkgid) + .subscribe((data) => { + this.notificationSuccess(notificationModel); + //refresh list after successful deletion + this.getTableVnfData() + }, (err) => { + console.log(err); + this.notificationFailed(notificationModel); + }) + } + + //delete PnfItem + deletePnfService(index, pkgid, notificationModel) { + this.myhttp.deletePnfIdData(pkgid) + .subscribe((data) => { + //refresh list after successful deletion + this.notificationSuccess(notificationModel); + this.getTablePnfData() + }, (err) => { + console.log(err); + this.notificationFailed(notificationModel); + }) + } + +} |