2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
22 * Created by obarda on 3/30/2016.
25 import * as _ from "lodash";
26 import {IUserProperties, IAppMenu, Resource, Component, Plugin, PluginsConfiguration, PluginDisplayOptions} from "app/models";
28 WorkspaceMode, ComponentFactory, ChangeLifecycleStateHandler, Role, ComponentState, MenuItemGroup, MenuHandler,
29 MenuItem, ModalsHandler, States, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FLAG, ResourceType, PREVIOUS_CSAR_COMPONENT
36 LeftPaletteLoaderService
37 } from "app/services";
38 import {FileUploadModel} from "../../directives/file-upload/file-upload";
39 import {AutomatedUpgradeService} from "../../ng2/pages/automated-upgrade/automated-upgrade.service";
40 import {ComponentServiceNg2} from "../../ng2/services/component-services/component.service";
41 import {EventBusService} from "../../ng2/services/event-bus.service";
42 import {PluginsService} from "../../ng2/services/plugins.service";
43 import {IDependenciesServerResponse} from "../../ng2/services/responses/dependencies-server-response";
46 export interface IWorkspaceViewModelScope extends ng.IScope {
49 isCreateProgress:boolean;
51 originComponent:Component;
54 leftBarTabs:MenuItemGroup;
58 isActiveTopBar:boolean;
60 breadcrumbsModel:Array<MenuItemGroup>;
62 changeLifecycleStateButtons:any;
64 versionsList:Array<any>;
66 isComposition:boolean;
69 $state:ng.ui.IStateService;
72 disabledButtons:boolean;
73 menuComponentTitle:string;
74 progressService:ProgressService;
75 progressMessage:string;
76 ComponentServiceNg2: ComponentServiceNg2;
77 // leftPanelComponents:Array<Models.Components.Component>; //this is in order to load the left panel once, and not wait long time when moving to composition
78 unsavedChanges:boolean;
79 unsavedChangesCallback:Function;
83 startProgress(message:string):void;
85 updateBreadcrumbs(component:Component):void;
86 updateUnsavedFileFlag(isUnsaved:boolean):void;
87 showChangeStateButton():boolean;
88 getComponent():Component;
89 setComponent(component:Component):void;
90 setOriginComponent(component:Component):void;
91 onMenuItemPressed(state:string, params:any):ng.IPromise<boolean>;
94 setValidState(isValid:boolean):void;
95 changeLifecycleState(state:string):void;
96 handleChangeLifecycleState(state:string, newCsarVersion?:string):void;
97 disableMenuItems():void;
98 enableMenuItems():void;
100 isViewMode():boolean;
101 isEditMode():boolean;
102 isCreateMode():boolean;
103 isDisableMode():boolean;
104 isGeneralView():boolean;
105 goToBreadcrumbHome():void;
106 onVersionChanged(selectedId:string):void;
107 getLatestVersion():void;
109 showLifecycleIcon():boolean;
110 updateSelectedMenuItem(state:string):void;
111 isSelected(menuItem:MenuItem):boolean;
112 uploadFileChangedInGeneralTab():void;
113 updateMenuComponentName(ComponentName:string):void;
114 getTabTitle():string;
115 reload(component:Component):void;
118 export class WorkspaceViewModel {
128 'Sdc.Services.CacheService',
129 'ChangeLifecycleStateHandler',
131 'LeftPaletteLoaderService',
133 'EventListenerService',
134 'Sdc.Services.EntityService',
137 'Sdc.Services.ProgressService',
138 'ComponentServiceNg2',
139 'AutomatedUpgradeService',
144 constructor(private $scope:IWorkspaceViewModelScope,
145 private injectComponent:Component,
146 private ComponentFactory:ComponentFactory,
147 private $state:ng.ui.IStateService,
148 private sdcMenu:IAppMenu,
149 private $q:ng.IQService,
150 private MenuHandler:MenuHandler,
151 private cacheService:CacheService,
152 private ChangeLifecycleStateHandler:ChangeLifecycleStateHandler,
153 private ModalsHandler:ModalsHandler,
154 private LeftPaletteLoaderService:LeftPaletteLoaderService,
155 private $filter:ng.IFilterService,
156 private EventListenerService:EventListenerService,
157 private EntityService:EntityService,
158 private Notification:any,
159 private $stateParams:any,
160 private progressService:ProgressService,
161 private ComponentServiceNg2:ComponentServiceNg2,
162 private AutomatedUpgradeService:AutomatedUpgradeService,
163 private eventBusService:EventBusService,
164 private pluginsService:PluginsService) {
169 this.initAfterScope();
170 this.$scope.updateSelectedMenuItem(this.$state.current.name);
174 private components:Array<Component>;
176 private initViewMode = ():WorkspaceMode => {
177 let mode = WorkspaceMode.VIEW;
179 if (!this.$state.params['id']) { //&& !this.$state.params['vspComponent']
180 mode = WorkspaceMode.CREATE;
182 if (this.$scope.component.lifecycleState === ComponentState.NOT_CERTIFIED_CHECKOUT &&
183 this.$scope.component.lastUpdaterUserId === this.cacheService.get("user").userId) {
184 if ((this.$scope.component.isService() || this.$scope.component.isResource()) && this.role == Role.DESIGNER) {
185 mode = WorkspaceMode.EDIT;
192 private initChangeLifecycleStateButtons = ():void => {
193 let state = this.$scope.component.isService() && (Role.OPS == this.role || Role.GOVERNOR == this.role) ? this.$scope.component.distributionStatus : this.$scope.component.lifecycleState;
194 this.$scope.changeLifecycleStateButtons = (this.sdcMenu.roles[this.role].changeLifecycleStateButtons[state] || [])[this.$scope.component.componentType.toUpperCase()];
198 private initLeftPalette = ():void => {
199 //this.LeftPaletteLoaderService.loadLeftPanel(this.$scope.component);
202 private initScope = ():void => {
204 this.$scope.component = this.injectComponent;
205 //this.initLeftPalette();
206 this.$scope.menuComponentTitle = this.$scope.component.name;
207 this.$scope.disabledButtons = false;
208 this.$scope.originComponent = this.ComponentFactory.createComponent(this.$scope.component);
209 this.$scope.componentType = this.$scope.component.componentType;
210 this.$scope.version = this.cacheService.get('version');
211 this.$scope.user = this.cacheService.get("user");
212 this.role = this.$scope.user.role;
213 this.$scope.mode = this.initViewMode();
214 this.$scope.isValidForm = true;
215 this.initChangeLifecycleStateButtons();
216 this.initVersionObject();
217 this.$scope.$state = this.$state;
218 this.$scope.isLoading = false;
219 this.$scope.isComposition = (this.$state.current.name.indexOf(States.WORKSPACE_COMPOSITION) > -1);
220 this.$scope.isDeployment = this.$state.current.name == States.WORKSPACE_DEPLOYMENT;
221 this.$scope.progressService = this.progressService;
222 this.$scope.unsavedChanges = false;
224 this.EventListenerService.registerObserverCallback(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.setWorkspaceButtonState);
225 //this.EventListenerService.registerObserverCallback(EVENTS.ON_UPDATE_VSP_FILE, this.updateVspFlag);
227 this.$scope.getComponent = ():Component => {
228 return this.$scope.component;
231 this.$scope.updateMenuComponentName = (ComponentName:string):void => {
232 this.$scope.menuComponentTitle = ComponentName;
235 this.$scope.sdcMenu = this.sdcMenu;
236 // Will be called from each step after save to update the resource.
237 this.$scope.setComponent = (component:Component):void => {
238 this.$scope.component = component;
241 this.$scope.setOriginComponent = (component:Component):void => {
242 this.$scope.originComponent = component;
245 this.$scope.uploadFileChangedInGeneralTab = ():void => {
246 // In case user select browse file, and in update mode, need to disable submit for testing and checkin buttons.
247 if (this.$scope.isEditMode() && this.$scope.component.isResource() && (<Resource>this.$scope.component).resourceType == ResourceType.VF) {
248 // NOTE: Commented out the disabling of the workspace buttons on CSAR updating due fix of a bug [417534]
249 // this.$scope.disabledButtons = true;
253 this.$scope.archiveComponent = ():void => {
254 this.$scope.isLoading = true;
255 const typeComponent = this.$scope.component.componentType;
256 this.ComponentServiceNg2.archiveComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=>{
257 this.$scope.isLoading = false;
258 if(this.$state.params.previousState){
259 switch(this.$state.params.previousState){
262 this.$state.go(this.$state.params.previousState);
268 this.$scope.component.archived = true;
269 this.deleteArchiveCache();
271 this.Notification.success({
272 message: this.$scope.component.name + ' ' + this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TEXT"),
273 title: this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TITLE")
275 }, (error) => { this.$scope.isLoading = false; });
278 this.$scope.restoreComponent = ():void => {
279 this.$scope.isLoading = true;
280 const typeComponent = this.$scope.component.componentType;
281 this.ComponentServiceNg2.restoreComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=>{
282 this.$scope.isLoading = false;
283 this.Notification.success({
284 message: this.$scope.component.name + ' ' + this.$filter('translate')("RESTORE_SUCCESS_MESSAGE_TEXT"),
285 title: this.$filter('translate')("RESTORE_SUCCESS_MESSAGE_TITLE")
288 this.$scope.component.archived = false;
289 this.deleteArchiveCache();
292 this.$scope.$on('$stateChangeStart', (event, toState, toParams, fromState, fromParams) => {
293 if(this.$scope.isEditMode()){
294 if (fromParams.id == toParams.id && this.$state.current.data && this.$state.current.data.unsavedChanges) {
295 event.preventDefault();
296 if(this.$scope.isValidForm){
297 this.$scope.save().then(() => {
298 this.$scope.onMenuItemPressed(toState.name, toParams);
300 console.error("Save failed, unable to navigate to " + toState.name);
303 console.error("Form is invalid, unable to navigate to " + toState.name);
310 this.$scope.$on('$stateChangeSuccess', (event, toState) => {
311 this.$scope.updateSelectedMenuItem(this.$state.current.name);
314 this.$scope.onMenuItemPressed = (state:string, params:any):ng.IPromise<boolean> => {
316 let deferred:ng.IDeferred<boolean> = this.$q.defer();
317 let goToState = ():void => {
318 this.$state.go(state, Object.assign({
319 id: this.$scope.component.uniqueId,
320 type: this.$scope.component.componentType.toLowerCase(),
321 components: this.components
323 deferred.resolve(true);
326 if (this.$scope.isEditMode() && //this is a workaround for amdocs - we need to get the artifact in order to avoid saving the vf when moving from their tabs
327 (this.$state.current.name === States.WORKSPACE_MANAGEMENT_WORKFLOW || this.$state.current.name === States.WORKSPACE_NETWORK_CALL_FLOW)) {
328 let onGetSuccess = (component:Component) => {
329 this.$scope.isLoading = false;
330 // Update the components
331 this.$scope.component = component;
334 let onFailed = () => {
335 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_ERROR);
336 this.$scope.isLoading = false; // stop the progress.
337 deferred.reject(false);
339 this.$scope.component.getComponent().then(onGetSuccess, onFailed);
343 return deferred.promise;
346 this.$scope.setValidState = (isValid:boolean):void => {
347 this.$scope.isValidForm = isValid;
350 this.$scope.onVersionChanged = (selectedId:string):void => {
351 if (this.$scope.isGeneralView() && this.$state.current.data.unsavedChanges) {
352 this.$scope.changeVersion.selectedVersion = _.find(this.$scope.versionsList, (versionObj)=> {
353 return versionObj.versionId === this.$scope.component.uniqueId;
358 uuid: this.$scope.component.uuid,
359 version: this.$scope.changeVersion.selectedVersion.versionNumber
362 this.eventBusService.notify("VERSION_CHANGED", eventData).subscribe(() => {
363 this.$scope.isLoading = true;
365 this.$state.go(this.$state.current.name, {
367 type: this.$scope.componentType.toLowerCase(),
368 mode: WorkspaceMode.VIEW,
369 components: this.$state.params['components']
374 this.$scope.getLatestVersion = ():void => {
375 this.$scope.onVersionChanged(_.first(this.$scope.versionsList).versionId);
378 this.$scope.create = () => {
380 this.$scope.startProgress("Creating Asset...");
381 _.first(this.$scope.leftBarTabs.menuItems).isDisabled = true;//disabled click on general tab (DE246274)
383 // In case we import CSAR. Notify user that import VF will take long time (the create is performed in the background).
384 if (this.$scope.component.isResource() && (<Resource>this.$scope.component).csarUUID) {
385 this.Notification.info({
386 message: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_DESCRIPTION"),
387 title: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_TITLE")
391 let onFailed = () => {
392 this.$scope.stopProgress();
393 this.$scope.isLoading = false; // stop the progress.
394 _.first(this.$scope.leftBarTabs.menuItems).isDisabled = false;//enabled click on general tab (DE246274)
395 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_ERROR);
396 let modalInstance:ng.ui.bootstrap.IModalServiceInstance;
397 modalInstance && modalInstance.close(); // Close the modal in case it is opened.
398 this.$scope.component.tags = _.without(this.$scope.component.tags, this.$scope.component.name);// for fix DE246217
400 this.$scope.setValidState(true); // Set the form valid (if sent form is valid, the error from server).
403 let onSuccessCreate = (component:Component) => {
405 this.$scope.stopProgress();
406 this.showSuccessNotificationMessage();
408 // Update the components list for breadcrumbs
409 this.components.unshift(component);
411 this.$state.go(States.WORKSPACE_GENERAL, {
412 id: component.uniqueId,
413 type: component.componentType.toLowerCase(),
414 components: this.components
415 }, {inherit: false});
418 this.ComponentFactory.createComponentOnServer(this.$scope.component).then(onSuccessCreate, onFailed);
423 this.$scope.save = ():Promise<void> => {
425 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_CLICK);
427 this.$scope.startProgress("Updating Asset...");
428 this.$scope.disableMenuItems();
430 return new Promise<void>((resolve, reject) => {
431 let stopProgressAndEnableUI = () => {
432 this.$scope.disabledButtons = false;
433 this.$scope.isLoading = false;
434 this.$scope.enableMenuItems();
435 this.$scope.stopProgress();
438 let onFailed = () => {
439 stopProgressAndEnableUI();
440 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_ERROR);
445 let onSuccessUpdate = (component:Component) => {
446 stopProgressAndEnableUI();
447 this.showSuccessNotificationMessage();
449 component.tags = _.reject(component.tags, (item)=> {
450 return item === component.name
453 this.$scope.updateBreadcrumbs(component);
455 //update the component
456 this.$scope.setComponent(component);
457 this.$scope.originComponent = this.ComponentFactory.createComponent(this.$scope.component);
459 if (this.cacheService.contains(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
460 this.cacheService.remove(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
462 if (this.cacheService.contains(PREVIOUS_CSAR_COMPONENT)){
463 this.cacheService.remove(PREVIOUS_CSAR_COMPONENT);
467 this.$state.current.data.unsavedChanges = false;
468 this.$scope.unsavedFile = false;
472 this.$scope.component.updateComponent().then(onSuccessUpdate, onFailed);
477 this.$scope.changeLifecycleState = (state:string):void => {
478 if (this.$scope.isGeneralView() && state !== 'deleteVersion') {
479 this.EventListenerService.notifyObservers(EVENTS.ON_LIFECYCLE_CHANGE_WITH_SAVE, state);
481 this.$scope.handleChangeLifecycleState(state);
485 let defaultActionAfterChangeLifecycleState = ():void => {
486 if (this.$state.current.data && this.$state.current.data.unsavedChanges) {
487 this.$state.current.data.unsavedChanges = false;
489 this.$state.go('dashboard');
492 this.$scope.handleChangeLifecycleState = (state:string, newCsarVersion?:string) => {
493 if ('monitor' === state) {
494 this.$state.go('workspace.distribution');
498 let data = this.$scope.changeLifecycleStateButtons[state];
499 let onSuccess = (component:Component, url:string):void => {
500 //Updating the component from server response
502 // Creating the data object to notify the plugins with
503 let eventData: any = {
504 uuid: this.$scope.component.uuid,
505 version: this.$scope.component.version
508 //the server returns only metaData (small component) except checkout (Full component) ,so we update only the statuses of distribution & lifecycle
509 this.$scope.component.lifecycleState = component.lifecycleState;
510 this.$scope.component.distributionStatus = component.distributionStatus;
513 case 'lifecycleState/CHECKOUT':
514 this.eventBusService.notify("CHECK_OUT", eventData, false).subscribe(() => {
515 // only checkOut get the full component from server
516 // this.$scope.component = component;
517 // Work around to change the csar version
519 this.cacheService.set(CHANGE_COMPONENT_CSAR_VERSION_FLAG, newCsarVersion);
522 //when checking out a minor version uuid remains
523 const bcIdx = _.findIndex(this.components, (item) => {
524 return item.uuid === component.uuid;
527 this.components[bcIdx] = component;
529 //when checking out a major(certified) version
530 this.components.unshift(component);
532 this.$scope.mode = this.initViewMode();
533 this.initChangeLifecycleStateButtons();
534 this.initVersionObject();
535 this.$scope.isLoading = false;
536 this.EventListenerService.notifyObservers(EVENTS.ON_CHECKOUT, component);
538 this.Notification.success({
539 message: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TEXT"),
540 title: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TITLE")
545 case 'lifecycleState/CHECKIN':
546 defaultActionAfterChangeLifecycleState();
547 this.Notification.success({
548 message: this.$filter('translate')("CHECKIN_SUCCESS_MESSAGE_TEXT"),
549 title: this.$filter('translate')("CHECKIN_SUCCESS_MESSAGE_TITLE")
552 case 'lifecycleState/UNDOCHECKOUT':
553 this.eventBusService.notify("UNDO_CHECK_OUT", eventData, false).subscribe(() => {
554 defaultActionAfterChangeLifecycleState();
555 this.Notification.success({
556 message: this.$filter('translate')("DELETE_SUCCESS_MESSAGE_TEXT"),
557 title: this.$filter('translate')("DELETE_SUCCESS_MESSAGE_TITLE")
561 case 'lifecycleState/certificationRequest':
562 defaultActionAfterChangeLifecycleState();
563 this.Notification.success({
564 message: this.$filter('translate')("SUBMIT_FOR_TESTING_SUCCESS_MESSAGE_TEXT"),
565 title: this.$filter('translate')("SUBMIT_FOR_TESTING_SUCCESS_MESSAGE_TITLE")
569 case 'lifecycleState/failCertification':
570 defaultActionAfterChangeLifecycleState();
571 this.Notification.success({
572 message: this.$filter('translate')("REJECT_SUCCESS_MESSAGE_TEXT"),
573 title: this.$filter('translate')("REJECT_SUCCESS_MESSAGE_TITLE")
576 case 'lifecycleState/certify':
578 this.$scope.handleCertification(component);
581 //DE203504 Bug Fix Start
582 case 'lifecycleState/startCertification':
583 this.initChangeLifecycleStateButtons();
584 this.Notification.success({
585 message: this.$filter('translate')("START_TESTING_SUCCESS_MESSAGE_TEXT"),
586 title: this.$filter('translate')("START_TESTING_SUCCESS_MESSAGE_TITLE")
589 case 'lifecycleState/cancelCertification':
590 this.initChangeLifecycleStateButtons();
591 this.Notification.success({
592 message: this.$filter('translate')("CANCEL_TESTING_SUCCESS_MESSAGE_TEXT"),
593 title: this.$filter('translate')("CANCEL_TESTING_SUCCESS_MESSAGE_TITLE")
597 case 'distribution/PROD/activate':
598 this.initChangeLifecycleStateButtons();
599 this.Notification.success({
600 message: this.$filter('translate')("DISTRIBUTE_SUCCESS_MESSAGE_TEXT"),
601 title: this.$filter('translate')("DISTRIBUTE_SUCCESS_MESSAGE_TITLE")
605 case 'distribution-state/reject':
606 this.initChangeLifecycleStateButtons();
607 this.Notification.success({
608 message: this.$filter('translate')("REJECT_SUCCESS_MESSAGE_TEXT"),
609 title: this.$filter('translate')("REJECT_SUCCESS_MESSAGE_TITLE")
612 case 'distribution-state/approve':
613 this.initChangeLifecycleStateButtons();
614 this.$state.go('catalog');
615 this.Notification.success({
616 message: this.$filter('translate')("APPROVE_SUCCESS_MESSAGE_TEXT"),
617 title: this.$filter('translate')("APPROVE_SUCCESS_MESSAGE_TITLE")
620 //DE203504 Bug Fix End
623 defaultActionAfterChangeLifecycleState();
626 if (data.url != 'lifecycleState/CHECKOUT') {
627 this.$scope.isLoading = false;
630 //this.$scope.isLoading = true;
632 this.ChangeLifecycleStateHandler.changeLifecycleState(this.$scope.component, data, this.$scope, onSuccess);
637 this.$scope.isViewMode = ():boolean => {
638 return this.$scope.mode === WorkspaceMode.VIEW;
641 this.$scope.isDesigner = ():boolean => {
642 return this.role == Role.DESIGNER;
645 this.$scope.isDisableMode = ():boolean => {
646 return this.$scope.mode === WorkspaceMode.VIEW && this.$scope.component.lifecycleState === ComponentState.NOT_CERTIFIED_CHECKIN;
649 this.$scope.isGeneralView = ():boolean => {
650 //we show revert and save icons only in general view
651 return this.$state.current.name === States.WORKSPACE_GENERAL;
654 this.$scope.isCreateMode = ():boolean => {
655 return this.$scope.mode === WorkspaceMode.CREATE;
658 this.$scope.isEditMode = ():boolean => {
659 return this.$scope.mode === WorkspaceMode.EDIT;
662 this.$scope.goToBreadcrumbHome = ():void => {
663 let bcHome:MenuItemGroup = this.$scope.breadcrumbsModel[0];
664 this.$state.go(bcHome.menuItems[bcHome.selectedIndex].state);
667 this.$scope.showLifecycleIcon = ():boolean => {
668 return this.role == Role.DESIGNER;
671 this.$scope.getStatus = ():string => {
672 if (this.$scope.isCreateMode()) {
676 return this.$scope.component.getStatus(this.sdcMenu);
679 this.initMenuItems();
681 this.$scope.showChangeStateButton = ():boolean => {
682 let result:boolean = true;
683 if (!this.$scope.component.isLatestVersion() && Role.OPS != this.role && Role.GOVERNOR != this.role) {
686 if (ComponentState.NOT_CERTIFIED_CHECKOUT === this.$scope.component.lifecycleState && this.$scope.isViewMode()) {
689 if (ComponentState.CERTIFIED != this.$scope.component.lifecycleState &&
690 (Role.OPS == this.role || Role.GOVERNOR == this.role)) {
696 this.$scope.updateSelectedMenuItem = (state:string):void => {
697 let stateArray:Array<string> = state.split('.', 2);
698 let stateWithoutInternalNavigate:string = stateArray[0] + '.' + stateArray[1];
699 let selectedItem:MenuItem = _.find(this.$scope.leftBarTabs.menuItems, (item:MenuItem) => {
700 let itemStateArray: Array<string> = item.state.split('.', 2);
701 let itemStateWithoutNavigation:string = itemStateArray[0] + '.' + itemStateArray[1];
702 return (itemStateWithoutNavigation === stateWithoutInternalNavigate);
705 let selectedIndex = selectedItem ? this.$scope.leftBarTabs.menuItems.indexOf(selectedItem) : 0;
707 if (stateArray[1] === 'plugins') {
708 _.forEach(PluginsConfiguration.plugins, (plugin) => {
709 if (plugin.pluginStateUrl == this.$state.params.path) {
712 else if (this.pluginsService.isPluginDisplayedInContext(plugin, this.role, this.$scope.component.getComponentSubType())) {
718 this.$scope.leftBarTabs.selectedIndex = selectedIndex;
721 this.$scope.isSelected = (menuItem:MenuItem): boolean => {
722 return this.$scope.leftBarTabs.selectedIndex === _.indexOf(this.$scope.leftBarTabs.menuItems, menuItem);
725 this.$scope.$watch('$state.current.name', (newVal:string):void => {
727 this.$scope.isComposition = (newVal.indexOf(States.WORKSPACE_COMPOSITION) > -1);
728 this.$scope.isDeployment = newVal == States.WORKSPACE_DEPLOYMENT;
729 this.$scope.isPlugins = newVal == States.WORKSPACE_PLUGINS;
733 this.$scope.getTabTitle = ():string => {
734 return this.$scope.leftBarTabs.menuItems.find((menuItem:MenuItem) => {
735 return menuItem.state == this.$scope.$state.current.name;
739 this.$scope.reload = (component:Component):void => {
740 this.$state.go(this.$state.current.name, {id: component.uniqueId}, {reload: true});
743 this.$scope.$on('$destroy', () => {
744 this.EventListenerService.unRegisterObserver(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES);
747 this.$scope.openAutomatedUpgradeModal = ():void => {
748 this.$scope.isLoading = true;
749 this.ComponentServiceNg2.getDependencies(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response:Array<IDependenciesServerResponse>)=> {
750 this.$scope.isLoading = false;
751 this.AutomatedUpgradeService.openAutomatedUpgradeModal(response, this.$scope.component, false);
755 this.$scope.handleCertification = (certifyComponent): void => {
756 if (this.$scope.component.getComponentSubType() === ResourceType.VF) {
757 this.ComponentServiceNg2.getDependencies(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response:Array<IDependenciesServerResponse>) => {
758 this.$scope.isLoading = false;
760 let isUpgradeNeeded = _.filter(response, (componentToUpgrade:IDependenciesServerResponse) => {
761 return componentToUpgrade.dependencies && componentToUpgrade.dependencies.length > 0;
763 if(isUpgradeNeeded.length === 0) {
764 this.onSuccessWithoutUpgradeNeeded();
767 this.refreshDataAfterChangeLifecycleState(certifyComponent);
768 this.AutomatedUpgradeService.openAutomatedUpgradeModal(response, this.$scope.component, true);
771 this.onSuccessWithoutUpgradeNeeded();
775 this.$scope.disableMenuItems = () => {
776 this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => {
777 item.isDisabled = (States.WORKSPACE_GENERAL != item.state);
781 this.$scope.enableMenuItems = () => {
782 this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => {
783 item.isDisabled = false;
788 this.$scope.startProgress = (message:string):void => {
789 this.progressService.initCreateComponentProgress(this.$scope.component.uniqueId);
790 this.$scope.isCreateProgress = true;
791 this.$scope.progressMessage = message;
794 this.$scope.stopProgress = ():void => {
795 this.$scope.isCreateProgress = false;
796 this.progressService.deleteProgressValue(this.$scope.component.uniqueId);
799 this.$scope.updateBreadcrumbs = (component:Component):void => {
800 // Update the components list for breadcrumbs
801 const bcIdx = this.MenuHandler.findBreadcrumbComponentIndex(this.components, component);
803 this.components[bcIdx] = component;
804 this.initBreadcrumbs(); // re-calculate breadcrumbs
808 this.$scope.updateUnsavedFileFlag = (isUnsaved:boolean) => {
809 this.$scope.unsavedFile = isUnsaved;
814 private onSuccessWithoutUpgradeNeeded = ():void => {
815 this.$scope.isLoading = false;
816 this.Notification.success({
817 message: this.$filter('translate')("ACCEPT_TESTING_SUCCESS_MESSAGE_TEXT"),
818 title: this.$filter('translate')("ACCEPT_TESTING_SUCCESS_MESSAGE_TITLE")
820 this.$state.go('dashboard');
822 private refreshDataAfterChangeLifecycleState = (component:Component):void => {
823 this.$scope.isLoading = false;
824 this.$scope.mode = this.initViewMode();
825 this.initChangeLifecycleStateButtons();
826 this.initVersionObject();
827 this.EventListenerService.notifyObservers(EVENTS.ON_LIFECYCLE_CHANGE, component);
830 private initAfterScope = ():void => {
831 // In case user select csar from the onboarding modal, need to disable checkout and submit for testing.
832 if (this.$state.params['disableButtons'] === true) {
833 this.$scope.uploadFileChangedInGeneralTab();
837 private initVersionObject = ():void => {
838 this.$scope.versionsList = (this.$scope.component.getAllVersionsAsSortedArray()).reverse();
839 this.$scope.changeVersion = {
840 selectedVersion: _.find(this.$scope.versionsList, (versionObj)=> {
841 return versionObj.versionId === this.$scope.component.uniqueId;
846 private getNewComponentBreadcrumbItem = ():MenuItem => {
848 if (this.$scope.component.isResource() && (<Resource>this.$scope.component).isCsarComponent()) {
849 text = this.$scope.component.getComponentSubType() + ': ' + this.$scope.component.name;
851 text = 'Create new ' + this.$state.params['type'];
853 return new MenuItem(text, null, States.WORKSPACE_GENERAL, 'goToState', [this.$state.params]);
856 private updateMenuItemByRole = (menuItems:Array<any>, role:string) => {
857 let tempMenuItems:Array<any> = new Array<any>();
858 menuItems.forEach((item:any) => {
859 //remove item if role is disabled
860 if (!(item.disabledRoles && item.disabledRoles.indexOf(role) > -1)) {
861 tempMenuItems.push(item);
864 return tempMenuItems;
867 private deleteArchiveCache = () => {
868 this.cacheService.remove("archiveComponents"); //delete the cache to ensure the archive is reloaded from server
871 private initBreadcrumbs = () => {
872 this.components = this.cacheService.get('breadcrumbsComponents');
873 let breadcrumbsComponentsLvl = this.MenuHandler.generateBreadcrumbsModelFromComponents(this.components, this.$scope.component);
875 if (this.$scope.isCreateMode()) {
876 let createItem = this.getNewComponentBreadcrumbItem();
877 if (!breadcrumbsComponentsLvl.menuItems) {
878 breadcrumbsComponentsLvl.menuItems = [];
880 breadcrumbsComponentsLvl.menuItems.unshift(createItem);
881 breadcrumbsComponentsLvl.selectedIndex = 0;
884 this.$scope.breadcrumbsModel = [breadcrumbsComponentsLvl, this.$scope.leftBarTabs];
887 private initMenuItems() {
889 let inCreateMode = this.$scope.isCreateMode();
890 this.$scope.leftBarTabs = new MenuItemGroup();
891 const menuItemsObjects:Array<any> = this.updateMenuItemByRole(this.sdcMenu.component_workspace_menu_option[this.$scope.component.getComponentSubType()], this.role);
893 // Only adding plugins to the workspace if they can be displayed for the current user role
894 _.each(PluginsConfiguration.plugins, (plugin: Plugin) => {
895 if (this.pluginsService.isPluginDisplayedInContext(plugin, this.role, this.$scope.component.getComponentSubType())) {
896 menuItemsObjects.push({
897 text: plugin.pluginDisplayOptions["context"].displayName,
898 action: 'onMenuItemPressed',
899 state: 'workspace.plugins',
900 params: {path: plugin.pluginStateUrl}
905 this.$scope.leftBarTabs.menuItems = menuItemsObjects.map((item:MenuItem) => {
906 const menuItem = new MenuItem(item.text, item.callback, item.state, item.action, item.params, item.blockedForTypes);
907 if (menuItem.params) {
908 menuItem.params.state = menuItem.state;
911 menuItem.params = {state: menuItem.state};
913 menuItem.callback = () => this.$scope[menuItem.action](menuItem.state, menuItem.params);
914 menuItem.isDisabled = (inCreateMode && States.WORKSPACE_GENERAL != menuItem.state) ||
915 (States.WORKSPACE_DEPLOYMENT === menuItem.state && this.$scope.component.modules && this.$scope.component.modules.length === 0 && this.$scope.component.isResource());
919 if (this.cacheService.get('breadcrumbsComponents')) {
920 this.initBreadcrumbs();
926 private showSuccessNotificationMessage = ():void => {
927 this.Notification.success({
928 message: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_FINISHED_DESCRIPTION"),
929 title: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_FINISHED_TITLE")
933 private setWorkspaceButtonState = (newState:boolean, callback?:Function) => {
934 this.$scope.unsavedChanges = newState;
935 this.$scope.unsavedChangesCallback = callback;