X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=catalog-ui%2Fsrc%2Fapp%2Fview-models%2Fforms%2Fproperty-forms%2Fcomponent-property-form%2Fproperty-form-view-model.ts;h=4b41e7ab25fd590af1e42113916b53d1ed5656f7;hb=974764bdb65a7313c546b65c67d49df1de4ea1e1;hp=b3557b055f9c248d052d438ca256c5243022461f;hpb=ed64b5edff15e702493df21aa3230b81593e6133;p=sdc.git diff --git a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts index b3557b055f..4b41e7ab25 100644 --- a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts +++ b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts @@ -1,13 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + 'use strict'; -import { - PROPERTY_TYPES, ModalsHandler, ValidationUtils, PROPERTY_VALUE_CONSTRAINTS, FormState, PROPERTY_DATA} from "app/utils"; +import * as _ from "lodash"; +import {FormState, PROPERTY_DATA, PROPERTY_TYPES, PROPERTY_VALUE_CONSTRAINTS, ValidationUtils} from "app/utils"; import {DataTypesService} from "app/services"; -import {PropertyModel, DataTypesMap, Component} from "app/models"; +import {DataTypesMap, PropertyModel, InputBEModel, Component, InputFEModel} from "app/models"; +import {ComponentInstance} from "../../../../models/componentsInstances/componentInstance"; +import {ComponentInstanceServiceNg2} from "app/ng2/services/component-instance-services/component-instance.service"; +import {ComponentServiceNg2} from "app/ng2/services/component-services/component.service"; +import {SdcUiCommon, SdcUiComponents, SdcUiServices} from "onap-ui-angular"; +import {CompositionService} from "app/ng2/pages/composition/composition.service"; +import {WorkspaceService} from "app/ng2/pages/workspace/workspace.service"; +import {Observable} from "rxjs"; +import {TopologyTemplateService} from "app/ng2/services/component-services/topology-template.service"; +import {InstanceFeDetails} from "../../../../models/instance-fe-details"; +import {ToscaGetFunction} from "../../../../models/tosca-get-function"; +import {ToscaFunctionValidationEvent} from "../../../../ng2/pages/properties-assignment/tosca-function/tosca-function.component"; export interface IEditPropertyModel { property:PropertyModel; types:Array; simpleTypes:Array; + hasGetFunctionValue: boolean; + isGetFunctionValid: boolean; } interface IPropertyFormViewModelScope extends ng.IScope { @@ -15,12 +48,14 @@ interface IPropertyFormViewModelScope extends ng.IScope { editForm:ng.IFormController; footerButtons:Array; isNew:boolean; + nameMaxLength:number; isLoading:boolean; - isService:boolean; + componentMetadata: { isService: boolean, isVfc: boolean } validationPattern:RegExp; propertyNameValidationPattern:RegExp; commentValidationPattern:RegExp; - editPropertyModel:IEditPropertyModel; + editPropertyModel: IEditPropertyModel; + componentInstanceMap: Map; modalInstanceProperty:ng.ui.bootstrap.IModalServiceInstance; currentPropertyIndex:number; isLastProperty:boolean; @@ -29,14 +64,19 @@ interface IPropertyFormViewModelScope extends ng.IScope { dataTypes:DataTypesMap; isTypeDataType:boolean; maxLength:number; + isViewOnly:boolean; isPropertyValueOwner:boolean; + isVnfConfiguration:boolean; + constraints:string[]; + modelNameFilter:string; + isGetFunctionValueType: boolean; + invalidMandatoryFields: boolean; validateJson(json:string):boolean; save(doNotCloseModal?:boolean):void; getValidationPattern(type:string):RegExp; validateIntRange(value:string):boolean; close():void; - onValueChange():void; onSchemaTypeChange():void; onTypeChange(resetSchema:boolean):void; showSchema():boolean; @@ -45,6 +85,7 @@ interface IPropertyFormViewModelScope extends ng.IScope { getNext():void; isSimpleType(typeName:string):boolean; getDefaultValue():any; + onValueTypeChange(): void; } export class PropertyFormViewModel { @@ -60,10 +101,19 @@ export class PropertyFormViewModel { 'ValidationUtils', 'component', '$filter', - 'ModalsHandler', + 'ModalServiceSdcUI', 'filteredProperties', '$timeout', - 'isPropertyValueOwner' + 'isViewOnly', + 'isPropertyValueOwner', + 'propertyOwnerType', + 'propertyOwnerId', + 'ComponentInstanceServiceNg2', + 'ComponentServiceNg2', + 'TopologyTemplateService', + 'CompositionService', + 'workspaceService', + 'inputProperty' ]; private formState:FormState; @@ -78,10 +128,19 @@ export class PropertyFormViewModel { private ValidationUtils:ValidationUtils, private component:Component, private $filter:ng.IFilterService, - private ModalsHandler:ModalsHandler, + private modalService:SdcUiServices.ModalService, private filteredProperties:Array, private $timeout:ng.ITimeoutService, - private isPropertyValueOwner:boolean) { + private isViewOnly:boolean, + private isPropertyValueOwner:boolean, + private propertyOwnerType:string, + private propertyOwnerId:string, + private ComponentInstanceServiceNg2: ComponentInstanceServiceNg2, + private ComponentServiceNg2: ComponentServiceNg2, + private topologyTemplateService: TopologyTemplateService, + private compositionService: CompositionService, + private workspaceService: WorkspaceService, + private inputProperty : InputFEModel) { this.formState = angular.isDefined(property.name) ? FormState.UPDATE : FormState.CREATE; this.initScope(); @@ -90,54 +149,105 @@ export class PropertyFormViewModel { private initResource = ():void => { this.$scope.editPropertyModel.property = new PropertyModel(this.property); this.$scope.editPropertyModel.property.type = this.property.type ? this.property.type : null; + this.$scope.editPropertyModel.property.value = this.property.value ? this.property.value : this.property.defaultValue; + this.$scope.constraints = this.property.constraints && this.property.constraints[0] ? this.property.constraints[0]["validValues"] : null; + this.initToscaGetFunction(); this.setMaxLength(); - this.initAddOnLabels(); }; - //init property add-ons labels that show up at the left side of the input. - private initAddOnLabels = () => { - if (this.$scope.editPropertyModel.property.name == 'network_role' && this.$scope.isService) { - //the server sends back the normalized name. Remove it (to prevent interference with validation) and set the addon label to the component name directly. - //Note: this cant be done in properties.ts because we dont have access to the component - if (this.$scope.editPropertyModel.property.value) { - let splitProp = this.$scope.editPropertyModel.property.value.split(new RegExp(this.component.normalizedName + '.', "gi")); - this.$scope.editPropertyModel.property.value = splitProp.pop(); - } - this.$scope.editPropertyModel.property.addOn = this.component.name; - } + private initToscaGetFunction() { + this.$scope.editPropertyModel.hasGetFunctionValue = this.$scope.editPropertyModel.property.isToscaFunction(); + this.$scope.editPropertyModel.isGetFunctionValid = true; } - private initEditPropertyModel = ():void => { - this.$scope.editPropertyModel = { - property: null, - types: PROPERTY_DATA.TYPES, - simpleTypes: PROPERTY_DATA.SIMPLE_TYPES - }; + private isDataTypeForPropertyType = (property:PropertyModel):boolean=> { + property.simpleType = ""; + if (property.type && PROPERTY_DATA.TYPES.indexOf(property.type) > -1) { + return false; + } + let simpleType = this.getTypeForDataTypeDerivedFromSimple(property.type); + if (simpleType) { + property.simpleType = simpleType; + return false; + } + return true; + }; - this.initResource(); + private getTypeForDataTypeDerivedFromSimple = (dataTypeName:string):string => { + if (!this.$scope.dataTypes[dataTypeName]) { + return 'string'; + } + if (this.$scope.dataTypes[dataTypeName].derivedFromName == "tosca.datatypes.Root" || this.$scope.dataTypes[dataTypeName].properties) { + return null; + } + if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(this.$scope.dataTypes[dataTypeName].derivedFromName) > -1) { + return this.$scope.dataTypes[dataTypeName].derivedFromName + } + return this.getTypeForDataTypeDerivedFromSimple(this.$scope.dataTypes[dataTypeName].derivedFromName); }; private initForNotSimpleType = ():void => { - let property = this.$scope.editPropertyModel.property; + const property = this.$scope.editPropertyModel.property; this.$scope.isTypeDataType = this.DataTypesService.isDataTypeForPropertyType(this.$scope.editPropertyModel.property); - if (property.type && this.$scope.editPropertyModel.simpleTypes.indexOf(property.type) == -1) { - if (!(property.value || property.defaultValue)) { - switch (property.type) { - case PROPERTY_TYPES.MAP: - this.$scope.myValue = {'': null}; - break; - case PROPERTY_TYPES.LIST: - this.$scope.myValue = []; - break; - default: - this.$scope.myValue = {}; - } - } else { + if (property.isToscaFunction()) { + this.initValueForGetFunction(); + return; + } + + if (this.isComplexType(property.type)) { + if (property.value || property.defaultValue) { this.$scope.myValue = JSON.parse(property.value || property.defaultValue); + } else { + this.initEmptyComplexValue(property.type); } } }; + private initValueForGetFunction(): void { + const property = this.$scope.editPropertyModel.property; + if (property.defaultValue) { + this.$scope.myValue = JSON.parse(property.defaultValue); + return; + } + if (this.isComplexType(property.type)) { + this.initEmptyComplexValue(property.type); + return; + } + + this.$scope.myValue = undefined; + } + + private initComponentInstanceMap() { + this.$scope.componentInstanceMap = new Map(); + if (this.compositionService.componentInstances) { + this.compositionService.componentInstances.forEach(value => { + this.$scope.componentInstanceMap.set(value.uniqueId, { + name: value.name + }); + }); + } + } + + private initEmptyComplexValue(type: string): any { + switch (type) { + case PROPERTY_TYPES.MAP: + this.$scope.myValue = {'': null}; + break; + case PROPERTY_TYPES.LIST: + this.$scope.myValue = []; + break; + default: + this.$scope.myValue = {}; + } + } + + private isComplexType(type: string): boolean { + if (!type) { + return false; + } + return PROPERTY_DATA.SIMPLE_TYPES.indexOf(type) == -1; + } + private setMaxLength = ():void => { switch (this.$scope.editPropertyModel.property.type) { case PROPERTY_TYPES.MAP: @@ -158,25 +268,46 @@ export class PropertyFormViewModel { private initScope = ():void => { //scope properties + this.$scope.isViewOnly = this.isViewOnly; + this.$scope.isLoading = true; this.$scope.forms = {}; this.$scope.validationPattern = this.ValidationPattern; this.$scope.propertyNameValidationPattern = this.PropertyNameValidationPattern; this.$scope.commentValidationPattern = this.CommentValidationPattern; - this.$scope.isLoading = false; + this.$scope.nameMaxLength = PROPERTY_VALUE_CONSTRAINTS.NAME_MAX_LENGTH; this.$scope.isNew = (this.formState === FormState.CREATE); - this.$scope.isService = this.component.isService(); + this.$scope.componentMetadata = { + isService: this.workspaceService.metadata.isService(), + isVfc: this.workspaceService.metadata.isVfc() + } this.$scope.modalInstanceProperty = this.$uibModalInstance; this.$scope.currentPropertyIndex = _.findIndex(this.filteredProperties, i=> i.name == this.property.name); this.$scope.isLastProperty = this.$scope.currentPropertyIndex == (this.filteredProperties.length - 1); - this.$scope.dataTypes = this.DataTypesService.getAllDataTypes(); + const property = new PropertyModel(this.property); + this.$scope.editPropertyModel = { + 'property': property, + types: PROPERTY_DATA.TYPES, + simpleTypes: PROPERTY_DATA.SIMPLE_TYPES, + hasGetFunctionValue: property.isToscaFunction(), + isGetFunctionValid: true, + }; + this.$scope.editPropertyModel.types.sort((a,b) => a.localeCompare(b)); this.$scope.isPropertyValueOwner = this.isPropertyValueOwner; - this.initEditPropertyModel(); - - this.$scope.nonPrimitiveTypes = _.filter(Object.keys(this.$scope.dataTypes), (type:string)=> { - return this.$scope.editPropertyModel.types.indexOf(type) == -1; - }); + this.$scope.propertyOwnerType = this.propertyOwnerType; + this.$scope.modelNameFilter = this.workspaceService.metadata.model; + //check if property of VnfConfiguration + this.$scope.isVnfConfiguration = false; + if(this.propertyOwnerType == "component" && angular.isArray(this.compositionService.componentInstances)) { + const componentPropertyOwner:ComponentInstance = this.compositionService.componentInstances.find((ci:ComponentInstance) => { + return ci.uniqueId === this.property.resourceInstanceUniqueId; + }); + if (componentPropertyOwner && componentPropertyOwner.componentName === 'vnfConfiguration') { + this.$scope.isVnfConfiguration = true; + } + } + this.initResource(); this.initForNotSimpleType(); - + this.initComponentInstanceMap(); this.$scope.validateJson = (json:string):boolean => { if (!json) { @@ -185,10 +316,36 @@ export class PropertyFormViewModel { return this.ValidationUtils.validateJson(json); }; + this.DataTypesService.fetchDataTypesByModel(this.workspaceService.metadata.model).then(response => { + this.$scope.dataTypes = response.data as DataTypesMap; + this.$scope.nonPrimitiveTypes = _.filter(Object.keys(this.$scope.dataTypes), (type: string) => { + return this.$scope.editPropertyModel.types.indexOf(type) == -1 ; + }).sort((a, b) => a.localeCompare(b)); + this.$scope.isLoading = false; + }); //scope methods this.$scope.save = (doNotCloseModal?:boolean):void => { let property:PropertyModel = this.$scope.editPropertyModel.property; + this.$scope.isLoading = true; + if (property.propertyView){ + if (property.constraints.length == 0) { + return; + } + let input : InputBEModel = this.inputProperty; + input.constraints = property.constraints; + this.ComponentServiceNg2.updateComponentInputs(this.component, [input]).subscribe( + (response) => { + console.debug("Input property updated"); + this.$uibModalInstance.close(); + }, + (error) => { + console.debug("Failed to update input property"); + this.$uibModalInstance.close(); + } + ); + return; + } this.$scope.editPropertyModel.property.description = this.ValidationUtils.stripAndSanitize(this.$scope.editPropertyModel.property.description); //if read only - or no changes made - just closes the modal //need to check for property.value changes manually to detect if map properties deleted @@ -200,38 +357,51 @@ export class PropertyFormViewModel { this.$scope.isLoading = true; - let onPropertyFaild = (response):void => { - console.info('onFaild', response); + let onPropertyFailure = (response):void => { + console.error('Failed to update property', response); this.$scope.isLoading = false; }; let onPropertySuccess = (propertyFromBE:PropertyModel):void => { - console.info('onPropertyResourceSuccess : ', propertyFromBE); this.$scope.isLoading = false; - + this.filteredProperties[this.$scope.currentPropertyIndex] = propertyFromBE; if (!doNotCloseModal) { - this.$uibModalInstance.close(); + this.$uibModalInstance.close(propertyFromBE); } else { this.$scope.forms.editForm.$setPristine(); this.$scope.editPropertyModel.property = new PropertyModel(); } }; - //in case we have uniqueId we call update method - if (this.$scope.isPropertyValueOwner) { - if (!this.$scope.editPropertyModel.property.simpleType && !this.$scope.isSimpleType(property.type)) { - let myValueString:string = JSON.stringify(this.$scope.myValue); - property.value = myValueString; + //Not clean, but doing this as a temporary fix until we update the property right panel modals + if (this.propertyOwnerType === "group"){ + this.ComponentInstanceServiceNg2.updateComponentGroupInstanceProperties(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, this.propertyOwnerId, [property]) + .subscribe((propertiesFromBE) => { onPropertySuccess(propertiesFromBE[0])}, error => onPropertyFailure(error)); + } else if (this.propertyOwnerType === "policy"){ + if (!this.$scope.editPropertyModel.property.simpleType && + !this.$scope.isSimpleType(this.$scope.editPropertyModel.property.type) && + !_.isNil(this.$scope.myValue)) { + property.value = JSON.stringify(this.$scope.myValue); } - this.component.updateInstanceProperty(property).then(onPropertySuccess, onPropertyFaild); + this.ComponentInstanceServiceNg2.updateComponentPolicyInstanceProperties(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, this.propertyOwnerId, [property]) + .subscribe((propertiesFromBE) => { onPropertySuccess(propertiesFromBE[0])}, error => onPropertyFailure(error)); } else { - if (!this.$scope.editPropertyModel.property.simpleType && !this.$scope.isSimpleType(property.type)) { - let myValueString:string = JSON.stringify(this.$scope.myValue); - property.defaultValue = myValueString; + //in case we have uniqueId we call update method + if (this.$scope.isPropertyValueOwner) { + if (!this.$scope.editPropertyModel.property.simpleType && !this.$scope.isSimpleType(property.type)) { + property.value = JSON.stringify(this.$scope.myValue); + } + this.updateInstanceProperties(property.resourceInstanceUniqueId, [property]).subscribe((propertiesFromBE) => onPropertySuccess(propertiesFromBE[0]), + error => onPropertyFailure(error)); } else { - this.$scope.editPropertyModel.property.defaultValue = this.$scope.editPropertyModel.property.value; + if (!this.$scope.editPropertyModel.property.simpleType && !this.$scope.isSimpleType(property.type)) { + property.defaultValue = JSON.stringify(this.$scope.myValue); + property.value = JSON.stringify(this.$scope.myValue); + } else { + this.$scope.editPropertyModel.property.defaultValue = this.$scope.editPropertyModel.property.value; + } + this.addOrUpdateProperty(property).subscribe(onPropertySuccess, error => onPropertyFailure(error)); } - this.component.addOrUpdateProperty(property).then(onPropertySuccess, onPropertyFaild); } }; @@ -269,23 +439,30 @@ export class PropertyFormViewModel { this.$uibModalInstance.close(); }; - // put default value when instance value is empty - this.$scope.onValueChange = ():void => { - if (!this.$scope.editPropertyModel.property.value) { - if (this.$scope.isPropertyValueOwner) { - this.$scope.editPropertyModel.property.value = this.$scope.editPropertyModel.property.defaultValue; - } - } - }; - // Add the done button at the footer. this.$scope.footerButtons = [ {'name': 'Save', 'css': 'blue', 'callback': this.$scope.save}, {'name': 'Cancel', 'css': 'grey', 'callback': this.$scope.close} ]; - this.$scope.$watch("forms.editForm.$invalid", (newVal, oldVal) => { - this.$scope.footerButtons[0].disabled = this.$scope.forms.editForm.$invalid; + this.$scope.$watch("forms.editForm.$invalid", (newVal) => { + if (this.$scope.editPropertyModel.hasGetFunctionValue) { + this.$scope.invalidMandatoryFields = !newVal || !this.$scope.editPropertyModel.property.toscaFunction || this.isViewOnly; + this.$scope.footerButtons[0].disabled = this.$scope.invalidMandatoryFields; + } else { + this.$scope.invalidMandatoryFields = !newVal || this.isViewOnly; + this.$scope.footerButtons[0].disabled = this.$scope.invalidMandatoryFields; + } + }); + + this.$scope.$watch("forms.editForm.$valid", (newVal) => { + if (this.$scope.editPropertyModel.hasGetFunctionValue) { + this.$scope.invalidMandatoryFields = !newVal || !this.$scope.editPropertyModel.property.toscaFunction || this.isViewOnly; + this.$scope.footerButtons[0].disabled = this.$scope.invalidMandatoryFields; + } else { + this.$scope.invalidMandatoryFields = !newVal || this.isViewOnly; + this.$scope.footerButtons[0].disabled = this.$scope.invalidMandatoryFields; + } }); this.$scope.getDefaultValue = ():any => { @@ -301,7 +478,7 @@ export class PropertyFormViewModel { this.$scope.onSchemaTypeChange = ():void => { if (this.$scope.editPropertyModel.property.type == PROPERTY_TYPES.MAP) { - this.$scope.myValue = {'': null}; + this.$scope.myValue = {}; } else if (this.$scope.editPropertyModel.property.type == PROPERTY_TYPES.LIST) { this.$scope.myValue = []; } @@ -309,14 +486,127 @@ export class PropertyFormViewModel { }; this.$scope.delete = (property:PropertyModel):void => { - let onOk = ():void => { - this.component.deleteProperty(property.uniqueId).then( + let onOk: Function = ():void => { + this.deleteProperty(property.uniqueId).subscribe( this.$scope.close ); }; let title:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TITLE"); let message:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TEXT", "{'name': '" + property.name + "'}"); - this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk); + const okButton = {testId: "OK", text: "OK", type: SdcUiCommon.ButtonType.info, callback: onOk, closeModal: true} as SdcUiComponents.ModalButtonComponent; + this.modalService.openInfoModal(title, message, 'delete-modal', [okButton]); }; + + this.$scope.onValueTypeChange = (): void => { + this.setEmptyValue(); + if (this.$scope.editPropertyModel.hasGetFunctionValue) { + this.$scope.editPropertyModel.isGetFunctionValid = undefined; + } else { + this.$scope.editPropertyModel.property.toscaFunction = undefined; + this.$scope.editPropertyModel.isGetFunctionValid = true; + } + } + + this.$scope.onConstraintChange = (constraints: any): void => { + console.log('$scope.onConstraintChange', constraints); + + if (!this.$scope.invalidMandatoryFields) { + this.$scope.footerButtons[0].disabled = !constraints.valid; + } else { + this.$scope.footerButtons[0].disabled = this.$scope.invalidMandatoryFields; + } + if (!constraints.constraints || constraints.constraints.length == 0) { + this.$scope.editPropertyModel.property.propertyConstraints = null; + this.$scope.editPropertyModel.property.constraints = null; + return; + } + this.$scope.editPropertyModel.property.propertyConstraints = this.serializePropertyConstraints(constraints.constraints); + this.$scope.editPropertyModel.property.constraints = constraints.constraints; + } + + this.$scope.onGetFunctionValidFunction = (toscaGetFunction: ToscaGetFunction): void => { + this.$scope.editPropertyModel.property.toscaFunction = toscaGetFunction; + } + + this.$scope.onToscaFunctionValidityChange = (validationEvent: ToscaFunctionValidationEvent): void => { + if (validationEvent.isValid) { + this.$scope.editPropertyModel.isGetFunctionValid = true; + return; + } + this.$scope.editPropertyModel.isGetFunctionValid = undefined; + } + }; + + private serializePropertyConstraints(constraints: any[]): string[] { + if (constraints) { + let stringConstrsints = new Array(); + constraints.forEach((constraint) => { + stringConstrsints.push(JSON.stringify(constraint)); + }) + return stringConstrsints; + } + return null; + } + + private setEmptyValue() { + const property1 = this.$scope.editPropertyModel.property; + property1.value = undefined; + if (this.isComplexType(property1.type)) { + this.initEmptyComplexValue(property1.type); + return; + } + this.$scope.myValue = ''; } + + private updateInstanceProperties = (componentInstanceId:string, properties:PropertyModel[]):Observable => { + + return this.ComponentInstanceServiceNg2.updateInstanceProperties(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, componentInstanceId, properties) + .map(newProperties => { + newProperties.forEach((newProperty) => { + if (!_.isNil(newProperty.path)) { + if (newProperty.path[0] === newProperty.resourceInstanceUniqueId) newProperty.path.shift(); + // find exist instance property in parent component for update the new value ( find bu uniqueId & path) + let existProperty: PropertyModel = _.find(this.compositionService.componentInstancesProperties[newProperty.resourceInstanceUniqueId], { + uniqueId: newProperty.uniqueId, + path: newProperty.path + }); + let index = this.compositionService.componentInstancesProperties[newProperty.resourceInstanceUniqueId].indexOf(existProperty); + this.compositionService.componentInstancesProperties[newProperty.resourceInstanceUniqueId][index] = newProperty; + } + }); + return newProperties; + }); + }; + + private addOrUpdateProperty = (property: PropertyModel): Observable => { + if (!property.uniqueId) { + let onSuccess = (newProperty: PropertyModel): PropertyModel => { + this.filteredProperties.push(newProperty); + return newProperty; + }; + return this.topologyTemplateService.addProperty(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, property) + .map(onSuccess); + } else { + let onSuccess = (newProperty: PropertyModel): PropertyModel => { + // find exist instance property in parent component for update the new value ( find bu uniqueId ) + let existProperty: PropertyModel = _.find(this.filteredProperties, {uniqueId: newProperty.uniqueId}); + let propertyIndex = this.filteredProperties.indexOf(existProperty); + this.filteredProperties[propertyIndex] = newProperty; + return newProperty; + }; + return this.topologyTemplateService.updateProperty(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, property).map(onSuccess); + } + }; + + public deleteProperty = (propertyId:string):Observable => { + let onSuccess = ():void => { + console.debug("Property deleted"); + delete _.remove(this.filteredProperties, {uniqueId: propertyId})[0]; + }; + let onFailed = ():void => { + console.debug("Failed to delete property"); + }; + return this.topologyTemplateService.deleteProperty(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, propertyId).map(onSuccess, onFailed); + }; + }