From ff76b5ed0aa91d5fdf9dc4f95e8b20f91ed9d072 Mon Sep 17 00:00:00 2001 From: "Sonsino, Ofir (os0695)" Date: Tue, 10 Jul 2018 15:57:37 +0300 Subject: New Angular UI from 1806 Change-Id: I39c160db0e0a6ec2e587ccf007ee1b23c6a08666 Issue-ID: VID-208 Signed-off-by: Sonsino, Ofir (os0695) --- .../service-instance-details.component.ts | 238 +++++++++++++++++++++ .../service-instance-details.html | 168 +++++++++++++++ .../service-instance-details.scss | 64 ++++++ .../service-instance-details.service.spec.ts | 26 +++ .../service-instance-details.service.ts | 22 ++ .../servicePopupDataModel.ts | 32 +++ 6 files changed, 550 insertions(+) create mode 100644 vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.component.ts create mode 100644 vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.html create mode 100644 vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.scss create mode 100644 vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.service.spec.ts create mode 100644 vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.service.ts create mode 100644 vid-webpack-master/src/app/components/service-popup/service-instance-details/servicePopupDataModel.ts (limited to 'vid-webpack-master/src/app/components/service-popup/service-instance-details') diff --git a/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.component.ts b/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.component.ts new file mode 100644 index 000000000..b6a2e3967 --- /dev/null +++ b/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.component.ts @@ -0,0 +1,238 @@ +import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild} from '@angular/core'; +import {FormControl, FormGroup, Validators} from "@angular/forms"; +import {ServicePopupDataModel} from './servicePopupDataModel'; +import {AaiService} from '../../../services/aaiService/aai.service'; +import {updateServiceInstance} from "../../../service.actions"; +import * as _ from 'lodash'; +import {ServiceModel} from "../../../shared/models/serviceModel"; +import {ModelInfo} from "../../../shared/models/modelInfo"; +import {loadProductFamiliesAction} from "../../../services/aaiService/aai.actions"; +import {Observable} from "rxjs/Observable"; +import {SelectOptionInterface} from "../../../shared/models/selectOption"; +import {NgRedux, select} from "@angular-redux/store"; +import {AppState} from "../../../store/reducers"; +import {isNullOrUndefined} from 'util'; +import {ServiceInstanceDetailsService} from './service-instance-details.service'; +import {NumbersLettersUnderscoreValidator} from '../../../shared/components/validators/numbersLettersUnderscore/numbersLettersUnderscore.validator'; +import {DefaultDataGeneratorService} from '../../../shared/services/defaultDataServiceGenerator/default.data.generator.service'; + + +@Component({ + selector: 'service-instance-details', + templateUrl: 'service-instance-details.html', + styleUrls: ['service-instance-details.scss'], + providers: [AaiService] +}) + +export class ServiceInstanceDetailsComponent implements OnInit, OnChanges { + ngOnChanges(changes: SimpleChanges): void { + if (changes["serviceInstance"] !== undefined && changes["serviceInstance"].currentValue !== changes["serviceInstance"].previousValue && changes["serviceInstance"].currentValue !== null) { + this.oldServiceInstance = Object.assign({}, this.serviceInstance); + } + } + _serviceModel: ServiceModel; + @Input () serviceInstance: any; + @Input () dynamicInputs; + @Input () servicesQty: number; + @Input () + set serviceModel(serviceModel: ServiceModel) { + this._serviceModel = serviceModel; + this.updateFormGroupControlsWithServiceModel(serviceModel); + } + @ViewChild('serviceForm') serviceForm: 'ServiceForm'; + @Output() closePopup : EventEmitter = new EventEmitter(); + @Output() onDataChanged: EventEmitter = new EventEmitter(); + oldServiceInstance = {}; + + //todo: implement Epics and use @select to fetch the rest of the form's data as done with productFamilies. + //that way we can loose the updateFormData function and the subscription to store in the constructor. + @select(['service','productFamilies']) + readonly productFamilies : Observable; + serviceDetails:any = { + + }; + servicePopupDataModel: ServicePopupDataModel = new ServicePopupDataModel(); + serviceInstanceDetailsFormGroup: FormGroup; + serviceInstanceDetailsService : ServiceInstanceDetailsService; + + constructor(private _aaiService: AaiService, private store: NgRedux, private _serviceInstanceDetailsService : ServiceInstanceDetailsService, private _defaultDataGeneratorService : DefaultDataGeneratorService) { + this.store.subscribe(() => {this.updateFormData()}); + this.serviceInstanceDetailsService = this._serviceInstanceDetailsService; + this.serviceInstanceDetailsFormGroup = this.createFormGroup(); + + this.serviceInstanceDetailsFormGroup.valueChanges.subscribe(()=> { + this.onDataChanged.next(); + }) + } + + ngOnInit() { + this.subscribeToFormChanges(); + this._aaiService.getSubscribers().subscribe(); + this._aaiService.getCategoryParameters(null).subscribe(); + this._aaiService.getAicZones().subscribe(); + this.store.dispatch(loadProductFamiliesAction()); + } + + + createFormGroup(): FormGroup { + const formGroup = new FormGroup({ + globalSubscriberId: new FormControl( + Validators.compose([Validators.required]) + ), + productFamilyId: new FormControl(), + subscriptionServiceType: new FormControl({value: null, disabled: true}, Validators.compose([Validators.required])), + lcpCloudRegionId: new FormControl({value: null, disabled: true}, Validators.compose([Validators.required])), + tenantId: new FormControl({value: null, disabled: true}, Validators.compose([Validators.required])), + aicZoneId: new FormControl(), + projectName: new FormControl(), + owningEntityId: new FormControl(Validators.compose([Validators.required])), + rollbackOnFailure: new FormControl(null, Validators.required), + }); + + return formGroup; + } + + updateFormGroupControlsWithServiceModel(serviceModel: ServiceModel) { + this.serviceInstanceDetailsFormGroup.markAsUntouched(); + + if (serviceModel) { + this.serviceDetails.isUserProvidedNaming = serviceModel.isUserProvidedNaming; + if (serviceModel.isUserProvidedNaming) { + this.serviceInstanceDetailsFormGroup.addControl('instanceName', new FormControl('', Validators.compose([Validators.required, NumbersLettersUnderscoreValidator.valid]))) + }else{ + this.serviceInstanceDetailsFormGroup.removeControl('instanceName'); + } + + if (serviceModel.isMultiStepDesign) { + this.serviceInstanceDetailsFormGroup.addControl('pause', new FormControl(true)); + }else{ + this.serviceInstanceDetailsFormGroup.removeControl('pause'); + } + } + } + + updateFormData() { + let service = this.store.getState().service; + this.servicePopupDataModel.subscribers = service.subscribers; + this.servicePopupDataModel.serviceTypes = service.serviceTypes[this.servicePopupDataModel.globalCustomerId]; + this.servicePopupDataModel.lcpRegions = service.lcpRegionsAndTenants.lcpRegionList; + if (this.serviceInstance) { + this.servicePopupDataModel.tenants = service.lcpRegionsAndTenants.lcpRegionsTenantsMap[this.serviceInstance.lcpCloudRegionId]; + } + this.servicePopupDataModel.aicZones = service.aicZones; + this.servicePopupDataModel.owningEntities = _.get(service.categoryParameters, 'owningEntityList'); + this.servicePopupDataModel.projects = _.get(service.categoryParameters, 'projectList'); + this.onDataChanged.next(); + } + + subscribeToFormChanges(): void { + this.serviceInstanceDetailsFormGroup.get('globalSubscriberId').valueChanges.subscribe(val => { + this.updateServiceTypes(val); + this.setDisabledState(val, 'subscriptionServiceType'); + + }); + this.serviceInstanceDetailsFormGroup.get('subscriptionServiceType').valueChanges.subscribe(val => { + this.getTenants(val); + this.setDisabledState(val, 'lcpCloudRegionId'); + + }); + this.serviceInstanceDetailsFormGroup.get('lcpCloudRegionId').valueChanges.subscribe(val => { + this.setDisabledState(val, 'tenantId'); + this.updateTenantList(val); + + }); + + this.serviceInstanceDetailsFormGroup.get('tenantId').valueChanges.subscribe(val => { + this.serviceDetails.tenantName = this.getNameFromListById(this.servicePopupDataModel.tenants, val); + this.onDataChanged.next(); + }); + + this.serviceInstanceDetailsFormGroup.get('aicZoneId').valueChanges.subscribe(val => { + this.serviceDetails.aicZoneName = this.getNameFromListById(this.servicePopupDataModel.aicZones, val); + this.onDataChanged.next(); + }); + } + + getNameFromListById(list, id:string ) { + if(list && id) { + let filterItem = list.filter(item => { + return item.id == id; + }) + return filterItem && filterItem[0].name; + } + return null; + } + + setDisabledState(val, field: string): void { + if(val) { + this.serviceInstanceDetailsFormGroup.controls[field].enable(); + } else { + this.serviceInstanceDetailsFormGroup.controls[field].disable(); + } + } + + isShowingNotificationArea(): boolean { + return this.servicesQty > 1; + } + + updateServiceTypes(subscriberId) { + if (subscriberId) { + this.servicePopupDataModel.globalCustomerId = subscriberId; + this._aaiService.getServiceTypes(subscriberId).subscribe(() => { + this.updateFormData(); + this.onDataChanged.next(); + }, (error) => { + + }); + } + } + + updateTenantList(cloudRegionId) { + this.servicePopupDataModel.tenants = this.store.getState().service.lcpRegionsAndTenants.lcpRegionsTenantsMap[cloudRegionId]; + this.onDataChanged.next(); + } + + getTenants(serviceType) { + if (serviceType) { + this._aaiService.getLcpRegionsAndTenants(this.servicePopupDataModel.globalCustomerId, serviceType).subscribe(()=>{ + this.onDataChanged.next(); + }); + } + } + + onSubmit(formValues): void { + formValues.bulkSize = this.servicesQty; + let dynamicFields: { [dynamicField: string] : string; }; + dynamicFields = {}; + this.dynamicInputs.map(function (x) { + let dynamicField: string = x.id; + dynamicFields[dynamicField] = formValues[dynamicField]; + delete formValues[dynamicField]; + }); + formValues.instanceParams = []; + formValues.instanceParams.push(dynamicFields); + formValues.modelInfo = new ModelInfo(this._serviceModel); + Object.assign(formValues, this.serviceDetails); + this.store.dispatch(updateServiceInstance(formValues, this._serviceModel.uuid)); + if (this.store.getState().global.flags['FLAG_SETTING_DEFAULTS_IN_DRAWING_BOARD']){ + this._defaultDataGeneratorService.updateReduxOnFirstSet(this._serviceModel.uuid,formValues); + } + window.parent.postMessage( { + eventId: 'submitIframe', + data: { + serviceModelId: this._serviceModel.uuid + } + }, "*"); + this.closePopup.emit(this._serviceModel.uuid); + } + + hasApiError(controlName : string, data : Array){ + if(!isNullOrUndefined(this.servicePopupDataModel) && !isNullOrUndefined(data)){ + if(!this.serviceInstanceDetailsFormGroup.controls[controlName].disabled && data.length === 0){ + return true; + } + } + return false; + } + +} diff --git a/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.html b/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.html new file mode 100644 index 000000000..3d632bd89 --- /dev/null +++ b/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.html @@ -0,0 +1,168 @@ + +
+
+ + + + +
+ + + + +
+ +
+ + + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + +
+
+ + + +
+
+ + +
+ + + +
+
diff --git a/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.scss b/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.scss new file mode 100644 index 000000000..928343d43 --- /dev/null +++ b/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.scss @@ -0,0 +1,64 @@ +#service-instance-details { + position: relative; + + #notification-area { + color: #959595; + font-size: 12px; + position: absolute; + top: 3px; + left: 30px; + } + + height: 100%; + overflow: auto; + padding: 30px; + + /deep/ { + .form-control { + border-radius: 2px; + box-shadow: none; + border-color: #D2D2D2; + } + + label { + font-family: OpenSans-Semibold; + font-size: 12px; + } + + select { + @extend .form-control; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: url('../../../../assets/img/chevron.svg') 0 0 no-repeat; + background-size: 24px; + background-position-x: right; + background-position-y: center; + font-family: OpenSans-Italic; + font-size: 14px; + color: #959595; + height: 38px; + } + + input:not([type='checkbox']) { + @extend .form-control; + height: 38px; + } + + .form-control[disabled], fieldset[disabled] .form-control { + opacity: 0.5; + } + .input-text { + border: 1px solid #D2D2D2; + border-radius: 2px; + } + + .details-item { + margin-bottom: 20px; + } + } + + .checkbox-label { + font-family: OpenSans-Regular; + } +} diff --git a/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.service.spec.ts b/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.service.spec.ts new file mode 100644 index 000000000..605653bd0 --- /dev/null +++ b/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.service.spec.ts @@ -0,0 +1,26 @@ +import { getTestBed, TestBed } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; +import { ServiceInstanceDetailsService } from './service-instance-details.service'; +import { NgRedux } from '@angular-redux/store'; + +export class MockAppStore {} + +describe('Service instance details service', () => { + let injector; + let service: ServiceInstanceDetailsService; + let httpMock: HttpTestingController; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [HttpClientTestingModule], + providers: [ServiceInstanceDetailsService, + {provide: NgRedux, useClass: MockAppStore}] + }); + + injector = getTestBed(); + service = injector.get(ServiceInstanceDetailsService); + httpMock = injector.get(HttpTestingController); + }); +}); + + diff --git a/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.service.ts b/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.service.ts new file mode 100644 index 000000000..99b390d2f --- /dev/null +++ b/vid-webpack-master/src/app/components/service-popup/service-instance-details/service-instance-details.service.ts @@ -0,0 +1,22 @@ +import { Injectable } from '@angular/core'; +import { isNullOrUndefined } from 'util'; +import { FormGroup } from '@angular/forms'; +import * as _ from 'lodash'; +import { createVFModuleInstance, updateVFModuleInstance, updateVNFInstance } from '../../../service.actions'; +import { NgRedux } from '@angular-redux/store'; +import { AppState } from '../../../store/reducers'; + +@Injectable() +export class ServiceInstanceDetailsService { + static controlsFieldsStatus = {}; + + constructor(private store: NgRedux) { } + hasApiError(controlName: string, data: Array, serviceInstanceDetailsFormGroup: FormGroup) { + if (!isNullOrUndefined(data)) { + if (!serviceInstanceDetailsFormGroup.controls[controlName].disabled && data.length === 0) { + return true; + } + } + return false; + } +} diff --git a/vid-webpack-master/src/app/components/service-popup/service-instance-details/servicePopupDataModel.ts b/vid-webpack-master/src/app/components/service-popup/service-instance-details/servicePopupDataModel.ts new file mode 100644 index 000000000..c7894e2cd --- /dev/null +++ b/vid-webpack-master/src/app/components/service-popup/service-instance-details/servicePopupDataModel.ts @@ -0,0 +1,32 @@ +import {SelectOption, SelectOptionInterface} from "../../../shared/models/selectOption"; + +export class ServicePopupDataModel { + subscribers: SelectOptionInterface[]; + serviceTypes: SelectOptionInterface[]; + aicZones: SelectOptionInterface[]; + lcpRegions: SelectOptionInterface[]; + productFamilies: SelectOptionInterface[]; + lcpRegionsTenantsMap: object; + tenants: SelectOptionInterface[]; + projects: SelectOptionInterface[]; + owningEntities: SelectOptionInterface[]; + globalCustomerId: string; + rollbackOnFailure: SelectOptionInterface[]; + + + constructor(){ + this.subscribers = null; + this.serviceTypes = null; + this.aicZones = null; + this.lcpRegions = null; + this.lcpRegionsTenantsMap = {}; + this.tenants = null; + this.productFamilies = null; + this.projects = null; + this.owningEntities = null; + this.rollbackOnFailure = [ + new SelectOption({id: 'true', name: 'Rollback'}), + new SelectOption({id: 'false', name: 'Don\'t Rollback'}) + ]; + } +} -- cgit 1.2.3-korg