CSIT Fix for SDC-2585
[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(), "component", property.resourceInstanceUniqueId).then((updatedProperty:PropertyModel) => {
143                 if(updatedProperty){
144                     let oldProp = _.find(this.$scope.properties[updatedProperty.resourceInstanceUniqueId], (prop:PropertyModel) => {return prop.uniqueId == updatedProperty.uniqueId;});
145                     oldProp.value = updatedProperty.value;
146                 }
147         });
148     };
149
150     private openAttributeModal = (atrribute:AttributeModel):void => {
151
152         let modalOptions:ng.ui.bootstrap.IModalSettings = {
153             template: 'app/view-models/forms/attribute-form/attribute-form-view.html',
154             controller: 'Sdc.ViewModels.AttributeFormViewModel',
155             size: 'sdc-md',
156             backdrop: 'static',
157             keyboard: false,
158             resolve: {
159                 attribute: ():AttributeModel => {
160                     return atrribute;
161                 },
162                 component: ():Component => {
163                     return this.$scope.currentComponent;
164                 }
165             }
166         };
167         this.$uibModal.open(modalOptions);
168     };
169
170     private getComponentInstancesPropertiesAndAttributes = () => {
171
172         this.ComponentServiceNg2.getComponentInstanceAttributesAndProperties(this.$scope.currentComponent).subscribe((genericResponse:ComponentGenericResponse) => {
173             this.$scope.currentComponent.componentInstancesAttributes = genericResponse.componentInstancesAttributes;
174             this.$scope.currentComponent.componentInstancesProperties = genericResponse.componentInstancesProperties;
175             this.initScope();
176         });
177     };
178
179     private initScope = ():void => {
180
181
182         this.initComponentProperties();
183         this.initComponentAttributes();
184
185         this.$scope.$watchCollection('currentComponent.properties', (newData:any):void => {
186             this.initComponentProperties();
187         });
188
189         this.$scope.$watch('currentComponent.selectedInstance', (newInstance:ComponentInstance):void => {
190             if (angular.isDefined(newInstance)) {
191                 this.initComponentProperties();
192                 this.initComponentAttributes();
193
194             }
195         });
196
197         this.$scope.isPropertyOwner = ():boolean => {
198             return this.$scope.currentComponent && this.$scope.currentComponent.isResource() && !this.$scope.isComponentInstanceSelected();
199         };
200
201         this.$scope.updateProperty = (property:PropertyModel):void => {
202             this.openEditPropertyModal(property);
203         };
204
205         this.$scope.deleteProperty = (property:PropertyModel):void => {
206
207             let onOk = ():void => {
208                 this.$scope.currentComponent.deleteProperty(property.uniqueId);
209             };
210
211             let title:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TITLE");
212             let message:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TEXT", "{'name': '" + property.name + "'}");
213             this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk);
214         };
215
216         this.$scope.viewAttribute = (attribute:AttributeModel):void => {
217             this.openAttributeModal(attribute);
218         };
219
220         this.$scope.groupNameByKey = (key:string):string => {
221             switch (key) {
222                 case 'derived':
223                     return "Derived";
224
225                 case this.$scope.currentComponent.uniqueId:
226                     return this.$filter("resourceName")(this.$scope.currentComponent.name);
227
228                 default:
229                     let componentInstance = _.find(this.$scope.currentComponent.componentInstances, {uniqueId: key});
230                     if(componentInstance)
231                         return this.$filter("resourceName")(componentInstance.name);
232             }
233         };
234
235         this.$scope.getComponentInstanceNameFromInstanceByKey = (key:string):string => {
236             let instanceName:string = "";
237             if (key !== undefined && this.$scope.selectedComponent.uniqueId == this.$scope.currentComponent.selectedInstance.componentUid) {
238                 instanceName = this.$filter("resourceName")((_.find(this.$scope.selectedComponent.componentInstances, {uniqueId: key})).name);
239             }
240             return instanceName;
241         };
242
243     }
244 }