Sync Integ to Master
[sdc.git] / catalog-ui / src / app / view-models / workspace / tabs / composition / tabs / properties-and-attributes / properties-view-model.ts
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 'use strict';
22 import * as _ from "lodash";
23 import {
24     AttributeModel,
25     AttributesGroup,
26     Component,
27     ComponentInstance,
28     PropertyModel,
29     PropertiesGroup
30 } from "app/models";
31 import {ICompositionViewModelScope} from "../../composition-view-model";
32 import {ModalsHandler} from "app/utils";
33 import {ComponentServiceNg2} from "app/ng2/services/component-services/component.service";
34 import {ComponentGenericResponse} from "app/ng2/services/responses/component-generic-response";
35
36 interface IResourcePropertiesAndAttributesViewModelScope extends ICompositionViewModelScope {
37     properties:PropertiesGroup;
38     attributes:AttributesGroup;
39     propertiesMessage:string;
40     groupPropertiesByInstance:boolean;
41     showGroupsOfInstanceProperties:Array<boolean>;
42     addProperty():void;
43     updateProperty(property:PropertyModel):void;
44     deleteProperty(property:PropertyModel):void;
45     viewAttribute(attribute:AttributeModel):void;
46     groupNameByKey(key:string):string;
47     isPropertyOwner():boolean;
48     getComponentInstanceNameFromInstanceByKey(key:string):string;
49 }
50
51 export class ResourcePropertiesViewModel {
52
53     static '$inject' = [
54         '$scope',
55         '$filter',
56         '$uibModal',
57         'ModalsHandler',
58         'ComponentServiceNg2'
59
60     ];
61
62
63     constructor(private $scope:IResourcePropertiesAndAttributesViewModelScope,
64                 private $filter:ng.IFilterService,
65                 private $uibModal:ng.ui.bootstrap.IModalService,
66                 private ModalsHandler:ModalsHandler,
67                 private ComponentServiceNg2:ComponentServiceNg2) {
68
69         this.getComponentInstancesPropertiesAndAttributes();
70     }
71
72     private initComponentProperties = ():void => {
73         let result:PropertiesGroup = {};
74
75         if (this.$scope.selectedComponent) {
76             this.$scope.propertiesMessage = undefined;
77             this.$scope.groupPropertiesByInstance = false;
78             if (this.$scope.isComponentInstanceSelected()) {
79                 if (this.$scope.currentComponent.selectedInstance.originType === 'VF') {
80                     this.$scope.groupPropertiesByInstance = true;
81                 }
82                 result[this.$scope.currentComponent.selectedInstance.uniqueId] = this.$scope.currentComponent.componentInstancesProperties[this.$scope.currentComponent.selectedInstance.uniqueId];
83             } else if (this.$scope.currentComponent.isService()) {
84                 // Temporally fix to hide properties for service (UI stack when there are many properties)
85                 result = this.$scope.currentComponent.componentInstancesProperties;
86                 this.$scope.propertiesMessage = "Note: properties for service are disabled";
87             } else {
88                 let key = this.$scope.selectedComponent.uniqueId;
89                 result[key] = Array<PropertyModel>();
90                 let derived = Array<PropertyModel>();
91                 _.forEach(this.$scope.selectedComponent.properties, (property:PropertyModel) => {
92                     if (key == property.parentUniqueId) {
93                         result[key].push(property);
94                     } else {
95                         property.readonly = true;
96                         derived.push(property);
97                     }
98                 });
99                 if (derived.length) {
100                     result['derived'] = derived;
101                 }
102             }
103             this.$scope.properties = result;
104         }
105     };
106
107
108     private initComponentAttributes = ():void => {
109         let result:AttributesGroup = {};
110
111         if (this.$scope.selectedComponent) {
112             if (this.$scope.isComponentInstanceSelected()) {
113                 result[this.$scope.currentComponent.selectedInstance.uniqueId] = this.$scope.currentComponent.componentInstancesAttributes[this.$scope.currentComponent.selectedInstance.uniqueId];
114             } else if (this.$scope.currentComponent.isService()) {
115                 result = this.$scope.currentComponent.componentInstancesAttributes;
116             }
117             this.$scope.attributes = result;
118         }
119     };
120
121     /**
122      * This function is checking if the component is the value owner of the current property
123      * in order to notify the edit property modal which fields to disable
124      */
125     private isPropertyValueOwner = ():boolean => {
126         return this.$scope.currentComponent.isService() || !!this.$scope.currentComponent.selectedInstance;
127     };
128
129     /**
130      *  The function opens the edit property modal.
131      *  It checks if the property is from the VF or from one of it's resource instances and sends the needed property list.
132      *  For create property reasons an empty array is transferd
133      *
134      * @param property the wanted property to edit/create
135      */
136     private openEditPropertyModal = (property:PropertyModel):void => {
137         this.ModalsHandler.openEditPropertyModal(property,
138             this.$scope.component,
139             (this.$scope.isPropertyOwner() ?
140                 this.$scope.properties[property.parentUniqueId] :
141                 this.$scope.properties[property.resourceInstanceUniqueId]) || [],
142             this.isPropertyValueOwner()).then((updatedProperty:PropertyModel) => {
143                let oldProp = _.find(this.$scope.properties[updatedProperty.resourceInstanceUniqueId], (prop:PropertyModel) => {return prop.uniqueId == updatedProperty.uniqueId;});
144             oldProp.value = updatedProperty.value;
145         });
146     };
147
148     private openAttributeModal = (atrribute:AttributeModel):void => {
149
150         let modalOptions:ng.ui.bootstrap.IModalSettings = {
151             template: 'app/view-models/forms/attribute-form/attribute-form-view.html',
152             controller: 'Sdc.ViewModels.AttributeFormViewModel',
153             size: 'sdc-md',
154             backdrop: 'static',
155             keyboard: false,
156             resolve: {
157                 attribute: ():AttributeModel => {
158                     return atrribute;
159                 },
160                 component: ():Component => {
161                     return this.$scope.currentComponent;
162                 }
163             }
164         };
165         this.$uibModal.open(modalOptions);
166     };
167
168     private getComponentInstancesPropertiesAndAttributes = () => {
169
170         this.ComponentServiceNg2.getComponentInstanceAttributesAndProperties(this.$scope.currentComponent).subscribe((genericResponse:ComponentGenericResponse) => {
171             this.$scope.currentComponent.componentInstancesAttributes = genericResponse.componentInstancesAttributes;
172             this.$scope.currentComponent.componentInstancesProperties = genericResponse.componentInstancesProperties;
173             this.initScope();
174         });
175     };
176
177     private initScope = ():void => {
178
179
180         this.initComponentProperties();
181         this.initComponentAttributes();
182
183         this.$scope.$watchCollection('currentComponent.properties', (newData:any):void => {
184             this.initComponentProperties();
185         });
186
187         this.$scope.$watch('currentComponent.selectedInstance', (newInstance:ComponentInstance):void => {
188             if (angular.isDefined(newInstance)) {
189                 this.initComponentProperties();
190                 this.initComponentAttributes();
191
192             }
193         });
194
195         this.$scope.isPropertyOwner = ():boolean => {
196             return this.$scope.currentComponent && this.$scope.currentComponent.isResource() && !this.$scope.isComponentInstanceSelected();
197         };
198
199         this.$scope.updateProperty = (property:PropertyModel):void => {
200             this.openEditPropertyModal(property);
201         };
202
203         this.$scope.deleteProperty = (property:PropertyModel):void => {
204
205             let onOk = ():void => {
206                 this.$scope.currentComponent.deleteProperty(property.uniqueId);
207             };
208
209             let title:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TITLE");
210             let message:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TEXT", "{'name': '" + property.name + "'}");
211             this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk);
212         };
213
214         this.$scope.viewAttribute = (attribute:AttributeModel):void => {
215             this.openAttributeModal(attribute);
216         };
217
218         this.$scope.groupNameByKey = (key:string):string => {
219             switch (key) {
220                 case 'derived':
221                     return "Derived";
222
223                 case this.$scope.currentComponent.uniqueId:
224                     return this.$filter("resourceName")(this.$scope.currentComponent.name);
225
226                 default:
227                     return this.$filter("resourceName")((_.find(this.$scope.currentComponent.componentInstances, {uniqueId: key})).name);
228             }
229         };
230
231         this.$scope.getComponentInstanceNameFromInstanceByKey = (key:string):string => {
232             let instanceName:string = "";
233             if (key !== undefined && this.$scope.selectedComponent.uniqueId == this.$scope.currentComponent.selectedInstance.componentUid) {
234                 instanceName = this.$filter("resourceName")((_.find(this.$scope.selectedComponent.componentInstances, {uniqueId: key})).name);
235             }
236             return instanceName;
237         };
238
239     }
240 }