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