re base code
[sdc.git] / catalog-ui / src / app / view-models / workspace / workspace-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 /**
22  * Created by obarda on 3/30/2016.
23  */
24 'use strict';
25 import * as _ from "lodash";
26 import {IUserProperties, IAppMenu, Resource, Component, Plugin, PluginsConfiguration, PluginDisplayOptions} from "app/models";
27 import {
28     WorkspaceMode, ComponentFactory, ChangeLifecycleStateHandler, Role, ComponentState, MenuItemGroup, MenuHandler,
29     MenuItem, ModalsHandler, States, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FLAG, ResourceType, PREVIOUS_CSAR_COMPONENT
30 } from "app/utils";
31 import {
32     EventListenerService,
33     EntityService,
34     ProgressService,
35     CacheService,
36     LeftPaletteLoaderService
37 } from "app/services";
38 import {FileUploadModel} from "../../directives/file-upload/file-upload";
39 import {AutomatedUpgradeService} from "../../ng2/pages/automated-upgrade/automated-upgrade.service";
40 import {ComponentServiceNg2} from "../../ng2/services/component-services/component.service";
41 import {EventBusService} from "../../ng2/services/event-bus.service";
42 import {PluginsService} from "../../ng2/services/plugins.service";
43 import {IDependenciesServerResponse} from "../../ng2/services/responses/dependencies-server-response";
44
45
46 export interface IWorkspaceViewModelScope extends ng.IScope {
47
48     isLoading:boolean;
49     isCreateProgress:boolean;
50     component:Component;
51     originComponent:Component;
52     componentType:string;
53     importFile:any;
54     leftBarTabs:MenuItemGroup;
55     isNew:boolean;
56     isFromImport:boolean;
57     isValidForm:boolean;
58     isActiveTopBar:boolean;
59     mode:WorkspaceMode;
60     breadcrumbsModel:Array<MenuItemGroup>;
61     sdcMenu:IAppMenu;
62     changeLifecycleStateButtons:any;
63     version:string;
64     versionsList:Array<any>;
65     changeVersion:any;
66     isComposition:boolean;
67     isDeployment:boolean;
68     isPlugins:boolean;
69     $state:ng.ui.IStateService;
70     user:IUserProperties;
71     thirdParty:boolean;
72     disabledButtons:boolean;
73     menuComponentTitle:string;
74     progressService:ProgressService;
75     progressMessage:string;
76     ComponentServiceNg2: ComponentServiceNg2;
77     // leftPanelComponents:Array<Models.Components.Component>; //this is in order to load the left panel once, and not wait long time when moving to composition
78     unsavedChanges:boolean;
79     unsavedChangesCallback:Function;
80     unsavedFile:boolean;
81
82
83     startProgress(message:string):void;
84     stopProgress():void;
85     updateBreadcrumbs(component:Component):void;
86     updateUnsavedFileFlag(isUnsaved:boolean):void;
87     showChangeStateButton():boolean;
88     getComponent():Component;
89     setComponent(component:Component):void;
90     setOriginComponent(component:Component):void;
91     onMenuItemPressed(state:string, params:any):ng.IPromise<boolean>;
92     create():void;
93     save():Promise<void>;
94     setValidState(isValid:boolean):void;
95     changeLifecycleState(state:string):void;
96     handleChangeLifecycleState(state:string, newCsarVersion?:string):void;
97     disableMenuItems():void;
98     enableMenuItems():void;
99     isDesigner():boolean;
100     isViewMode():boolean;
101     isEditMode():boolean;
102     isCreateMode():boolean;
103     isDisableMode():boolean;
104     isGeneralView():boolean;
105     goToBreadcrumbHome():void;
106     onVersionChanged(selectedId:string):void;
107     getLatestVersion():void;
108     getStatus():string;
109     showLifecycleIcon():boolean;
110     updateSelectedMenuItem(state:string):void;
111     isSelected(menuItem:MenuItem):boolean;
112     uploadFileChangedInGeneralTab():void;
113     updateMenuComponentName(ComponentName:string):void;
114     getTabTitle():string;
115     reload(component:Component):void;
116 }
117
118 export class WorkspaceViewModel {
119
120     static '$inject' = [
121         '$scope',
122         'injectComponent',
123         'ComponentFactory',
124         '$state',
125         'sdcMenu',
126         '$q',
127         'MenuHandler',
128         'Sdc.Services.CacheService',
129         'ChangeLifecycleStateHandler',
130         'ModalsHandler',
131         'LeftPaletteLoaderService',
132         '$filter',
133         'EventListenerService',
134         'Sdc.Services.EntityService',
135         'Notification',
136         '$stateParams',
137         'Sdc.Services.ProgressService',
138         'ComponentServiceNg2',
139         'AutomatedUpgradeService',
140         'EventBusService',
141         'PluginsService'
142     ];
143
144     constructor(private $scope:IWorkspaceViewModelScope,
145                 private injectComponent:Component,
146                 private ComponentFactory:ComponentFactory,
147                 private $state:ng.ui.IStateService,
148                 private sdcMenu:IAppMenu,
149                 private $q:ng.IQService,
150                 private MenuHandler:MenuHandler,
151                 private cacheService:CacheService,
152                 private ChangeLifecycleStateHandler:ChangeLifecycleStateHandler,
153                 private ModalsHandler:ModalsHandler,
154                 private LeftPaletteLoaderService:LeftPaletteLoaderService,
155                 private $filter:ng.IFilterService,
156                 private EventListenerService:EventListenerService,
157                 private EntityService:EntityService,
158                 private Notification:any,
159                 private $stateParams:any,
160                 private progressService:ProgressService,
161                 private ComponentServiceNg2:ComponentServiceNg2,
162                 private AutomatedUpgradeService:AutomatedUpgradeService,
163                 private eventBusService:EventBusService,
164                 private pluginsService:PluginsService) {
165               
166
167
168         this.initScope();
169         this.initAfterScope();
170         this.$scope.updateSelectedMenuItem(this.$state.current.name);
171     }
172
173     private role:string;
174     private components:Array<Component>;
175
176     private initViewMode = ():WorkspaceMode => {
177         let mode = WorkspaceMode.VIEW;
178
179         if (!this.$state.params['id']) {   //&& !this.$state.params['vspComponent']
180             mode = WorkspaceMode.CREATE;
181         } else {
182             if (this.$scope.component.lifecycleState === ComponentState.NOT_CERTIFIED_CHECKOUT &&
183                 this.$scope.component.lastUpdaterUserId === this.cacheService.get("user").userId) {
184                 if ((this.$scope.component.isService() || this.$scope.component.isResource()) && this.role == Role.DESIGNER) {
185                     mode = WorkspaceMode.EDIT;
186                 }
187             }
188         }
189         return mode;
190     };
191
192     private initChangeLifecycleStateButtons = ():void => {
193         let state = this.$scope.component.isService() && (Role.OPS == this.role || Role.GOVERNOR == this.role) ? this.$scope.component.distributionStatus : this.$scope.component.lifecycleState;
194         this.$scope.changeLifecycleStateButtons = (this.sdcMenu.roles[this.role].changeLifecycleStateButtons[state] || [])[this.$scope.component.componentType.toUpperCase()];
195
196     };
197
198     private initLeftPalette = ():void => {
199         //this.LeftPaletteLoaderService.loadLeftPanel(this.$scope.component);
200     };
201
202     private initScope = ():void => {
203
204         this.$scope.component = this.injectComponent;
205         //this.initLeftPalette();
206         this.$scope.menuComponentTitle = this.$scope.component.name;
207         this.$scope.disabledButtons = false;
208         this.$scope.originComponent = this.ComponentFactory.createComponent(this.$scope.component);
209         this.$scope.componentType = this.$scope.component.componentType;
210         this.$scope.version = this.cacheService.get('version');
211         this.$scope.user = this.cacheService.get("user");
212         this.role = this.$scope.user.role;
213         this.$scope.mode = this.initViewMode();
214         this.$scope.isValidForm = true;
215         this.initChangeLifecycleStateButtons();
216         this.initVersionObject();
217         this.$scope.$state = this.$state;
218         this.$scope.isLoading = false;
219         this.$scope.isComposition = (this.$state.current.name.indexOf(States.WORKSPACE_COMPOSITION) > -1);
220         this.$scope.isDeployment = this.$state.current.name == States.WORKSPACE_DEPLOYMENT;
221         this.$scope.progressService = this.progressService;
222         this.$scope.unsavedChanges = false;
223
224         this.EventListenerService.registerObserverCallback(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.setWorkspaceButtonState);
225         //this.EventListenerService.registerObserverCallback(EVENTS.ON_UPDATE_VSP_FILE, this.updateVspFlag);
226
227         this.$scope.getComponent = ():Component => {
228             return this.$scope.component;
229         };
230
231         this.$scope.updateMenuComponentName = (ComponentName:string):void => {
232             this.$scope.menuComponentTitle = ComponentName;
233         };
234
235         this.$scope.sdcMenu = this.sdcMenu;
236         // Will be called from each step after save to update the resource.
237         this.$scope.setComponent = (component:Component):void => {
238             this.$scope.component = component;
239         };
240
241         this.$scope.setOriginComponent = (component:Component):void => {
242             this.$scope.originComponent = component;
243         }
244
245         this.$scope.uploadFileChangedInGeneralTab = ():void => {
246             // In case user select browse file, and in update mode, need to disable submit for testing and checkin buttons.
247             if (this.$scope.isEditMode() && this.$scope.component.isResource() && (<Resource>this.$scope.component).resourceType == ResourceType.VF) {
248                 // NOTE: Commented out the disabling of the workspace buttons on CSAR updating due fix of a bug [417534]
249                 // this.$scope.disabledButtons = true;
250             }
251         };
252
253         this.$scope.archiveComponent = ():void => {
254             this.$scope.isLoading = true;
255             const typeComponent = this.$scope.component.componentType;
256             this.ComponentServiceNg2.archiveComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=>{
257                 this.$scope.isLoading = false;
258                 if(this.$state.params.previousState){
259                     switch(this.$state.params.previousState){
260                         case 'catalog':
261                         case 'dashboard':
262                             this.$state.go(this.$state.params.previousState);
263                             break;
264                         default:
265                             break;
266                     } 
267                 }
268                 this.$scope.component.archived = true;
269                 this.deleteArchiveCache();
270
271                 this.Notification.success({
272                     message: this.$scope.component.name + ' ' + this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TEXT"),
273                     title: this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TITLE")
274                 });
275             }, (error) => { this.$scope.isLoading = false; });
276         } 
277
278         this.$scope.restoreComponent = ():void => {
279             this.$scope.isLoading = true;
280             const typeComponent = this.$scope.component.componentType;
281             this.ComponentServiceNg2.restoreComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=>{
282                 this.$scope.isLoading = false;
283                 this.Notification.success({
284                             message: this.$scope.component.name + ' ' + this.$filter('translate')("RESTORE_SUCCESS_MESSAGE_TEXT"),
285                             title: this.$filter('translate')("RESTORE_SUCCESS_MESSAGE_TITLE")
286                         });
287             });
288             this.$scope.component.archived = false;
289             this.deleteArchiveCache();
290         }
291
292         this.$scope.$on('$stateChangeStart', (event, toState, toParams, fromState, fromParams) => {
293             if(this.$scope.isEditMode()){
294                 if (fromParams.id == toParams.id && this.$state.current.data && this.$state.current.data.unsavedChanges) {
295                     event.preventDefault();
296                     if(this.$scope.isValidForm){
297                         this.$scope.save().then(() => {
298                             this.$scope.onMenuItemPressed(toState.name, toParams);
299                         }, ()=> { 
300                             console.error("Save failed, unable to navigate to " + toState.name);
301                         })
302                     } else {
303                         console.error("Form is invalid, unable to navigate to " + toState.name);
304                     }
305                 } 
306             }
307
308         });
309
310         this.$scope.$on('$stateChangeSuccess', (event, toState) => {
311             this.$scope.updateSelectedMenuItem(this.$state.current.name);
312         });
313
314         this.$scope.onMenuItemPressed = (state:string, params:any):ng.IPromise<boolean> => {
315
316             let deferred:ng.IDeferred<boolean> = this.$q.defer();
317             let goToState = ():void => {
318                 this.$state.go(state, Object.assign({
319                     id: this.$scope.component.uniqueId,
320                     type: this.$scope.component.componentType.toLowerCase(),
321                     components: this.components
322                 }, params));
323                 deferred.resolve(true);
324             };
325
326             if (this.$scope.isEditMode() && //this is a workaround for amdocs - we need to get the artifact in order to avoid saving the vf when moving from their tabs
327                 (this.$state.current.name === States.WORKSPACE_MANAGEMENT_WORKFLOW || this.$state.current.name === States.WORKSPACE_NETWORK_CALL_FLOW)) {
328                 let onGetSuccess = (component:Component) => {
329                     this.$scope.isLoading = false;
330                     // Update the components
331                     this.$scope.component = component;
332                     goToState();
333                 };
334                 let onFailed = () => {
335                     this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_ERROR);
336                     this.$scope.isLoading = false; // stop the progress.
337                     deferred.reject(false);
338                 };
339                 this.$scope.component.getComponent().then(onGetSuccess, onFailed);
340             } else {
341                 goToState();
342             }
343             return deferred.promise;
344         };
345
346         this.$scope.setValidState = (isValid:boolean):void => {
347             this.$scope.isValidForm = isValid;
348         };
349
350         this.$scope.onVersionChanged = (selectedId:string):void => {
351             if (this.$scope.isGeneralView() && this.$state.current.data.unsavedChanges) {
352                 this.$scope.changeVersion.selectedVersion = _.find(this.$scope.versionsList, (versionObj)=> {
353                     return versionObj.versionId === this.$scope.component.uniqueId;
354                 });
355             }
356
357             let eventData = {
358                 uuid: this.$scope.component.uuid,
359                 version: this.$scope.changeVersion.selectedVersion.versionNumber
360             };
361
362             this.eventBusService.notify("VERSION_CHANGED", eventData).subscribe(() => {
363                 this.$scope.isLoading = true;
364
365                 this.$state.go(this.$state.current.name, {
366                     id: selectedId,
367                     type: this.$scope.componentType.toLowerCase(),
368                     mode: WorkspaceMode.VIEW,
369                     components: this.$state.params['components']
370                 }, {reload: true});
371             });
372         };
373
374         this.$scope.getLatestVersion = ():void => {
375             this.$scope.onVersionChanged(_.first(this.$scope.versionsList).versionId);
376         };
377
378         this.$scope.create = () => {
379             
380             this.$scope.startProgress("Creating Asset...");
381             _.first(this.$scope.leftBarTabs.menuItems).isDisabled = true;//disabled click on general tab (DE246274)
382
383              // In case we import CSAR. Notify user that import VF will take long time (the create is performed in the background).
384              if (this.$scope.component.isResource() && (<Resource>this.$scope.component).csarUUID) {
385                 this.Notification.info({
386                     message: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_DESCRIPTION"),
387                     title: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_TITLE")
388                 });
389             }
390
391             let onFailed = () => {
392                 this.$scope.stopProgress();
393                 this.$scope.isLoading = false; // stop the progress.
394                 _.first(this.$scope.leftBarTabs.menuItems).isDisabled = false;//enabled click on general tab (DE246274)
395                 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_ERROR);
396                 let modalInstance:ng.ui.bootstrap.IModalServiceInstance;
397                 modalInstance && modalInstance.close();  // Close the modal in case it is opened.
398                 this.$scope.component.tags = _.without(this.$scope.component.tags, this.$scope.component.name);// for fix DE246217
399
400                 this.$scope.setValidState(true);  // Set the form valid (if sent form is valid, the error from server).
401             };
402
403             let onSuccessCreate = (component:Component) => {
404
405                 this.$scope.stopProgress();
406                 this.showSuccessNotificationMessage();
407
408                 // Update the components list for breadcrumbs
409                 this.components.unshift(component);
410
411                 this.$state.go(States.WORKSPACE_GENERAL, {
412                     id: component.uniqueId,
413                     type: component.componentType.toLowerCase(),
414                     components: this.components
415                 }, {inherit: false});
416             };
417
418             this.ComponentFactory.createComponentOnServer(this.$scope.component).then(onSuccessCreate, onFailed);
419
420
421         };
422
423         this.$scope.save = ():Promise<void> => {
424             
425             this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_CLICK);
426
427             this.$scope.startProgress("Updating Asset...");
428             this.$scope.disableMenuItems();
429
430             return new Promise<void>((resolve, reject) => {
431                 let stopProgressAndEnableUI = () => {
432                     this.$scope.disabledButtons = false;
433                     this.$scope.isLoading = false;
434                     this.$scope.enableMenuItems();
435                     this.$scope.stopProgress();
436                 }
437
438                 let onFailed = () => {
439                     stopProgressAndEnableUI();
440                     this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_ERROR);
441
442                     reject();
443                 };
444
445                 let onSuccessUpdate = (component:Component) => {
446                     stopProgressAndEnableUI();
447                     this.showSuccessNotificationMessage();
448
449                     component.tags = _.reject(component.tags, (item)=> {
450                         return item === component.name
451                     });
452
453                     this.$scope.updateBreadcrumbs(component);
454                     
455                     //update the component
456                     this.$scope.setComponent(component);
457                     this.$scope.originComponent = this.ComponentFactory.createComponent(this.$scope.component);
458
459                     if (this.cacheService.contains(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
460                         this.cacheService.remove(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
461                     }
462                     if (this.cacheService.contains(PREVIOUS_CSAR_COMPONENT)){
463                         this.cacheService.remove(PREVIOUS_CSAR_COMPONENT);
464                     }
465
466                     //clear edit flags
467                     this.$state.current.data.unsavedChanges = false;
468                     this.$scope.unsavedFile = false;
469                     resolve();
470                 };
471
472                 this.$scope.component.updateComponent().then(onSuccessUpdate, onFailed);
473             });
474
475         };
476
477         this.$scope.changeLifecycleState = (state:string):void => {
478             if (this.$scope.isGeneralView() && state !== 'deleteVersion') {
479                 this.EventListenerService.notifyObservers(EVENTS.ON_LIFECYCLE_CHANGE_WITH_SAVE, state);
480             } else {
481                 this.$scope.handleChangeLifecycleState(state);
482             }
483         };
484
485         let defaultActionAfterChangeLifecycleState = ():void => {
486             if (this.$state.current.data && this.$state.current.data.unsavedChanges) {
487                 this.$state.current.data.unsavedChanges = false;
488             }
489             this.$state.go('dashboard');
490         };
491
492         this.$scope.handleChangeLifecycleState = (state:string, newCsarVersion?:string) => {
493             if ('monitor' === state) {
494                 this.$state.go('workspace.distribution');
495                 return;
496             }
497
498             let data = this.$scope.changeLifecycleStateButtons[state];
499             let onSuccess = (component:Component, url:string):void => {
500                 //Updating the component from server response
501
502                 // Creating the data object to notify the plugins with
503                 let eventData: any = {
504                     uuid: this.$scope.component.uuid,
505                     version: this.$scope.component.version
506                 };
507
508                 //the server returns only metaData (small component) except checkout (Full component)  ,so we update only the statuses of distribution & lifecycle
509                 this.$scope.component.lifecycleState = component.lifecycleState;
510                 this.$scope.component.distributionStatus = component.distributionStatus;
511
512                 switch (url) {
513                     case 'lifecycleState/CHECKOUT':
514                         this.eventBusService.notify("CHECK_OUT", eventData, false).subscribe(() => {
515                             // only checkOut get the full component from server
516                             //   this.$scope.component = component;
517                             // Work around to change the csar version
518                             if(newCsarVersion) {
519                                 this.cacheService.set(CHANGE_COMPONENT_CSAR_VERSION_FLAG, newCsarVersion);
520                             } 
521
522                             //when checking out a minor version uuid remains
523                             const bcIdx = _.findIndex(this.components, (item) => {
524                                 return item.uuid === component.uuid;
525                             });
526                             if (bcIdx !== -1) {
527                                 this.components[bcIdx] = component;
528                             } else {
529                                 //when checking out a major(certified) version
530                                 this.components.unshift(component);
531                             }
532                             this.$scope.mode = this.initViewMode();
533                             this.initChangeLifecycleStateButtons();
534                             this.initVersionObject();
535                             this.$scope.isLoading = false;
536                             this.EventListenerService.notifyObservers(EVENTS.ON_CHECKOUT, component);
537
538                             this.Notification.success({
539                                 message: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TEXT"),
540                                 title: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TITLE")
541                             });
542
543                         });
544                         break;
545                     case 'lifecycleState/CHECKIN':
546                         defaultActionAfterChangeLifecycleState();
547                         this.Notification.success({
548                             message: this.$filter('translate')("CHECKIN_SUCCESS_MESSAGE_TEXT"),
549                             title: this.$filter('translate')("CHECKIN_SUCCESS_MESSAGE_TITLE")
550                         });
551                         break;
552                     case 'lifecycleState/UNDOCHECKOUT':
553                         this.eventBusService.notify("UNDO_CHECK_OUT", eventData, false).subscribe(() => {
554                             defaultActionAfterChangeLifecycleState();
555                             this.Notification.success({
556                                 message: this.$filter('translate')("DELETE_SUCCESS_MESSAGE_TEXT"),
557                                 title: this.$filter('translate')("DELETE_SUCCESS_MESSAGE_TITLE")
558                             });
559                         });
560                         break;
561                     case 'lifecycleState/certificationRequest':
562                         defaultActionAfterChangeLifecycleState();
563                         this.Notification.success({
564                             message: this.$filter('translate')("SUBMIT_FOR_TESTING_SUCCESS_MESSAGE_TEXT"),
565                             title: this.$filter('translate')("SUBMIT_FOR_TESTING_SUCCESS_MESSAGE_TITLE")
566                         });
567                         break;
568                     //Tester Role
569                     case 'lifecycleState/failCertification':
570                         defaultActionAfterChangeLifecycleState();
571                         this.Notification.success({
572                             message: this.$filter('translate')("REJECT_SUCCESS_MESSAGE_TEXT"),
573                             title: this.$filter('translate')("REJECT_SUCCESS_MESSAGE_TITLE")
574                         });
575                         break;
576                     case 'lifecycleState/certify':
577
578                         this.$scope.handleCertification(component);
579                         
580                         break;
581                     //DE203504 Bug Fix Start
582                     case 'lifecycleState/startCertification':
583                         this.initChangeLifecycleStateButtons();
584                         this.Notification.success({
585                             message: this.$filter('translate')("START_TESTING_SUCCESS_MESSAGE_TEXT"),
586                             title: this.$filter('translate')("START_TESTING_SUCCESS_MESSAGE_TITLE")
587                         });
588                         break;
589                     case  'lifecycleState/cancelCertification':
590                         this.initChangeLifecycleStateButtons();
591                         this.Notification.success({
592                             message: this.$filter('translate')("CANCEL_TESTING_SUCCESS_MESSAGE_TEXT"),
593                             title: this.$filter('translate')("CANCEL_TESTING_SUCCESS_MESSAGE_TITLE")
594                         });
595                         break;
596                     //Ops Role
597                     case  'distribution/PROD/activate':
598                         this.initChangeLifecycleStateButtons();
599                         this.Notification.success({
600                             message: this.$filter('translate')("DISTRIBUTE_SUCCESS_MESSAGE_TEXT"),
601                             title: this.$filter('translate')("DISTRIBUTE_SUCCESS_MESSAGE_TITLE")
602                         });
603                         break;
604                     //Governor Role
605                     case  'distribution-state/reject':
606                         this.initChangeLifecycleStateButtons();
607                         this.Notification.success({
608                             message: this.$filter('translate')("REJECT_SUCCESS_MESSAGE_TEXT"),
609                             title: this.$filter('translate')("REJECT_SUCCESS_MESSAGE_TITLE")
610                         });
611                         break;
612                     case  'distribution-state/approve':
613                         this.initChangeLifecycleStateButtons();
614                         this.$state.go('catalog');
615                         this.Notification.success({
616                             message: this.$filter('translate')("APPROVE_SUCCESS_MESSAGE_TEXT"),
617                             title: this.$filter('translate')("APPROVE_SUCCESS_MESSAGE_TITLE")
618                         });
619                         break;
620                     //DE203504 Bug Fix End
621
622                     default :
623                         defaultActionAfterChangeLifecycleState();
624
625                 }
626                 if (data.url != 'lifecycleState/CHECKOUT') {
627                     this.$scope.isLoading = false;
628                 }
629             };
630             //this.$scope.isLoading = true;
631
632             this.ChangeLifecycleStateHandler.changeLifecycleState(this.$scope.component, data, this.$scope, onSuccess);
633         };
634
635
636
637         this.$scope.isViewMode = ():boolean => {
638             return this.$scope.mode === WorkspaceMode.VIEW;
639         };
640
641         this.$scope.isDesigner = ():boolean => {
642             return this.role == Role.DESIGNER;
643         };
644
645         this.$scope.isDisableMode = ():boolean => {
646             return this.$scope.mode === WorkspaceMode.VIEW && this.$scope.component.lifecycleState === ComponentState.NOT_CERTIFIED_CHECKIN;
647         };
648
649         this.$scope.isGeneralView = ():boolean => {
650             //we show revert and save icons only in general view
651             return this.$state.current.name === States.WORKSPACE_GENERAL;
652         };
653
654         this.$scope.isCreateMode = ():boolean => {
655             return this.$scope.mode === WorkspaceMode.CREATE;
656         };
657
658         this.$scope.isEditMode = ():boolean => {
659             return this.$scope.mode === WorkspaceMode.EDIT;
660         };
661
662         this.$scope.goToBreadcrumbHome = ():void => {
663             let bcHome:MenuItemGroup = this.$scope.breadcrumbsModel[0];
664             this.$state.go(bcHome.menuItems[bcHome.selectedIndex].state);
665         };
666
667         this.$scope.showLifecycleIcon = ():boolean => {
668             return this.role == Role.DESIGNER;
669         };
670
671         this.$scope.getStatus = ():string => {
672             if (this.$scope.isCreateMode()) {
673                 return 'IN DESIGN';
674             }
675
676             return this.$scope.component.getStatus(this.sdcMenu);
677         };
678
679         this.initMenuItems();
680
681         this.$scope.showChangeStateButton = ():boolean => {
682             let result:boolean = true;
683             if (!this.$scope.component.isLatestVersion() && Role.OPS != this.role && Role.GOVERNOR != this.role) {
684                 result = false;
685             }
686             if (ComponentState.NOT_CERTIFIED_CHECKOUT === this.$scope.component.lifecycleState && this.$scope.isViewMode()) {
687                 result = false;
688             }
689             if (ComponentState.CERTIFIED != this.$scope.component.lifecycleState &&
690                 (Role.OPS == this.role || Role.GOVERNOR == this.role)) {
691                 result = false;
692             }
693             return result;
694         };
695
696         this.$scope.updateSelectedMenuItem = (state:string):void => {
697             let stateArray:Array<string> = state.split('.', 2);
698             let stateWithoutInternalNavigate:string = stateArray[0] + '.' + stateArray[1];
699             let selectedItem:MenuItem = _.find(this.$scope.leftBarTabs.menuItems, (item:MenuItem) => {
700                 let itemStateArray: Array<string> = item.state.split('.', 2);
701                 let itemStateWithoutNavigation:string = itemStateArray[0] + '.' + itemStateArray[1];
702                 return (itemStateWithoutNavigation === stateWithoutInternalNavigate);
703             });
704
705             let selectedIndex = selectedItem ? this.$scope.leftBarTabs.menuItems.indexOf(selectedItem) : 0;
706
707            if (stateArray[1] === 'plugins') {
708                 _.forEach(PluginsConfiguration.plugins, (plugin) => {
709                     if (plugin.pluginStateUrl == this.$state.params.path) {
710                         return false;
711                     }
712                     else if (this.pluginsService.isPluginDisplayedInContext(plugin, this.role, this.$scope.component.getComponentSubType())) {
713                             selectedIndex++;
714                     }
715                 });
716             }
717
718             this.$scope.leftBarTabs.selectedIndex = selectedIndex;
719         };
720
721         this.$scope.isSelected = (menuItem:MenuItem): boolean => {
722             return this.$scope.leftBarTabs.selectedIndex === _.indexOf(this.$scope.leftBarTabs.menuItems, menuItem);
723         };
724
725         this.$scope.$watch('$state.current.name', (newVal:string):void => {
726             if (newVal) {
727                 this.$scope.isComposition = (newVal.indexOf(States.WORKSPACE_COMPOSITION) > -1);
728                 this.$scope.isDeployment = newVal == States.WORKSPACE_DEPLOYMENT;
729                 this.$scope.isPlugins = newVal == States.WORKSPACE_PLUGINS;
730             }
731         });
732
733         this.$scope.getTabTitle = ():string => {
734             return this.$scope.leftBarTabs.menuItems.find((menuItem:MenuItem) => {
735                 return menuItem.state == this.$scope.$state.current.name;
736             }).text;
737         };
738
739         this.$scope.reload = (component:Component):void => {
740             this.$state.go(this.$state.current.name, {id: component.uniqueId}, {reload: true});
741         };
742
743         this.$scope.$on('$destroy', () => {
744             this.EventListenerService.unRegisterObserver(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES);
745         });
746         
747         this.$scope.openAutomatedUpgradeModal = ():void => {
748             this.$scope.isLoading = true;
749             this.ComponentServiceNg2.getDependencies(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response:Array<IDependenciesServerResponse>)=> {
750                 this.$scope.isLoading = false;
751                 this.AutomatedUpgradeService.openAutomatedUpgradeModal(response, this.$scope.component, false);
752             });
753         }
754
755         this.$scope.handleCertification = (certifyComponent): void => {
756             if (this.$scope.component.getComponentSubType() === ResourceType.VF) {
757                 this.ComponentServiceNg2.getDependencies(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response:Array<IDependenciesServerResponse>) => {
758                     this.$scope.isLoading = false;
759
760                     let isUpgradeNeeded = _.filter(response, (componentToUpgrade:IDependenciesServerResponse) => {
761                         return componentToUpgrade.dependencies && componentToUpgrade.dependencies.length > 0;
762                     });
763                     if(isUpgradeNeeded.length === 0) {
764                         this.onSuccessWithoutUpgradeNeeded();
765                         return;
766                     }
767                     this.refreshDataAfterChangeLifecycleState(certifyComponent);
768                     this.AutomatedUpgradeService.openAutomatedUpgradeModal(response, this.$scope.component, true);
769                 });
770             } else {
771                 this.onSuccessWithoutUpgradeNeeded();
772             }
773         }
774
775         this.$scope.disableMenuItems = () => {
776             this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => {
777                 item.isDisabled = (States.WORKSPACE_GENERAL != item.state);
778             });
779         }
780     
781         this.$scope.enableMenuItems = () => {
782             this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => {
783                 item.isDisabled = false;
784             });
785         }
786
787
788         this.$scope.startProgress = (message:string):void => {
789             this.progressService.initCreateComponentProgress(this.$scope.component.uniqueId);
790             this.$scope.isCreateProgress = true;
791             this.$scope.progressMessage = message;
792         };
793
794         this.$scope.stopProgress = ():void => {
795             this.$scope.isCreateProgress = false;
796             this.progressService.deleteProgressValue(this.$scope.component.uniqueId);
797         }
798
799         this.$scope.updateBreadcrumbs = (component:Component):void => {
800             // Update the components list for breadcrumbs
801             const bcIdx = this.MenuHandler.findBreadcrumbComponentIndex(this.components, component);
802             if (bcIdx !== -1) {
803                 this.components[bcIdx] = component;
804                 this.initBreadcrumbs();  // re-calculate breadcrumbs
805             }
806         }
807
808         this.$scope.updateUnsavedFileFlag = (isUnsaved:boolean) => {
809             this.$scope.unsavedFile = isUnsaved;
810         }
811
812     };
813
814     private onSuccessWithoutUpgradeNeeded = ():void => {
815         this.$scope.isLoading = false;
816         this.Notification.success({
817             message: this.$filter('translate')("ACCEPT_TESTING_SUCCESS_MESSAGE_TEXT"),
818             title: this.$filter('translate')("ACCEPT_TESTING_SUCCESS_MESSAGE_TITLE")
819         });
820         this.$state.go('dashboard');
821     }
822     private refreshDataAfterChangeLifecycleState = (component:Component):void => {
823         this.$scope.isLoading = false;
824         this.$scope.mode = this.initViewMode();
825         this.initChangeLifecycleStateButtons();
826         this.initVersionObject();
827         this.EventListenerService.notifyObservers(EVENTS.ON_LIFECYCLE_CHANGE, component);
828     }
829
830     private initAfterScope = ():void => {
831         // In case user select csar from the onboarding modal, need to disable checkout and submit for testing.
832         if (this.$state.params['disableButtons'] === true) {
833             this.$scope.uploadFileChangedInGeneralTab();
834         }
835     };
836
837     private initVersionObject = ():void => {
838         this.$scope.versionsList = (this.$scope.component.getAllVersionsAsSortedArray()).reverse();
839         this.$scope.changeVersion = {
840             selectedVersion: _.find(this.$scope.versionsList, (versionObj)=> {
841                 return versionObj.versionId === this.$scope.component.uniqueId;
842             })
843         };
844     };
845
846     private getNewComponentBreadcrumbItem = ():MenuItem => {
847         let text = "";
848         if (this.$scope.component.isResource() && (<Resource>this.$scope.component).isCsarComponent()) {
849             text = this.$scope.component.getComponentSubType() + ': ' + this.$scope.component.name;
850         } else {
851             text = 'Create new ' + this.$state.params['type'];
852         }
853         return new MenuItem(text, null, States.WORKSPACE_GENERAL, 'goToState', [this.$state.params]);
854     };
855
856     private updateMenuItemByRole = (menuItems:Array<any>, role:string) => {
857         let tempMenuItems:Array<any> = new Array<any>();
858         menuItems.forEach((item:any) => {
859             //remove item if role is disabled
860             if (!(item.disabledRoles && item.disabledRoles.indexOf(role) > -1)) {
861                 tempMenuItems.push(item);
862             }
863         });
864         return tempMenuItems;
865     };
866
867     private deleteArchiveCache = () => {
868         this.cacheService.remove("archiveComponents"); //delete the cache to ensure the archive is reloaded from server
869     };
870
871     private initBreadcrumbs = () => {
872         this.components = this.cacheService.get('breadcrumbsComponents');
873         let breadcrumbsComponentsLvl = this.MenuHandler.generateBreadcrumbsModelFromComponents(this.components, this.$scope.component);
874
875         if (this.$scope.isCreateMode()) {
876             let createItem = this.getNewComponentBreadcrumbItem();
877             if (!breadcrumbsComponentsLvl.menuItems) {
878                 breadcrumbsComponentsLvl.menuItems = [];
879             }
880             breadcrumbsComponentsLvl.menuItems.unshift(createItem);
881             breadcrumbsComponentsLvl.selectedIndex = 0;
882         }
883
884         this.$scope.breadcrumbsModel = [breadcrumbsComponentsLvl, this.$scope.leftBarTabs];
885     };
886
887     private initMenuItems() {
888
889         let inCreateMode = this.$scope.isCreateMode();
890         this.$scope.leftBarTabs = new MenuItemGroup();
891         const menuItemsObjects:Array<any> = this.updateMenuItemByRole(this.sdcMenu.component_workspace_menu_option[this.$scope.component.getComponentSubType()], this.role);
892
893         // Only adding plugins to the workspace if they can be displayed for the current user role
894         _.each(PluginsConfiguration.plugins, (plugin: Plugin) => {
895             if (this.pluginsService.isPluginDisplayedInContext(plugin, this.role, this.$scope.component.getComponentSubType())) {
896                 menuItemsObjects.push({
897                     text: plugin.pluginDisplayOptions["context"].displayName,
898                     action: 'onMenuItemPressed',
899                     state: 'workspace.plugins',
900                     params: {path: plugin.pluginStateUrl}
901                 });
902             }
903         });
904
905         this.$scope.leftBarTabs.menuItems = menuItemsObjects.map((item:MenuItem) => {
906             const menuItem = new MenuItem(item.text, item.callback, item.state, item.action, item.params, item.blockedForTypes);
907             if (menuItem.params) {
908                 menuItem.params.state = menuItem.state;
909             }
910             else {
911                 menuItem.params = {state: menuItem.state};
912             }
913             menuItem.callback = () => this.$scope[menuItem.action](menuItem.state, menuItem.params);
914             menuItem.isDisabled = (inCreateMode && States.WORKSPACE_GENERAL != menuItem.state) ||
915                 (States.WORKSPACE_DEPLOYMENT === menuItem.state && this.$scope.component.modules && this.$scope.component.modules.length === 0 && this.$scope.component.isResource());
916             return menuItem;
917         });
918
919         if (this.cacheService.get('breadcrumbsComponents')) {
920             this.initBreadcrumbs();
921         }
922     }
923
924
925
926     private showSuccessNotificationMessage = ():void => {
927         this.Notification.success({
928             message: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_FINISHED_DESCRIPTION"),
929             title: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_FINISHED_TITLE")
930         });
931     };
932
933     private setWorkspaceButtonState = (newState:boolean, callback?:Function) => {
934         this.$scope.unsavedChanges = newState;
935         this.$scope.unsavedChangesCallback = callback;
936     }
937
938 }