[sdc] rebase update
[sdc.git] / catalog-ui / src / app / view-models / forms / artifact-form / artifact-form-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 {ArtifactModel, Resource, Component} from "app/models";
23 import {ArtifactsUtils, FormState, ValidationUtils, ArtifactType} from "app/utils";
24 import {CacheService} from "app/services";
25
26 export interface IEditArtifactModel {
27     artifactResource:ArtifactModel;
28     artifactTypes:Array<string>;
29     artifactFile:any;
30 }
31
32 export interface IArtifactResourceFormViewModelScope extends ng.IScope {
33     forms:any;
34     $$childTail:any;
35     isNew:boolean;
36     isLoading:boolean;
37     validationPattern:RegExp;
38     urlValidationPattern:RegExp;
39     labelValidationPattern:RegExp;
40     integerValidationPattern:RegExp;
41     commentValidationPattern:RegExp;
42     artifactType:string;
43     editArtifactResourceModel:IEditArtifactModel;
44     defaultHeatTimeout:number;
45     validExtensions:any;
46     originalArtifactName:string;
47     editForm:ng.IFormController;
48     footerButtons:Array<any>;
49     modalInstanceArtifact:ng.ui.bootstrap.IModalServiceInstance;
50
51     fileExtensions():string;
52     save(doNotCloseModal?:boolean):void;
53     saveAndAnother():void;
54     close():void;
55     getOptions():Array<string>;
56     isDeploymentHeat():boolean;
57     onFileChange():void;
58     setDefaultTimeout():void;
59     openEditEnvParametersModal(artifact:ArtifactModel):void;
60     getFormTitle():string;
61     fileUploadRequired():string;
62     isArtifactOwner():boolean;
63 }
64
65 export class ArtifactResourceFormViewModel {
66
67     static '$inject' = [
68         '$scope',
69         '$uibModalInstance',
70         'artifact',
71         'Sdc.Services.CacheService',
72         'ValidationPattern',
73         'UrlValidationPattern',
74         'LabelValidationPattern',
75         'IntegerValidationPattern',
76         'CommentValidationPattern',
77         'ValidationUtils',
78         '$base64',
79         '$state',
80         'ArtifactsUtils',
81         '$uibModal',
82         'component'
83     ];
84
85     private formState:FormState;
86     private entityId:string;
87
88     constructor(private $scope:IArtifactResourceFormViewModelScope,
89                 private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance,
90                 private artifact:ArtifactModel,
91                 private cacheService:CacheService,
92                 private ValidationPattern:RegExp,
93                 private UrlValidationPattern:RegExp,
94                 private LabelValidationPattern:RegExp,
95                 private IntegerValidationPattern:RegExp,
96                 private CommentValidationPattern:RegExp,
97                 private ValidationUtils:ValidationUtils,
98                 private $base64:any,
99                 private $state:any,
100                 private artifactsUtils:ArtifactsUtils,
101                 private $uibModal:ng.ui.bootstrap.IModalService,
102                 private component:Component) {
103
104
105         this.entityId = this.component.uniqueId;
106         this.formState = angular.isDefined(artifact.artifactLabel) ? FormState.UPDATE : FormState.CREATE;
107         this.initScope();
108     }
109
110     private initEntity = ():void => {
111         this.$scope.editArtifactResourceModel.artifactResource = this.artifact;
112         this.$scope.originalArtifactName = this.artifact.artifactName;
113     };
114
115
116     private initFooterButtons = ():void => {
117
118         this.$scope.footerButtons = [
119             {'name': 'Done', 'css': 'blue', 'callback': this.$scope.save}
120         ];
121         if (this.$scope.isNew) {
122             this.$scope.footerButtons.push({
123                 'name': 'Add Another',
124                 'css': 'grey',
125                 'disabled': !this.$scope.isNew && 'deployment' === this.$scope.artifactType,
126                 'callback': this.$scope.saveAndAnother
127             });
128         }
129     };
130
131     private filterDeploymentArtifactTypeByResourceType = (resourceType:string):any => {
132         let result = {};
133         _.each(this.$scope.validExtensions, function (typeSettings:any, typeName:string) {
134             if (!typeSettings.validForResourceTypes || typeSettings.validForResourceTypes.indexOf(resourceType) > -1) {
135                 result[typeName] = typeSettings;
136             }
137         });
138
139         return result;
140     };
141
142     private initArtifactTypes = ():void => {
143
144         let artifactTypes:any = this.cacheService.get('UIConfiguration');
145
146         if ('deployment' === this.$scope.artifactType) {
147
148
149             if ('HEAT_ENV' == this.artifact.artifactType || this.component.selectedInstance) {
150                 this.$scope.validExtensions = artifactTypes.artifacts.deployment.resourceInstanceDeploymentArtifacts;
151             } else if (this.component.isResource()) {
152                 this.$scope.validExtensions = artifactTypes.artifacts.deployment.resourceDeploymentArtifacts;
153                 this.$scope.validExtensions = this.filterDeploymentArtifactTypeByResourceType((<Resource>this.component).resourceType);
154             } else {
155                 this.$scope.validExtensions = artifactTypes.artifacts.deployment.serviceDeploymentArtifacts;
156             }
157
158             if (this.$scope.validExtensions) {
159                 this.$scope.editArtifactResourceModel.artifactTypes = Object.keys(this.$scope.validExtensions);
160             }
161             this.$scope.defaultHeatTimeout = artifactTypes.defaultHeatTimeout;
162             if (this.$scope.isNew) {
163                 let isHeat = 'HEAT_ENV' == this.artifact.artifactType;
164                 _.remove(this.$scope.editArtifactResourceModel.artifactTypes, (item:string)=> {
165                     return 'HEAT' == item.substring(0, 4) || (!isHeat && item == "VF_MODULES_METADATA") ||
166                         _.has(ArtifactType.THIRD_PARTY_RESERVED_TYPES, item);
167                 });
168             }
169
170         }
171         if (this.$scope.artifactType === 'informational') {
172             this.$scope.editArtifactResourceModel.artifactTypes = artifactTypes.artifacts.other.map((element:any)=> {
173                 return element.name;
174             });
175             _.remove(this.$scope.editArtifactResourceModel.artifactTypes, (item:string)=> {
176                 return _.has(ArtifactType.THIRD_PARTY_RESERVED_TYPES, item) ||
177                     _.has(ArtifactType.TOSCA, item);
178             })
179         }
180
181         if (this.component.isResource() && (<Resource>this.component).isCsarComponent()) {
182             _.remove(this.$scope.editArtifactResourceModel.artifactTypes, (item:string) => {
183                 return this.artifactsUtils.isLicenseType(item);
184             })
185         }
186
187     };
188
189     private initEditArtifactResourceModel = ():void => {
190         this.$scope.editArtifactResourceModel = {
191             artifactResource: null,
192             artifactTypes: null,
193             artifactFile: {}
194         };
195
196         this.initEntity();
197     };
198
199     private initScope = ():void => {
200
201         this.$scope.validationPattern = this.ValidationPattern;
202         this.$scope.urlValidationPattern = this.UrlValidationPattern;
203         this.$scope.labelValidationPattern = this.LabelValidationPattern;
204         this.$scope.integerValidationPattern = this.IntegerValidationPattern;
205         this.$scope.commentValidationPattern = this.CommentValidationPattern;
206         this.$scope.isLoading = false;
207         this.$scope.isNew = (this.formState === FormState.CREATE);
208         this.$scope.artifactType = this.artifactsUtils.getArtifactTypeByState(this.$state.current.name);
209         this.$scope.modalInstanceArtifact = this.$uibModalInstance;
210
211         this.initEditArtifactResourceModel();
212         this.initArtifactTypes();
213
214         // In case of edit, show the file name in browse.
215         if (this.artifact.artifactName !== "" && 'HEAT_ENV' !== this.artifact.artifactType) {
216             this.$scope.editArtifactResourceModel.artifactFile = {};
217             this.$scope.editArtifactResourceModel.artifactFile.filename = this.artifact.artifactName;
218         }
219
220         //scope methods
221         this.$scope.isDeploymentHeat = ():boolean => {
222             return !this.$scope.isNew && this.$scope.artifactType === 'deployment'
223                 && this.$scope.editArtifactResourceModel.artifactResource.isHEAT();
224
225         };
226         this.$scope.onFileChange = ():void => {
227             if (this.$scope.editArtifactResourceModel.artifactFile && this.$scope.editArtifactResourceModel.artifactFile.filename) {
228                 this.$scope.editArtifactResourceModel.artifactResource.artifactName = this.$scope.editArtifactResourceModel.artifactFile.filename;
229             } else {
230                 this.$scope.editArtifactResourceModel.artifactResource.artifactName = this.$scope.originalArtifactName;
231             }
232         };
233         this.$scope.setDefaultTimeout = ():void => {
234             if (this.$scope.isDeploymentHeat() && !this.$scope.editArtifactResourceModel.artifactResource.timeout) {
235                 this.$scope.editArtifactResourceModel.artifactResource.timeout = this.$scope.defaultHeatTimeout;
236             }
237
238             if (this.$scope.editArtifactResourceModel.artifactFile.filename) {
239                 this.$scope.editArtifactResourceModel.artifactFile = {};
240                 this.$scope.forms.editForm.myArtifactFile.$setValidity('required', false);
241             }
242         };
243
244         this.$scope.fileExtensions = ():string => {
245             let type:string = this.$scope.editArtifactResourceModel.artifactResource.artifactType;
246             return type && this.$scope.validExtensions && this.$scope.validExtensions[type].acceptedTypes ?
247                 this.$scope.validExtensions[type].acceptedTypes.join(',') : "";
248         };
249
250         this.$scope.save = (doNotCloseModal?:boolean):void => {
251             this.$scope.isLoading = true;
252             this.$scope.editArtifactResourceModel.artifactResource.description = this.ValidationUtils.stripAndSanitize(this.$scope.editArtifactResourceModel.artifactResource.description);
253
254             if (!this.$scope.isDeploymentHeat()) {
255                 this.$scope.editArtifactResourceModel.artifactResource.timeout = null;
256             }
257
258             if (this.$scope.editArtifactResourceModel.artifactFile) {
259                 this.$scope.editArtifactResourceModel.artifactResource.payloadData = this.$scope.editArtifactResourceModel.artifactFile.base64;
260                 this.$scope.editArtifactResourceModel.artifactResource.artifactName = this.$scope.editArtifactResourceModel.artifactFile.filename;
261             }
262
263             let onFaild = (response):void => {
264                 this.$scope.isLoading = false;
265                 console.info('onFaild', response);
266             };
267
268             let onSuccess = (artifactResource:ArtifactModel):void => {
269                 this.$scope.isLoading = false;
270                 this.$scope.originalArtifactName = "";
271
272                 if (this.$scope.isDeploymentHeat()) {
273                     if (artifactResource.heatParameters) {
274                         this.$scope.openEditEnvParametersModal(artifactResource);
275                     }
276                 }
277
278                 if (!doNotCloseModal) {
279                     this.$uibModalInstance.close();
280                 } else {
281                     this.$scope.editArtifactResourceModel.artifactFile = null;
282                     angular.element("input[type='file']").val(null); //  for support chrome when upload the same file
283                     this.artifactsUtils.addAnotherAfterSave(this.$scope);
284                 }
285
286             };
287
288             if ('HEAT_ENV' == this.artifact.artifactType) {
289                 if (this.component.selectedInstance) {
290                     this.component.uploadInstanceEnvFile(this.$scope.editArtifactResourceModel.artifactResource).then(onSuccess, onFaild);
291                 } else {
292                     this.component.addOrUpdateArtifact(this.$scope.editArtifactResourceModel.artifactResource).then(onSuccess, onFaild);
293
294                 }
295             } else if (this.$scope.isArtifactOwner()) {
296                 this.component.addOrUpdateInstanceArtifact(this.$scope.editArtifactResourceModel.artifactResource).then(onSuccess, onFaild);
297             } else {
298                 this.component.addOrUpdateArtifact(this.$scope.editArtifactResourceModel.artifactResource).then(onSuccess, onFaild);
299             }
300         };
301
302         this.$scope.isArtifactOwner = ():boolean=> {
303             return this.component.isService() && !!this.component.selectedInstance;
304         };
305
306         this.$scope.saveAndAnother = ():void => {
307             this.$scope.save(true);
308         };
309
310         this.$scope.close = ():void => {
311             this.$uibModalInstance.close();
312         };
313
314         this.$scope.fileUploadRequired = ():string => {
315             if (this.$scope.editArtifactResourceModel.artifactFile.filename) {
316                 // This is edit mode
317                 return 'false';
318             } else {
319                 return 'true';
320             }
321         };
322
323         this.$scope.getFormTitle = ():string => {
324             if ('HEAT_ENV' == this.artifact.artifactType) {
325                 return 'Update HEAT ENV';
326             }
327             if (this.$scope.isDeploymentHeat()) {
328                 if (!this.$scope.editArtifactResourceModel.artifactResource.artifactChecksum) {
329                     return 'Add HEAT Template';
330                 }
331                 return 'Update HEAT Template';
332             }
333             if (this.$scope.isNew) {
334                 return 'Add Artifact';
335             }
336             return 'Update Artifact';
337         };
338
339         this.$scope.openEditEnvParametersModal = (artifactResource:ArtifactModel):void => {
340
341             let modalOptions:ng.ui.bootstrap.IModalSettings = {
342                 templateUrl: '../env-parameters-form/env-parameters-form.html',
343                 controller: 'Sdc.ViewModels.EnvParametersFormViewModel',
344                 size: 'sdc-md',
345                 backdrop: 'static',
346                 resolve: {
347                     artifact: ():ArtifactModel => {
348                         return artifactResource;
349                     },
350                     component: ():Component => {
351                         return this.component;
352                     }
353                 }
354             };
355
356             let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions);
357             modalInstance
358                 .result
359                 .then(():void => {
360                 });
361         };
362
363         this.$scope.forms = {};
364
365         this.initFooterButtons();
366
367
368         this.$scope.$watch("forms.editForm.$invalid", (newVal, oldVal) => {
369             if(this.$scope.forms.editForm) {
370                 this.$scope.footerButtons[0].disabled = this.$scope.forms.editForm.$invalid;
371                 if (this.$scope.isNew) {
372                     this.$scope.footerButtons[1].disabled = this.$scope.forms.editForm.$invalid;
373                 }
374             }
375         });
376
377     }
378 }