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