diff options
7 files changed, 175 insertions, 97 deletions
diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..48e341a0 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3 @@ +{ + "lockfileVersion": 1 +} diff --git a/usecaseui-portal/src/app/mock/json/slicing_task_auditInfo.json b/usecaseui-portal/src/app/mock/json/slicing_task_auditInfo.json index 466d6ee4..012a802c 100644 --- a/usecaseui-portal/src/app/mock/json/slicing_task_auditInfo.json +++ b/usecaseui-portal/src/app/mock/json/slicing_task_auditInfo.json @@ -82,6 +82,7 @@ "cn_area_traffic_cap_dl": "300",
"cn_area_traffic_cap_ul": "300",
"cn_script_name":"test_cn_01",
+ "cn_max_number_of_pud_session":"10000",
"cn_overalluser_density":"test_cn_overalluser_density_01",
"cn_enableNSSISelection":true,
"cn_Endpoint":[
diff --git a/usecaseui-portal/src/app/shared/utils/utils.ts b/usecaseui-portal/src/app/shared/utils/utils.ts index 63d3e3b7..ad6a2f10 100644 --- a/usecaseui-portal/src/app/shared/utils/utils.ts +++ b/usecaseui-portal/src/app/shared/utils/utils.ts @@ -73,4 +73,53 @@ export class Util { validateRulesShow[index] = false; } } + isInteger (value: any) : boolean{ + // for common string and undefined, eg '123a3' + if (isNaN(value)) { + return false; + } else if (isNaN(parseInt(value))) { + return false; + } else if (Number(value) >= 0 && Number(value)%1 !== 0){ + return false; + } else { + return true; + } + } + judgeType (a: any) : string { + return Object.prototype.toString.call(a) + } + isEmpty (a: any): boolean { + const type = this.judgeType(a); + if (type === 'object Null' || type === '[object undefined]' || a === false || a === '') { + return true; + } else { + return false; + } + } + deepCheck (target: any) : boolean{ + //used to verify that each item is not '' or undefined in a object or an array + let type = this.judgeType(target); + if (type === '[object Array]') { + for (let i = 0; i < target.length; i++) { + if (!this.deepCheck(target[i])) { + return false; + } + } + } else if (type === '[object Object]') { + for (const prop in target) { + if (target.hasOwnProperty(prop)) { + if (!this.deepCheck(target[prop])) { + return false; + } + } + } + } else { + if (this.isEmpty(target)) { // '', undefined, null, false + return false; + } else { + return true; + } + } + return true; + } }
\ No newline at end of file diff --git a/usecaseui-portal/src/app/views/services/slicing-management/slicing-task-management/slicing-task-model/subnet-params-model/subnet-params-model.component.html b/usecaseui-portal/src/app/views/services/slicing-management/slicing-task-management/slicing-task-model/subnet-params-model/subnet-params-model.component.html index c4f377f1..93e6f485 100644 --- a/usecaseui-portal/src/app/views/services/slicing-management/slicing-task-management/slicing-task-model/subnet-params-model/subnet-params-model.component.html +++ b/usecaseui-portal/src/app/views/services/slicing-management/slicing-task-management/slicing-task-model/subnet-params-model/subnet-params-model.component.html @@ -3,8 +3,8 @@ <div class="subnet_params_container"> <form nz-form *ngIf="title === 'Tn'"> <nz-form-item *ngFor="let item of transferFormItems"> - <nz-form-label [nzSpan]="7" nzRequired [nzFor]="item.key"> - {{ item.title }} + <nz-form-label [nzSpan]="7" [nzRequired]="item.required" [nzFor]="item.key" [ngStyle]="labelStyle(item.required)"> + {{item.title}} </nz-form-label> <nz-form-control [nzSpan]="12"> <input nz-input @@ -13,19 +13,21 @@ [id]="item.key" [readOnly]="item.title === 'S-NSSAI'" [disabled]="item.title === 'S-NSSAI'" + [placeholder]="inputHolder(item.title)" /> + <div class="validation_alert" *ngIf="item.required">{{Util.isEmpty(formData[item.key])? 'can not be empty!':' '}}</div> </nz-form-control> </nz-form-item> </form> <form nz-form *ngIf="title === 'An' || title === 'Cn'"> <nz-form-item *ngFor="let item of coreFormItems"> - <nz-form-label [nzSpan]="(item.key === 'an_coverage_area_ta_list' || item.title === 'Endpoint')?7:13" nzRequired *ngIf=" item.title !== 'Endpoint' || EndpointEnable "> + <nz-form-label [nzSpan]="(item.key === 'an_coverage_area_ta_list' || item.title === 'Endpoint')?7:13" [nzRequired]="item.required" *ngIf=" item.title !== 'Endpoint' || EndpointEnable " [ngStyle]="labelStyle(item.required)"> {{ item.title }} </nz-form-label> <nz-form-control [nzSpan]="item.title === 'Endpoint'?14:8" *ngIf="item.key !== 'an_coverage_area_ta_list'"> <input nz-input [id]="item.key" [name]="item.key" [(ngModel)]="formData[item.key]" [readOnly]="item.title === 'S-NSSAI'" [disabled]="item.title === 'S-NSSAI'" - *ngIf=" item.title !== 'Resource Sharing Level' && item.title !== 'Mobility' && item.title !== 'Endpoint' " /> + *ngIf=" item.title !== 'Resource Sharing Level' && item.title !== 'Mobility' && item.title !== 'Endpoint' " [placeholder]="inputHolder(item.title)"/> <nz-radio-group [name]="item.key" [(ngModel)]="formData[item.key]" *ngIf="item.title === 'Resource Sharing Level'"> <label nz-radio [nzValue]="option.key" *ngFor="let option of item.options"> @@ -36,14 +38,13 @@ <nz-option [nzValue]="option.key" [nzLabel]="option.title" *ngFor="let option of item.options"> </nz-option> </nz-select> - <div class="validation_alert">{{formData[item.key] === ''? 'can not be empty!':' '}}</div> + <div class="validation_alert" *ngIf="item.required">{{Util.isEmpty(formData[item.key])? 'can not be empty!':' '}}</div> <!-- 2020.08.17 Add 3 parameters for Endpoint--> <!-- Comment: The following code--> <nz-input-group *ngIf="item.title === 'Endpoint' && EndpointEnable"> <div *ngFor="let option of item.options;let i=index"> <div class="endpoint_input"> <input nz-input - *ngIf="option.title !== 'nexthop_info'" [id]="option.key" [name]="option.key" [title]="EndpointInputs[i][option.key]" @@ -53,18 +54,8 @@ style="width:32%;margin-right:1%" /> <div class="end_alert_ip" *ngIf="option.title === 'ip_address'">{{validateEndPoint(option.title, EndpointInputs[i][option.key])}}</div> <div class="end_alert_logical" *ngIf="option.title === 'logical_link'">{{validateEndPoint(option.title, EndpointInputs[i][option.key])}}</div> + <div class="end_alert_nexthop" *ngIf="option.title === 'nexthop_info'">{{validateEndPoint(option.title, EndpointInputs[i][option.key])}}</div> </div> - <nz-select - *ngIf="option.title === 'nexthop_info'" - [name]="option.key" - [title]="EndpointInputs[i][option.key]" - [(ngModel)]="EndpointInputs[i][option.key]" style="width:34%;"> - <nz-option - *ngFor="let infoOption of NexthopInfoOptions" - [nzValue]="infoOption.key" - [nzLabel]="infoOption.title" - ></nz-option> - </nz-select> </div> </nz-input-group> <!-- Comment: Above code--> diff --git a/usecaseui-portal/src/app/views/services/slicing-management/slicing-task-management/slicing-task-model/subnet-params-model/subnet-params-model.component.less b/usecaseui-portal/src/app/views/services/slicing-management/slicing-task-management/slicing-task-model/subnet-params-model/subnet-params-model.component.less index d8cad111..335b377c 100644 --- a/usecaseui-portal/src/app/views/services/slicing-management/slicing-task-management/slicing-task-model/subnet-params-model/subnet-params-model.component.less +++ b/usecaseui-portal/src/app/views/services/slicing-management/slicing-task-management/slicing-task-model/subnet-params-model/subnet-params-model.component.less @@ -42,4 +42,10 @@ top: 0;
margin: 30px 0 0 126px;
}
+ .end_alert_nexthop {
+ position: absolute;
+ color: red;
+ top: 0;
+ margin: 30px 0 0 246px;
+ }
}
\ No newline at end of file diff --git a/usecaseui-portal/src/app/views/services/slicing-management/slicing-task-management/slicing-task-model/subnet-params-model/subnet-params-model.component.ts b/usecaseui-portal/src/app/views/services/slicing-management/slicing-task-management/slicing-task-model/subnet-params-model/subnet-params-model.component.ts index 145a03e7..fb1e5b55 100644 --- a/usecaseui-portal/src/app/views/services/slicing-management/slicing-task-management/slicing-task-model/subnet-params-model/subnet-params-model.component.ts +++ b/usecaseui-portal/src/app/views/services/slicing-management/slicing-task-management/slicing-task-model/subnet-params-model/subnet-params-model.component.ts @@ -1,6 +1,8 @@ import { Component, OnInit, Input, Output, EventEmitter, ElementRef } from '@angular/core'; import { TRANSFRER_FORM_ITEMS, CORE_FORM_ITEMS, ADDRESS , NexthopInfo_Options } from '@src/constants/constants'; import { NzMessageService } from "ng-zorro-antd"; +import { stringify } from '@angular/core/src/util'; +import { Util } from '../../../../../../shared/utils/utils'; @Component({ selector: 'app-subnet-params-model', @@ -28,6 +30,7 @@ export class SubnetParamsModelComponent implements OnInit { constructor( private message: NzMessageService, + private Util: Util ) { } @@ -62,7 +65,7 @@ export class SubnetParamsModelComponent implements OnInit { } } validateEndPoint (key: string, value: any): string { - if (value === '') { + if (this.Util.isEmpty(value)) { return 'can not be empty'; } if (key === 'ip_address') { @@ -72,7 +75,7 @@ export class SubnetParamsModelComponent implements OnInit { return ''; } } else if (key === 'logical_link') { - if (!this.isInteger(value)){ + if (!this.Util.isInteger(value)){ return 'integer only' } else { return '' @@ -182,6 +185,7 @@ export class SubnetParamsModelComponent implements OnInit { this.cancel.emit(this.showModel) } + // prompt text for each item of area_list checkArea (area: any) { if (area.every((item) => {return item.selected === ''})) { return 'empty'; @@ -192,55 +196,22 @@ export class SubnetParamsModelComponent implements OnInit { return ''; } - judgeType (a) { - return Object.prototype.toString.call(a) - } - - // used to verify that each item is not empty in a object - deepCheck (target) { - let type = this.judgeType(target); - if (type === '[object Array]') { - for (let i = 0; i < target.length; i++) { - if (!this.deepCheck(target[i])) { - return false; - } - } - } else if (type === '[object Object]') { - for (const prop in target) { - if (target.hasOwnProperty(prop)) { // special handling for address - if (prop === 'an_coverage_area_ta_list' || prop ==='cn_coverage_area_ta_list') { - return target[prop].every((item) => {return this.deepCheck(item.split(';'))}); - } else if (!this.deepCheck(target[prop])) { - return false; - } + // special handling for address + areaCheckBeforeSubmit (target: object) : Boolean{ + for (const prop in target) { + if (target.hasOwnProperty(prop)) { + if (prop === 'an_coverage_area_ta_list' || prop ==='cn_coverage_area_ta_list') { + // if the vlaue is "shanghai;shanghai;", the input is incomplete + return target[prop].every((item) => {return this.Util.deepCheck(item.split(';'))}); } } - } else { - if (!target && target!==0) { - return false; - } else { - return true; - } } return true; } - isInteger (value: any) { - // for common string and undefined, eg '123a3' - if (isNaN(value)) { - return false; - } else if (isNaN(parseInt(value))) { - return false; - } else if (Number(value) >= 0 && Number(value)%1 !== 0){ - return false; - } else { - return true; - } - } - - endCheckBeforeSubmit () { + endCheckBeforeSubmit () : Array<any>{ // check params of Endpoint - let result = [true, '']; + let result: Array<any> = [true, '']; let formatedEndpoint = {}; this.EndpointInputs.forEach((item) => { formatedEndpoint[Object.keys(item)[0]] = item[Object.keys(item)[0]]; @@ -252,7 +223,7 @@ export class SubnetParamsModelComponent implements OnInit { result = [false, 'Illegal IpAddress'] } } else if (prop === 'an_logical_link') { - if (!this.isInteger(formatedEndpoint[prop])) { + if (!this.Util.isInteger(formatedEndpoint[prop])) { result = [false, 'LogicalID can only be an integer'] } } @@ -264,7 +235,7 @@ export class SubnetParamsModelComponent implements OnInit { result = [false, 'Illegal IpAddress'] } } else if (prop === 'cn_logical_link') { - if (!this.isInteger(formatedEndpoint[prop])) { + if (!this.Util.isInteger(formatedEndpoint[prop])) { result = [false, 'LogicalID can only be an integer'] } } @@ -273,6 +244,25 @@ export class SubnetParamsModelComponent implements OnInit { return result; } + inputHolder (title: string): string { + const titleArr = title.split(' ') + if (titleArr.length > 1) { + return titleArr.slice(0, 2).join(''); + } else { + return title; + } + } + + labelStyle (required: boolean) : object{ + let style; + if (!required) { + style = {'margin-left': '18px', 'margin-right': '-18px'}; + } else { + style = {} + } + return style; + } + handleOk(): void { // Verify that items of EndPoint is correct let endCheckResult = this.endCheckBeforeSubmit() @@ -294,8 +284,8 @@ export class SubnetParamsModelComponent implements OnInit { } else { params = {...this.formData}; } - // Verify that each item is not empty - if (this.deepCheck(params)) { + // Verify that each item is not empty, include special handeling of area_list + if (this.Util.deepCheck(params) && this.areaCheckBeforeSubmit(params)) { this.paramsDataChange.emit(params); this.handleCancel(); } else { diff --git a/usecaseui-portal/src/constants/constants.ts b/usecaseui-portal/src/constants/constants.ts index 2d8abd9f..9e732336 100644 --- a/usecaseui-portal/src/constants/constants.ts +++ b/usecaseui-portal/src/constants/constants.ts @@ -117,35 +117,37 @@ export const BUSINESS_REQUIREMENT = [ export const TRANSFRER_FORM_ITEMS = [
{
title: 'S-NSSAI',
- key: 'tn_service_snssai'
+ key: 'tn_service_snssai',
+ required: true
},
{
title: 'Latency (ms)',
- key: 'tn_latency'
+ key: 'tn_latency',
+ required: true
},
{
title: 'Jitter',
- key: 'tn_jitter'
+ key: 'tn_jitter',
+ required: false,
},
{
title: 'MaxBandwidth',
- key: 'tn_bandwidth'
+ key: 'tn_bandwidth',
+ required: true
},
- {
- title: 'Script Name',
- key: 'tn_script_name'
- },
]
export const CORE_FORM_ITEMS = {
"An": [
{
title: 'S-NSSAI',
- key: 'an_service_snssai'
+ key: 'an_service_snssai',
+ required: true
},
{
title: 'Resource Sharing Level',
key: 'an_resource_sharing_level',
+ required: true,
options: [
{
title: 'Shared',
@@ -160,6 +162,7 @@ export const CORE_FORM_ITEMS = { {
title: 'Mobility',
key: 'an_ue_mobility_level',
+ required: true,
options: [
{
title: 'Stationary',
@@ -181,43 +184,58 @@ export const CORE_FORM_ITEMS = { },
{
title: 'Latency (ms)',
- key: 'an_latency'
+ key: 'an_latency',
+ required: true
+ },
+ {
+ title: 'Max Number of PUD Session',
+ key: 'an_max_number_of_pud_session',
+ required: true
},
{
title: 'Max Number of UEs',
- key: 'an_max_number_of_ues'
+ key: 'an_max_number_of_ues',
+ required: true
},
{
title: 'Activity Factor (%)',
- key: 'an_activity_factor'
+ key: 'an_activity_factor',
+ required: true
},
{
title: 'User Downlink Experience Rate(Mbps)',
- key: 'an_exp_data_rate_dl'
+ key: 'an_exp_data_rate_dl',
+ required: true
},
{
title: 'User Uplink Experience Rate(Mbps)',
- key: 'an_exp_data_rate_ul'
+ key: 'an_exp_data_rate_ul',
+ required: true
},
{
title: 'Downlink Regional Traffic Density(Mbps/km )',
- key: 'an_area_traffic_cap_dl'
+ key: 'an_area_traffic_cap_dl',
+ required: true
},
{
title: 'Uplink Regional Traffic Density(Mbps/km )',
- key: 'an_area_traffic_cap_ul'
+ key: 'an_area_traffic_cap_ul',
+ required: true
},
{
title: 'Script Name',
- key: 'an_script_name'
+ key: 'an_script_name',
+ required: true
},
{
- title: 'overallUserDensity',
- key: 'an_overalluser_density'
+ title: 'Overall User Density',
+ key: 'an_overalluser_density',
+ required: true
},
{
title:'Endpoint',
key:"an_Endpoint",
+ required: true,
options: [
{
title: 'ip_address',
@@ -231,23 +249,27 @@ export const CORE_FORM_ITEMS = { },
{
title: 'nexthop_info',
- key: 'an_nexthop_info'
+ key: 'an_nexthop_info',
+ holder: 'NextHop'
}
]
},
{
title: 'Coverage Area Ta List',
- key: 'an_coverage_area_ta_list'
+ key: 'an_coverage_area_ta_list',
+ required: true
}
],
"Cn": [
{
title: 'S-NSSAI',
- key: 'cn_service_snssai'
+ key: 'cn_service_snssai',
+ required: true
},
{
title: 'Resource Sharing Level',
key: 'cn_resource_sharing_level',
+ required: true,
options: [
{
title: 'Shared',
@@ -262,6 +284,7 @@ export const CORE_FORM_ITEMS = { {
title: 'Mobility',
key: 'cn_ue_mobility_level',
+ required: true,
options: [
{
title: 'Stationary',
@@ -283,43 +306,58 @@ export const CORE_FORM_ITEMS = { },
{
title: 'Latency (ms)',
- key: 'cn_latency'
+ key: 'cn_latency',
+ required: true
},
{
title: 'Max Number of UEs',
- key: 'cn_max_number_of_ues'
+ key: 'cn_max_number_of_ues',
+ required: true
},
{
title: 'Activity Factor (%)',
- key: 'cn_activity_factor'
+ key: 'cn_activity_factor',
+ required: true
},
{
title: 'User Downlink Experience Rate(Mbps)',
- key: 'cn_exp_data_rate_dl'
+ key: 'cn_exp_data_rate_dl',
+ required: true
},
{
title: 'User Uplink Experience Rate(Mbps)',
- key: 'cn_exp_data_rate_ul'
+ key: 'cn_exp_data_rate_ul',
+ required: true
},
{
title: 'Downlink Regional Traffic Density(Mbps/km )',
- key: 'cn_area_traffic_cap_dl'
+ key: 'cn_area_traffic_cap_dl',
+ required: true
},
{
title: 'Uplink Regional Traffic Density(Mbps/km )',
- key: 'cn_area_traffic_cap_ul'
+ key: 'cn_area_traffic_cap_ul',
+ required: true
},
{
title: 'Script Name',
- key: 'cn_script_name'
+ key: 'cn_script_name',
+ required: true
+ },
+ {
+ title: 'Max Number of PUD Session',
+ key: 'cn_max_number_of_pud_session',
+ required: true
},
{
- title: 'overallUserDensity',
- key: 'cn_overalluser_density'
+ title: 'OverAll User Density',
+ key: 'cn_overalluser_density',
+ required: true
},
{
title:'Endpoint',
key:"cn_Endpoint",
+ required: true,
options: [
{
title: 'ip_address',
|