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