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