Catalog alignment
[sdc.git] / catalog-ui / src / app / view-models / workspace / tabs / general / general-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 {ModalsHandler, ValidationUtils, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FLAG, ComponentType, DEFAULT_ICON,
24     ResourceType, ComponentState, instantiationType, ComponentFactory} from "app/utils";
25 import { EventListenerService, ProgressService} from "app/services";
26 import {CacheService, OnboardingService, ImportVSPService} from "app/services-ng2";
27 import {IAppConfigurtaion, IValidate, IMainCategory, Resource, ISubCategory,Service, ICsarComponent, Component} from "app/models";
28 import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model";
29 import {Dictionary} from "lodash";
30 import { PREVIOUS_CSAR_COMPONENT } from "../../../../utils/constants";
31 import { Observable, Subject } from "rxjs";
32
33
34 export class Validation {
35     componentNameValidationPattern:RegExp;
36     contactIdValidationPattern:RegExp;
37     tagValidationPattern:RegExp;
38     VendorReleaseValidationPattern:RegExp;
39     VendorNameValidationPattern:RegExp;
40     VendorModelNumberValidationPattern:RegExp;
41     commentValidationPattern:RegExp;
42 }
43
44 export class componentCategories {//categories field bind to this obj in order to solve this bug: DE242059
45     selectedCategory:string;
46 }
47
48 export interface IEnvironmentContext {
49     defaultValue:string;
50     validValues:Array<string>;
51 }
52
53 export interface IGeneralScope extends IWorkspaceViewModelScope {
54     validation:Validation;
55     editForm:ng.IFormController;
56     categories:Array<IMainCategory>;
57     environmentContextObj:IEnvironmentContext;
58     latestCategoryId:string;
59     latestVendorName:string;
60     importedFileExtension:any;
61     isCreate:boolean;
62     isShowFileBrowse:boolean;
63     isShowOnboardingSelectionBrowse:boolean;
64     importedToscaBrowseFileText:string;
65     importCsarProProgressKey:string;
66     browseFileLabel:string;
67     componentCategories:componentCategories;
68     instantiationTypes:Array<instantiationType>;
69     isHiddenCategorySelected: boolean;
70
71     save():Promise<any>;
72     revert():void;
73     onImportFileChange():void;
74     validateField(field:any):boolean;
75     validateName(isInit:boolean):void;
76     calculateUnique(mainCategory:string, subCategory:string):string; // Build unique string from main and sub category
77     onVendorNameChange(oldVendorName:string):void;
78     convertCategoryStringToOneArray(category:string, subcategory:string):Array<IMainCategory>;
79     onCategoryChange():void;
80     onEcompGeneratedNamingChange():void;
81     openOnBoardingModal():void;
82     initCategoreis():void;
83     initEnvironmentContext():void;
84     initInstantiationTypes():void;
85     onInstantiationTypeChange():void;
86     updateIcon():void;
87     possibleToUpdateIcon():boolean;
88 }
89
90 // tslint:disable-next-line:max-classes-per-file
91 export class GeneralViewModel {
92
93     static '$inject' = [
94         '$scope',
95         'Sdc.Services.CacheService',
96         'ComponentNameValidationPattern',
97         'ContactIdValidationPattern',
98         'TagValidationPattern',
99         'VendorReleaseValidationPattern',
100         'VendorNameValidationPattern',
101         'VendorModelNumberValidationPattern',
102         'CommentValidationPattern',
103         'ValidationUtils',
104         'sdcConfig',
105         '$state',
106         'ModalsHandler',
107         'EventListenerService',
108         'Notification',
109         'Sdc.Services.ProgressService',
110         '$interval',
111         '$filter',
112         '$timeout',
113         'OnboardingService',
114         'ComponentFactory',
115         'ImportVSPService',
116         '$stateParams'
117     ];
118
119     constructor(private $scope:IGeneralScope,
120                 private cacheService:CacheService,
121                 private ComponentNameValidationPattern:RegExp,
122                 private ContactIdValidationPattern:RegExp,
123                 private TagValidationPattern:RegExp,
124                 private VendorReleaseValidationPattern:RegExp,
125                 private VendorNameValidationPattern:RegExp,
126                 private VendorModelNumberValidationPattern:RegExp,
127                 private CommentValidationPattern:RegExp,
128                 private ValidationUtils:ValidationUtils,
129                 private sdcConfig:IAppConfigurtaion,
130                 private $state:ng.ui.IStateService,
131                 private ModalsHandler:ModalsHandler,
132                 private EventListenerService:EventListenerService,
133                 private Notification:any,
134                 private progressService:ProgressService,
135                 protected $interval:any,
136                 private $filter:ng.IFilterService,
137                 private $timeout:ng.ITimeoutService,
138                 private onBoardingService: OnboardingService,
139                 private ComponentFactory:ComponentFactory,
140                 private importVSPService: ImportVSPService,
141                 private $stateParams: any) {
142
143         this.initScopeValidation();
144         this.initScopeMethods();
145         this.initScope();
146     }
147
148
149
150
151     private initScopeValidation = ():void => {
152         this.$scope.validation = new Validation();
153         this.$scope.validation.componentNameValidationPattern = this.ComponentNameValidationPattern;
154         this.$scope.validation.contactIdValidationPattern = this.ContactIdValidationPattern;
155         this.$scope.validation.tagValidationPattern = this.TagValidationPattern;
156         this.$scope.validation.VendorReleaseValidationPattern = this.VendorReleaseValidationPattern;
157         this.$scope.validation.VendorNameValidationPattern = this.VendorNameValidationPattern;
158         this.$scope.validation.VendorModelNumberValidationPattern = this.VendorModelNumberValidationPattern;
159         this.$scope.validation.commentValidationPattern = this.CommentValidationPattern;
160     };
161
162     private loadOnboardingFileCache = (): Observable<Dictionary<Dictionary<string>>> => {
163         let onboardCsarFilesMap:Dictionary<Dictionary<string>>;
164         let onSuccess = (vsps:Array<ICsarComponent>) => {
165             onboardCsarFilesMap = {};
166             _.each(vsps, (vsp:ICsarComponent)=>{
167                 onboardCsarFilesMap[vsp.packageId] = onboardCsarFilesMap[vsp.packageId] || {};
168                 onboardCsarFilesMap[vsp.packageId][vsp.version] = vsp.vspName + " (" + vsp.version + ")";
169             });
170             this.cacheService.set('onboardCsarFilesMap', onboardCsarFilesMap);
171             return onboardCsarFilesMap;
172         };
173         let onError = (): void =>{
174             console.log("Error getting onboarding list");
175         };
176         return this.onBoardingService.getOnboardingVSPs().map(onSuccess, onError);
177     };
178
179     private setImportedFileText = ():void => {
180
181         if(!this.$scope.isShowOnboardingSelectionBrowse) return;
182
183         //these variables makes it easier to read this logic
184         let csarUUID:string = (<Resource>this.$scope.component).csarUUID;
185         let csarVersion:string = (<Resource>this.$scope.component).csarVersion;
186
187         let onboardCsarFilesMap:Dictionary<Dictionary<string>> = this.cacheService.get('onboardCsarFilesMap');
188         let assignFileName = ():void => {
189             if(this.$scope.component.vspArchived){
190                 this.$scope.importedToscaBrowseFileText = 'VSP is archived';
191             } else {
192                 if(this.$stateParams.componentCsar && this.$scope.component.lifecycleState === 'NOT_CERTIFIED_CHECKIN' && !this.$scope.isCreateMode()) {
193                     this.$scope.importedToscaBrowseFileText = this.$scope.originComponent.name + ' (' + (this.$scope.originComponent as Resource).csarVersion + ')';
194                 } else {
195                     this.$scope.importedToscaBrowseFileText = onboardCsarFilesMap[csarUUID][csarVersion];
196                 }
197             }
198         }
199
200
201         if(this.$scope.component.vspArchived || (onboardCsarFilesMap && onboardCsarFilesMap[csarUUID] && onboardCsarFilesMap[csarUUID][csarVersion])){ //check that the file name is already in cache
202             assignFileName();
203         } else {
204             this.loadOnboardingFileCache().subscribe((onboardingFiles) => {
205                 onboardCsarFilesMap = onboardingFiles;
206                 this.cacheService.set('onboardCsarFilesMap', onboardingFiles);
207                 assignFileName();
208             }, ()=> {});
209         }
210
211     }
212
213     isCreateModeAvailable(verifyObj:string): boolean {
214         var isCheckout:boolean = ComponentState.NOT_CERTIFIED_CHECKOUT === this.$scope.component.lifecycleState;
215         return this.$scope.isCreateMode() || (isCheckout && !verifyObj)
216     }
217
218     private initScope = ():void => {
219
220         this.$scope.importCsarProgressKey = "importCsarProgressKey";
221
222         this.$scope.browseFileLabel = this.$scope.component.isResource() && (<Resource>this.$scope.component).resourceType === ResourceType.VF ? 'VSP' : 'Upload VFC';
223         this.$scope.progressService = this.progressService;
224         this.$scope.componentCategories = new componentCategories();
225         this.$scope.componentCategories.selectedCategory = this.$scope.component.selectedCategory;
226
227         // Init UIModel
228         this.$scope.component.tags = _.without(this.$scope.component.tags, this.$scope.component.name);
229
230         // Init categories
231         this.$scope.initCategoreis();
232
233         // Init Environment Context
234         this.$scope.initEnvironmentContext();
235
236         // Init the decision if to show file browse.
237         this.$scope.isShowFileBrowse = false;
238         if (this.$scope.component.isResource()) {
239             let resource:Resource = <Resource>this.$scope.component;
240             console.log(resource.name + ": " + resource.csarUUID);
241             if (resource.importedFile) { // Component has imported file.
242                 this.$scope.isShowFileBrowse = true;
243             }
244             if (resource.resourceType === ResourceType.VF && !resource.csarUUID) {
245                 this.$scope.isShowFileBrowse = true;
246             }
247         } else if(this.$scope.component.isService()){
248             // Init Instantiation types
249             this.$scope.initInstantiationTypes();
250         }
251
252         if (this.cacheService.get(PREVIOUS_CSAR_COMPONENT)) { //keep the old component in the cache until checkout, so we dont need to pass it around
253             this.$scope.setOriginComponent(this.cacheService.get(PREVIOUS_CSAR_COMPONENT));
254             this.cacheService.remove(PREVIOUS_CSAR_COMPONENT);
255         }
256
257         if (this.$stateParams.componentCsar && !this.$scope.isCreateMode()) {
258             this.$scope.updateUnsavedFileFlag(true);
259             // We are coming from update VSP modal we need to automatically checkout (if needed) and save the VF
260             if (this.$scope.component.lifecycleState !== ComponentState.NOT_CERTIFIED_CHECKOUT) {
261                 // Checkout is needed after that a save will be invoked in workspace-view.handleLifeCycleStateChange
262                 this.EventListenerService.notifyObservers(EVENTS.ON_LIFECYCLE_CHANGE_WITH_SAVE, 'checkOut');
263                 // if(this.$scope.component.lifecycleState !== 'NOT_CERTIFIED_CHECKIN') {
264                 //     (<Resource>this.$scope.component).csarVersion = this.$stateParams.componentCsar.csarVersion;
265                 // }
266             } else {
267                 this.$scope.save();
268             }
269         }
270
271
272         if (this.$scope.component.isResource() &&
273             (this.$scope.component as Resource).resourceType === ResourceType.VF ||
274                 (this.$scope.component as Resource).resourceType === ResourceType.PNF && (this.$scope.component as Resource).csarUUID) {
275             this.$scope.isShowOnboardingSelectionBrowse = true;
276             this.setImportedFileText();
277         } else {
278             this.$scope.isShowOnboardingSelectionBrowse = false;
279         }
280
281
282         //init file extensions based on the file that was imported.
283         if (this.$scope.component.isResource() && (<Resource>this.$scope.component).importedFile) {
284             let fileName:string = (<Resource>this.$scope.component).importedFile.filename;
285             let fileExtension:string = fileName.split(".").pop();
286             if (this.sdcConfig.csarFileExtension.indexOf(fileExtension.toLowerCase()) !== -1) {
287                 this.$scope.importedFileExtension = this.sdcConfig.csarFileExtension;
288                 (<Resource>this.$scope.component).importedFile.filetype = "csar";
289             } else if (this.sdcConfig.toscaFileExtension.indexOf(fileExtension.toLowerCase()) !== -1) {
290                 (<Resource>this.$scope.component).importedFile.filetype = "yaml";
291                 this.$scope.importedFileExtension = this.sdcConfig.toscaFileExtension;
292             }
293             this.$scope.restoreFile = angular.copy((<Resource>this.$scope.originComponent).importedFile); //create backup
294         } else if (this.$scope.isEditMode() && (<Resource>this.$scope.component).resourceType === ResourceType.VF) {
295             this.$scope.importedFileExtension = this.sdcConfig.csarFileExtension;
296             //(<Resource>this.$scope.component).importedFile.filetype="csar";
297         }
298
299
300
301         this.$scope.setValidState(true);
302
303         this.$scope.calculateUnique = (mainCategory:string, subCategory:string):string => {
304             let uniqueId:string = mainCategory;
305             if (subCategory) {
306                 uniqueId += "_#_" + subCategory; // Set the select category combobox to show the selected category.
307             }
308             return uniqueId;
309         };
310
311         //TODO remove this after handling contact in UI
312         if (this.$scope.isCreateMode()) {
313             this.$scope.component.contactId = this.cacheService.get("user").userId;
314             this.$scope.originComponent.contactId = this.$scope.component.contactId;
315         }
316
317
318         this.$scope.$on('$destroy', () => {
319             this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE_WITH_SAVE);
320             this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
321         });
322
323     };
324
325     // Convert category string MainCategory_#_SubCategory to Array with one item (like the server except)
326     private convertCategoryStringToOneArray = ():IMainCategory[] => {
327         let tmp = this.$scope.component.selectedCategory.split("_#_");
328         let mainCategory = tmp[0];
329         let subCategory = tmp[1];
330
331         // Find the selected category and add the relevant sub category.
332         let selectedMainCategory:IMainCategory = <IMainCategory>_.find(this.$scope.categories, function (item) {
333             return item["name"] === mainCategory;
334
335         });
336
337         let mainCategoryClone = angular.copy(selectedMainCategory);
338         if (subCategory) {
339             let selectedSubcategory = <ISubCategory>_.find(selectedMainCategory.subcategories, function (item) {
340                 return item["name"] === subCategory;
341             });
342             mainCategoryClone['subcategories'] = [angular.copy(selectedSubcategory)];
343         }
344         let tmpSelected = <IMainCategory> mainCategoryClone;
345
346         let result:IMainCategory[] = [];
347         result.push(tmpSelected);
348
349         return result;
350     };
351
352     private updateComponentNameInBreadcrumbs = ():void => {
353         // update breadcrum after changing name
354         this.$scope.breadcrumbsModel[1].updateSelectedMenuItemText(this.$scope.component.getComponentSubType() + ': ' + this.$scope.component.name);
355         this.$scope.updateMenuComponentName(this.$scope.component.name);
356     };
357
358     //Find if a category is applicable for External API or not
359     private isHiddenCategory = (category: string) => {
360         let items: Array<any> = new Array<any>();
361         items = this.$scope.sdcMenu.component_workspace_menu_option[this.$scope.component.getComponentSubType()];
362         for(let index = 0; index < items.length; ++index) {
363             if ((items[index].hiddenCategories && items[index].hiddenCategories.indexOf(category) > -1)) {
364                 return true;
365             }
366         }
367         return false;
368     };
369
370     private filteredCategories = () => {
371         let tempCategories: Array<IMainCategory> = new Array<IMainCategory>();
372         this.$scope.categories.forEach((category) => {
373             if (!this.isHiddenCategory(category.name)
374                 && this.$scope.isCreateMode()
375             ) {
376                 tempCategories.push(category);
377             } else if ((ComponentState.NOT_CERTIFIED_CHECKOUT === this.$scope.component.lifecycleState)
378                 && !this.isHiddenCategory(this.$scope.component.selectedCategory)
379                 && !this.isHiddenCategory(category.name)
380             ) {
381                 tempCategories.push(category);
382             } else if ((ComponentState.NOT_CERTIFIED_CHECKOUT === this.$scope.component.lifecycleState)
383                 && this.isHiddenCategory(this.$scope.component.selectedCategory)) {
384                 tempCategories.push(category);
385             }
386         });
387
388         return tempCategories;
389     };    
390    
391     private initScopeMethods = ():void => {
392
393         this.$scope.initCategoreis = ():void => {
394             if (this.$scope.componentType === ComponentType.RESOURCE) {
395                 this.$scope.categories = this.cacheService.get('resourceCategories');
396
397             }
398             if (this.$scope.componentType === ComponentType.SERVICE) {
399                 this.$scope.categories = this.cacheService.get('serviceCategories');
400
401                 //Remove categories from dropdown applicable for External API
402                 if (this.$scope.isCreateMode() || (ComponentState.NOT_CERTIFIED_CHECKOUT === this.$scope.component.lifecycleState)) {
403                     this.$scope.categories = this.filteredCategories();
404                     //Flag to disbale category if service is created through External API
405                     this.$scope.isHiddenCategorySelected = this.isHiddenCategory(this.$scope.component.selectedCategory);
406                 }
407                 
408             }
409         };
410
411         this.$scope.initInstantiationTypes = ():void => {
412             if (this.$scope.componentType === ComponentType.SERVICE) {
413                 this.$scope.instantiationTypes = new Array();
414                 this.$scope.instantiationTypes.push(instantiationType.A_LA_CARTE);
415                 this.$scope.instantiationTypes.push(instantiationType.MACRO);
416                 var instantiationTypeField:string =(<Service>this.$scope.component).instantiationType;
417                 if (instantiationTypeField === ""){
418                     this.$scope.instantiationTypes.push("");
419                 }
420                 else if (this.isCreateModeAvailable(instantiationTypeField)) {
421                     (<Service>this.$scope.component).instantiationType = instantiationType.A_LA_CARTE;
422
423                 }
424             }
425         };
426
427         this.$scope.initEnvironmentContext = ():void => {
428             if (this.$scope.componentType === ComponentType.SERVICE) {
429                 this.$scope.environmentContextObj = this.cacheService.get('UIConfiguration').environmentContext;
430                 var environmentContext:string =(<Service>this.$scope.component).environmentContext;
431                 // In creation new service OR check outing old service without environmentContext parameter - set default value
432                 if(this.isCreateModeAvailable(environmentContext)){
433                     (<Service>this.$scope.component).environmentContext = this.$scope.environmentContextObj.defaultValue;
434                 }
435             }
436         };
437
438         this.$scope.validateField = (field:any):boolean => {
439             if (field && field.$dirty && field.$invalid) {
440                 return true;
441             }
442             return false;
443         };
444
445         this.$scope.openOnBoardingModal = ():void => {
446             if(this.$scope.component.vspArchived) return;
447             let csarUUID = (<Resource>this.$scope.component).csarUUID;
448             let csarVersion = (<Resource>this.$scope.component).csarVersion;
449             this.importVSPService.openOnboardingModal(csarUUID, csarVersion).subscribe((result) => {
450                 this.ComponentFactory.getComponentWithMetadataFromServer(result.type.toUpperCase(), result.previousComponent.uniqueId).then(
451                     (component:Component)=> {
452                     if (result.componentCsar && component.isResource()){
453                         this.cacheService.set(PREVIOUS_CSAR_COMPONENT, angular.copy(component));
454                         component = this.ComponentFactory.updateComponentFromCsar(result.componentCsar, <Resource>component);
455                     }
456                     this.$scope.setComponent(component);
457                     this.$scope.save();
458                     this.setImportedFileText();
459                 }, ()=> {
460                     // ERROR
461                 });
462             })
463         };
464
465         this.$scope.updateIcon = ():void => {
466             this.ModalsHandler.openUpdateIconModal(this.$scope.component).then((isDirty:boolean)=> {
467                 if(isDirty && !this.$scope.isCreateMode()){
468                     this.setUnsavedChanges(true);
469                 }
470             }, ()=> {
471                 // ERROR
472             });
473         };
474
475         this.$scope.possibleToUpdateIcon = ():boolean => {
476             if(this.$scope.componentCategories.selectedCategory && (!this.$scope.component.isResource() || this.$scope.component.vendorName) && !this.$scope.component.isAlreadyCertified()){
477                 return true;
478             }else{
479                 return false;
480             }
481         }
482
483         this.$scope.validateName = (isInit:boolean):void => {
484             if (isInit === undefined) {
485                 isInit = false;
486             }
487
488             let name = this.$scope.component.name;
489             if (!name || name === "") {
490                 if (this.$scope.editForm
491                     && this.$scope.editForm["componentName"]
492                     && this.$scope.editForm["componentName"].$error) {
493
494                     // Clear the error name already exists
495                     this.$scope.editForm["componentName"].$setValidity('nameExist', true);
496                 }
497
498                 return;
499             }
500             const subtype:string = ComponentType.RESOURCE == this.$scope.componentType ? this.$scope.component.getComponentSubType() : undefined;
501
502             const onFailed = (response) => {
503                 // console.info('onFaild', response);
504                 // this.$scope.isLoading = false;
505             };
506
507             const onSuccess = (validation:IValidate) => {
508                 this.$scope.editForm['componentName'].$setValidity('nameExist', validation.isValid);
509                 if (validation.isValid) {
510                     // update breadcrumb after changing name
511                     this.updateComponentNameInBreadcrumbs();
512                 }
513             };
514
515             if (isInit) {
516                 // When page is init after update
517                 if (this.$scope.component.name !== this.$scope.originComponent.name) {
518                     if (!(this.$scope.componentType === ComponentType.RESOURCE && (<Resource>this.$scope.component).csarUUID !== undefined)
519                     ) {
520                         this.$scope.component.validateName(name, subtype).then(onSuccess, onFailed);
521                     }
522                 }
523             } else {
524                 // Validating on change (has debounce)
525                 if (this.$scope.editForm
526                     && this.$scope.editForm["componentName"]
527                     && this.$scope.editForm["componentName"].$error
528                     && !this.$scope.editForm["componentName"].$error.pattern
529                     && (!this.$scope.originComponent.name || this.$scope.component.name.toUpperCase() !== this.$scope.originComponent.name.toUpperCase())
530                 ) {
531                     if (!(this.$scope.componentType === ComponentType.RESOURCE && (this.$scope.component as Resource).csarUUID !== undefined)
532                     ) {
533                         this.$scope.component.validateName(name, subtype).then(onSuccess, onFailed);
534                     }
535                 } else if (this.$scope.editForm && this.$scope.originComponent.name && this.$scope.component.name.toUpperCase() === this.$scope.originComponent.name.toUpperCase()) {
536                     // Clear the error
537                     this.$scope.editForm['componentName'].$setValidity('nameExist', true);
538                 }
539             }
540         };
541
542
543         this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE_WITH_SAVE, (nextState) => {
544             if (this.$state.current.data.unsavedChanges && this.$scope.isValidForm) {
545                 this.$scope.save().then(() => {
546                     this.$scope.handleChangeLifecycleState(nextState);
547                 }, () => {
548                     console.error('Save failed, unable to change lifecycle state to ' + nextState);
549                 });
550             } else if(!this.$scope.isValidForm){
551                 console.error('Form is not valid');
552             } else {
553                 let newCsarVersion:string;
554                 if(this.$scope.unsavedFile) {
555                     newCsarVersion = (this.$scope.component as Resource).csarVersion;
556                 }
557                 if(this.$stateParams.componentCsar && !this.$scope.isCreateMode()) {
558                     const onError = (): void => {
559                         if (this.$scope.component.lifecycleState === 'NOT_CERTIFIED_CHECKIN') {
560                             this.$scope.revert();
561                         }
562                     };
563                     this.$scope.handleChangeLifecycleState(nextState, newCsarVersion, onError);
564
565                 } else {
566                     this.$scope.handleChangeLifecycleState(nextState, newCsarVersion);
567                 }
568             }
569         });
570
571         this.$scope.revert = ():void => {
572             // in state of import file leave the file in place
573
574             this.$scope.setComponent(this.ComponentFactory.createComponent(this.$scope.originComponent));
575
576             if (this.$scope.component.isResource() && this.$scope.restoreFile) {
577                 (this.$scope.component as Resource).importedFile = angular.copy(this.$scope.restoreFile);
578             }
579
580             this.setImportedFileText();
581             this.$scope.updateBreadcrumbs(this.$scope.component); // update on workspace
582
583             this.$scope.componentCategories.selectedCategory = this.$scope.originComponent.selectedCategory;
584             this.setUnsavedChanges(false);
585             this.$scope.updateUnsavedFileFlag(false);
586             this.$scope.editForm.$setPristine();
587         };
588
589         this.$scope.onImportFileChange = () => {
590
591             if( !this.$scope.restoreFile && this.$scope.editForm.fileElement.value && this.$scope.editForm.fileElement.value.filename || // if file started empty but we have added a new one
592                 this.$scope.restoreFile && !angular.equals(this.$scope.restoreFile, this.$scope.editForm.fileElement.value)){ // or file was swapped for a new one
593                 this.$scope.updateUnsavedFileFlag(true);
594             } else {
595                 this.$scope.updateUnsavedFileFlag(false);
596                 this.$scope.editForm.fileElement.$setPristine();
597             }
598         };
599
600         this.$scope.$watchCollection('component.name', (newData: any): void => {
601             this.$scope.validateName(false);
602         });
603
604         // Notify the parent if this step valid or not.
605         this.$scope.$watch('editForm.$valid', (newVal, oldVal) => {
606             this.$scope.setValidState(newVal);
607         });
608
609         this.$scope.$watch('editForm.$dirty', (newVal, oldVal) => {
610             if (newVal && !this.$scope.isCreateMode()) {
611                 this.setUnsavedChanges(true);
612             }
613
614         });
615
616         this.$scope.onCategoryChange = (): void => {
617             this.$scope.component.selectedCategory = this.$scope.componentCategories.selectedCategory;
618             this.$scope.component.categories = this.convertCategoryStringToOneArray();
619             this.$scope.component.icon = DEFAULT_ICON;
620         };
621
622         this.$scope.onEcompGeneratedNamingChange = (): void => {
623             if (!(this.$scope.component as Service).ecompGeneratedNaming) {
624                 (this.$scope.component as Service).namingPolicy = '';
625             }
626         };
627
628         this.$scope.onVendorNameChange = (oldVendorName: string): void => {
629             if (this.$scope.component.icon === oldVendorName) {
630                 this.$scope.component.icon = DEFAULT_ICON;
631             }
632         };
633         this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.$scope.reload);
634
635     }
636
637     private setUnsavedChanges = (hasChanges: boolean): void => {
638         this.$state.current.data.unsavedChanges = hasChanges;
639     }
640
641 }
642