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