Sync Integ to Master
[sdc.git] / catalog-ui / src / app / view-models / workspace / tabs / composition / tabs / artifacts / artifacts-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     ArtifactModel,
25     Service,
26     IAppConfigurtaion,
27     Resource,
28     Component,
29     ComponentInstance,
30     ArtifactGroupModel,
31     IFileDownload
32 } from "app/models";
33 import {ICompositionViewModelScope} from "../../composition-view-model";
34 import {ArtifactsUtils, ModalsHandler, ArtifactGroupType} from "app/utils";
35 import {GRAPH_EVENTS} from "app/utils/constants";
36 import {EventListenerService} from "app/services/event-listener-service";
37 import {Dictionary} from "../../../../../../utils/dictionary/dictionary";
38
39 export interface IArtifactsViewModelScope extends ICompositionViewModelScope {
40     artifacts:Array<ArtifactModel>;
41     artifactType:string;
42     downloadFile:IFileDownload;
43     isLoading:boolean;
44     allowDeleteAndUpdateArtifactMap:Dictionary<string, boolean>;
45     getTitle():string;
46     addOrUpdate(artifact:ArtifactModel):void;
47     delete(artifact:ArtifactModel):void;
48     download(artifact:ArtifactModel):void;
49     openEditEnvParametersModal(artifact:ArtifactModel):void;
50     getEnvArtifact(heatArtifact:ArtifactModel):any;
51     getEnvArtifactName(artifact:ArtifactModel):string;
52     isLicenseArtifact(artifact:ArtifactModel):boolean;
53     //isVFiArtifact(artifact:ArtifactModel):boolean;
54 }
55
56 export class ResourceArtifactsViewModel {
57
58     static '$inject' = [
59         '$scope',
60         '$filter',
61         '$state',
62         'sdcConfig',
63         'ArtifactsUtils',
64         'ModalsHandler',
65         '$q',
66         'EventListenerService'
67     ];
68
69     constructor(private $scope:IArtifactsViewModelScope,
70                 private $filter:ng.IFilterService,
71                 private $state:any,
72                 private sdcConfig:IAppConfigurtaion,
73                 private artifactsUtils:ArtifactsUtils,
74                 private ModalsHandler:ModalsHandler,
75                 private $q:ng.IQService,
76                 private eventListenerService: EventListenerService) {
77
78         this.initScope();
79     }
80
81
82     private initArtifactArr = (artifactType:string):void => {
83         let artifacts:Array<ArtifactModel> = [];
84
85         if (this.$scope.selectedComponent) {
86             if ('interface' == artifactType) {
87                 let interfaces = this.$scope.currentComponent.interfaces;
88                 if (interfaces && interfaces.standard && interfaces.standard.operations) {
89
90                     angular.forEach(interfaces.standard.operations, (operation:any, interfaceName:string):void => {
91                         let item:ArtifactModel = <ArtifactModel>{};
92                         if (operation.implementation) {
93                             item = <ArtifactModel> operation.implementation;
94                         }
95                         item.artifactDisplayName = interfaceName;
96                         item.artifactLabel = interfaceName;
97                         item.mandatory = false;
98                         artifacts.push(item);
99                     });
100                 }
101             } else {
102                 //init normal artifacts, deployment or api artifacts
103                 let artifactsObj:ArtifactGroupModel;
104                 switch (artifactType) {
105                     case "api":
106                         artifactsObj = (<Service>this.$scope.currentComponent).serviceApiArtifacts;
107                         break;
108                     case "deployment":
109                         if (!this.$scope.isComponentInstanceSelected()) {
110                             artifactsObj = this.$scope.currentComponent.deploymentArtifacts;
111                         } else {
112                             artifactsObj = this.$scope.currentComponent.selectedInstance.deploymentArtifacts;
113                         }
114                         break;
115                     default:
116                         //artifactsObj = this.$scope.selectedComponent.artifacts;
117                         if (!this.$scope.isComponentInstanceSelected()) {
118                             artifactsObj = this.$scope.currentComponent.artifacts;
119                         } else {
120                             artifactsObj = this.$scope.currentComponent.selectedInstance.artifacts;
121                         }
122                         break;
123                 }
124                 _.forEach(artifactsObj, (artifact:ArtifactModel, key) => {
125                     artifacts.push(artifact);
126                 });
127             }
128         }
129         this.$scope.artifacts = artifacts;
130         this.$scope.allowDeleteAndUpdateArtifactMap = new Dictionary<string, boolean>();
131         _.forEach(this.$scope.artifacts, (artifact:ArtifactModel)=>{
132             this.$scope.allowDeleteAndUpdateArtifactMap[artifact.artifactLabel] = this.allowDeleteAndUpdateArtifact(artifact);
133         });
134         this.$scope.isLoading = false;
135         this.$scope.preventMoveTab(false);
136     };
137
138
139     private convertToArtifactUrl = (artifactType:string):string => {
140
141         switch (artifactType) {
142             case 'deployment':
143                 return 'DEPLOYMENT';
144             case 'api':
145                 return 'SERVICE_API';
146             default:
147                 return 'INFORMATIONAL';
148         }
149
150     }
151
152     private loadComponentArtifactIfNeeded = (forceLoad?: boolean) => {
153
154         let onGetComponentArtifactsSuccess = (artifacts:ArtifactGroupModel)=> {
155             switch (this.$scope.artifactType) {
156                 case 'deployment':
157                     this.$scope.currentComponent.deploymentArtifacts = artifacts;
158                     break;
159                 case 'api':
160                     (<Service>this.$scope.currentComponent).serviceApiArtifacts = artifacts;
161                     break;
162                 default:
163                     this.$scope.currentComponent.artifacts = artifacts;
164                     break;
165             }
166             this.$scope.isLoading = false;
167             this.initArtifactArr(this.$scope.artifactType);
168         }
169
170         let onError = ()=> {
171             this.$scope.isLoading = false;
172         };
173
174         switch (this.$scope.artifactType) {
175             case 'deployment':
176                 if(forceLoad || !this.$scope.currentComponent.deploymentArtifacts) {
177                     this.$scope.component.getArtifactByGroupType(this.convertToArtifactUrl(this.$scope.artifactType)).then(onGetComponentArtifactsSuccess, onError);
178                 } else {
179                     this.initArtifactArr(this.$scope.artifactType);
180                 }
181
182                 break;
183             case 'api':
184                 if(!(<Service>this.$scope.currentComponent).serviceApiArtifacts) {
185                     this.$scope.component.getArtifactByGroupType(this.convertToArtifactUrl(this.$scope.artifactType)).then(onGetComponentArtifactsSuccess, onError);
186                 } else {
187                     this.initArtifactArr(this.$scope.artifactType);
188                 }
189                 break;
190             default:
191                 if(!this.$scope.currentComponent.artifacts) {
192                     this.$scope.component.getArtifactByGroupType(this.convertToArtifactUrl(this.$scope.artifactType)).then(onGetComponentArtifactsSuccess, onError);
193                 } else {
194                     this.initArtifactArr(this.$scope.artifactType);
195                 }
196                 break;
197         }
198     }
199     private loadArtifacts = (forceLoad?: boolean):void => {
200
201         let onGetInstanceArtifactsSuccess = (artifacts:ArtifactGroupModel)=> {
202             switch (this.$scope.artifactType) {
203                 case 'deployment':
204                     this.$scope.currentComponent.selectedInstance.deploymentArtifacts = artifacts;
205                     break;
206                 default:
207                     this.$scope.currentComponent.selectedInstance.artifacts = artifacts;
208                     break;
209             }
210             this.initArtifactArr(this.$scope.artifactType);
211         };
212
213         let onError = ()=> {
214             this.$scope.isLoading = false;
215         };
216
217         this.$scope.isLoading = true;
218         this.$scope.preventMoveTab(true);
219         if (this.$scope.isComponentInstanceSelected()) {
220             this.$scope.component.getComponentInstanceArtifactsByGroupType(this.$scope.component.selectedInstance.uniqueId, this.convertToArtifactUrl(this.$scope.artifactType)).then(onGetInstanceArtifactsSuccess, onError);
221         } else {
222             this.loadComponentArtifactIfNeeded(forceLoad);
223         }
224     }
225
226     private updateArtifactsIfNeeded = ():void => {
227         if (this.$scope.artifactType === "deployment") {
228             this.loadArtifacts(true);
229         } else {
230             this.initArtifactArr(this.$scope.artifactType);
231         }
232     };
233
234     private openEditArtifactModal = (artifact:ArtifactModel):void => {
235         this.ModalsHandler.openArtifactModal(artifact, this.$scope.currentComponent).then(():void => {
236             this.updateArtifactsIfNeeded();
237         });
238     };
239
240     private allowDeleteAndUpdateArtifact = (artifact:ArtifactModel):boolean => {
241     if(!this.$scope.isViewMode()){
242         if(this.$scope.isComponentInstanceSelected()){//is artifact of instance
243             return !this.$scope.selectedComponent.deploymentArtifacts || !this.$scope.selectedComponent.deploymentArtifacts[artifact.artifactLabel];//if the artifact is not from instance parent
244         }else{//is artifact of main component
245             return (!artifact.isHEAT() && !artifact.isThirdParty() && !this.$scope.isLicenseArtifact(artifact));
246         }
247     }
248     return false;
249 };
250
251     private initScope = ():void => {
252
253         this.$scope.isLoading = false;
254         this.$scope.artifactType = this.artifactsUtils.getArtifactTypeByState(this.$state.current.name);
255         this.$scope.getTitle = ():string => {
256             return this.artifactsUtils.getTitle(this.$scope.artifactType, this.$scope.currentComponent);
257         };
258
259         // Bug 310499 - user should be unable to delete RI artifact. (also talked to David and agreed this function isn't necessary)
260         // this.$scope.isVFiArtifact = (artifact:ArtifactModel):boolean=> {
261         //     if (artifact.artifactGroupType === ArtifactGroupType.INFORMATION) {//fix DE256847
262         //         return this.$scope.currentComponent.artifacts && (!this.$scope.currentComponent.artifacts[artifact.artifactLabel] || !this.$scope.currentComponent.artifacts[artifact.artifactLabel].artifactName);
263         //     }
264         //     return this.$scope.currentComponent.selectedInstance && this.$scope.currentComponent.selectedInstance.deploymentArtifacts && this.$scope.currentComponent.selectedInstance.deploymentArtifacts[artifact.artifactLabel];
265         // };
266
267         this.$scope.addOrUpdate = (artifact:ArtifactModel):void => {
268             this.artifactsUtils.setArtifactType(artifact, this.$scope.artifactType);
269             let artifactCopy = new ArtifactModel(artifact);
270             this.openEditArtifactModal(artifactCopy);
271         };
272
273
274         this.$scope.delete = (artifact:ArtifactModel):void => {
275
276             let onOk = ():void => {
277                 this.$scope.isLoading = true;
278                 this.artifactsUtils.removeArtifact(artifact, this.$scope.artifacts);
279
280                 let success = (responseArtifact:ArtifactModel):void => {
281                     this.initArtifactArr(this.$scope.artifactType);
282                     this.$scope.isLoading = false;
283                 };
284
285                 let error = (error:any):void => {
286                     console.log('Delete artifact returned error:', error);
287                     this.initArtifactArr(this.$scope.artifactType);
288                     this.$scope.isLoading = false;
289                 };
290                 if (this.$scope.isComponentInstanceSelected()) {
291                     this.$scope.currentComponent.deleteInstanceArtifact(artifact.uniqueId, artifact.artifactLabel).then(success, error);
292                 } else {
293                     this.$scope.currentComponent.deleteArtifact(artifact.uniqueId, artifact.artifactLabel).then(success, error);//TODO simulate error (make sure error returns)
294                 }
295             };
296             let title:string = this.$filter('translate')("ARTIFACT_VIEW_DELETE_MODAL_TITLE");
297             let message:string = this.$filter('translate')("ARTIFACT_VIEW_DELETE_MODAL_TEXT", "{'name': '" + artifact.artifactDisplayName + "'}");
298             this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk);
299         };
300
301
302         this.$scope.getEnvArtifact = (heatArtifact:ArtifactModel):any=> {
303             return _.find(this.$scope.artifacts, (item:ArtifactModel)=> {
304                 return item.generatedFromId === heatArtifact.uniqueId;
305             });
306         };
307
308         this.$scope.getEnvArtifactName = (artifact:ArtifactModel):string => {
309             let envArtifact = this.$scope.getEnvArtifact(artifact);
310             if (envArtifact) {
311                 return envArtifact.artifactDisplayName;
312             }
313         };
314
315         this.$scope.isLicenseArtifact = (artifact:ArtifactModel):boolean => {
316             let isLicense:boolean = false;
317             if (this.$scope.component.isResource() && (<Resource>this.$scope.component).isCsarComponent()) {
318                 isLicense = this.artifactsUtils.isLicenseType(artifact.artifactType);
319             }
320
321             return isLicense;
322         };
323
324         this.$scope.openEditEnvParametersModal = (artifact:ArtifactModel):void => {
325             this.ModalsHandler.openEditEnvParametersModal(artifact, this.$scope.currentComponent).then(()=> {
326                 this.updateArtifactsIfNeeded();
327             }, ()=> {
328                 // ERROR
329             });
330         };
331
332         this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_NODE_SELECTED, this.loadArtifacts);
333         this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED, this.loadArtifacts);
334
335         this.$scope.$on('$destroy', () => {
336
337             this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_NODE_SELECTED, this.loadArtifacts);
338             this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED, this.loadArtifacts);
339         });
340
341         this.loadArtifacts();
342     }
343 }