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 {Component, DataTypeModel, IAppMenu, IUserProperties, Plugin, PluginsConfiguration, Resource, Service} from 'app/models';
28 CHANGE_COMPONENT_CSAR_VERSION_FLAG,
29 ChangeLifecycleStateHandler,
36 PREVIOUS_CSAR_COMPONENT,
42 import {EventListenerService, LeftPaletteLoaderService, ProgressService} from 'app/services';
43 import {CacheService} from 'app/services-ng2';
44 import {SdcUiCommon, SdcUiComponents, SdcUiServices} from 'onap-ui-angular';
45 import {AutomatedUpgradeService} from '../../ng2/pages/automated-upgrade/automated-upgrade.service';
46 import {CatalogService} from '../../ng2/services/catalog.service';
47 import {ComponentServiceNg2} from '../../ng2/services/component-services/component.service';
48 import {EventBusService} from '../../ng2/services/event-bus.service';
49 import {HomeService} from '../../ng2/services/home.service';
50 import {PluginsService} from '../../ng2/services/plugins.service';
51 import {IDependenciesServerResponse} from '../../ng2/services/responses/dependencies-server-response';
52 import {WorkspaceNg1BridgeService} from '../../ng2/pages/workspace/workspace-ng1-bridge-service';
53 import {WorkspaceService} from '../../ng2/pages/workspace/workspace.service';
55 export interface IWorkspaceViewModelScope extends ng.IScope {
58 isCreateProgress: boolean;
60 dataType: DataTypeModel;
61 originComponent: Component;
62 componentType: string;
64 leftBarTabs: MenuItemGroup;
66 isFromImport: boolean;
68 isActiveTopBar: boolean;
70 breadcrumbsModel: Array<MenuItemGroup>;
72 changeLifecycleStateButtons: any;
74 versionsList: Array<any>;
76 isComposition: boolean;
77 isDeployment: boolean;
79 $state: ng.ui.IStateService;
80 user: IUserProperties;
82 disabledButtons: boolean;
83 menuComponentTitle: string;
84 progressService: ProgressService;
85 progressMessage: string;
86 ComponentServiceNg2: ComponentServiceNg2;
87 unsavedChanges: boolean;
88 unsavedChangesCallback: Function;
90 hasNoDependencies: boolean;
91 models: Array<string>;
93 startProgress(message: string): void;
95 updateBreadcrumbs(component: Component): void;
96 updateUnsavedFileFlag(isUnsaved: boolean): void;
97 showChangeStateButton(): boolean;
98 getComponent(): Component;
99 setComponent(component: Component): void;
100 setOriginComponent(component: Component): void;
101 onMenuItemPressed(state: string, params: any): ng.IPromise<boolean>;
103 save(): Promise<void>;
104 setValidState(isValid: boolean): void;
105 changeLifecycleState(state: string): void;
106 handleChangeLifecycleState(state: string, newCsarVersion?: string, errorFunction?: Function): void;
107 disableMenuItems(): void;
108 enableMenuItems(): void;
109 isDesigner(): boolean;
110 isViewMode(): boolean;
111 isEditMode(): boolean;
112 isCreateMode(): boolean;
113 isDisableMode(): boolean;
114 isGeneralView(): boolean;
115 goToBreadcrumbHome(): void;
116 onVersionChanged(selectedId: string): void;
117 getLatestVersion(): void;
119 showLifecycleIcon(): boolean;
120 updateSelectedMenuItem(state: string): void;
121 isSelected(menuItem: MenuItem): boolean;
122 uploadFileChangedInGeneralTab(): void;
123 updateMenuComponentName(ComponentName: string): void;
124 getTabTitle(): string;
125 reload(component: Component): void;
128 export class WorkspaceViewModel {
138 'Sdc.Services.CacheService',
139 'ChangeLifecycleStateHandler',
140 'LeftPaletteLoaderService',
142 'EventListenerService',
147 'Sdc.Services.ProgressService',
148 'ComponentServiceNg2',
149 'AutomatedUpgradeService',
153 'WorkspaceNg1BridgeService',
157 constructor(private $scope: IWorkspaceViewModelScope,
158 private injectComponent: Component,
159 private ComponentFactory: ComponentFactory,
160 private $state: ng.ui.IStateService,
161 private sdcMenu: IAppMenu,
162 private $q: ng.IQService,
163 private MenuHandler: MenuHandler,
164 private cacheService: CacheService,
165 private ChangeLifecycleStateHandler: ChangeLifecycleStateHandler,
166 private LeftPaletteLoaderService: LeftPaletteLoaderService,
167 private $filter: ng.IFilterService,
168 private EventListenerService: EventListenerService,
169 private Notification: any,
170 private $stateParams: any,
171 private homeService: HomeService,
172 private catalogService: CatalogService,
173 private progressService: ProgressService,
174 private ComponentServiceNg2: ComponentServiceNg2,
175 private AutomatedUpgradeService: AutomatedUpgradeService,
176 private eventBusService: EventBusService,
177 private modalServiceSdcUI: SdcUiServices.ModalService,
178 private pluginsService: PluginsService,
179 private workspaceNg1BridgeService: WorkspaceNg1BridgeService,
180 private workspaceService: WorkspaceService) {
183 this.$scope.updateSelectedMenuItem(this.$state.current.name);
186 private role: string;
187 private category: string;
188 private components: Component[];
190 private initViewMode = ():WorkspaceMode => {
191 let mode = WorkspaceMode.VIEW;
193 if (!this.$state.params['id']) { //&& !this.$state.params['vspComponent']
194 mode = WorkspaceMode.CREATE;
196 if (this.$scope.component.lifecycleState === ComponentState.NOT_CERTIFIED_CHECKOUT &&
197 this.$scope.component.lastUpdaterUserId === this.cacheService.get('user').userId) {
198 if ((this.$scope.component.isService() || this.$scope.component.isResource()) && this.role === Role.DESIGNER) {
199 mode = WorkspaceMode.EDIT;
203 this.workspaceNg1BridgeService.updateIsViewOnly(mode === WorkspaceMode.VIEW);
207 private initChangeLifecycleStateButtons = (): void => {
209 if (this.$scope.component.isService() && this.$scope.component.lifecycleState === 'CERTIFIED') {
210 state = this.$scope.component.distributionStatus;
212 state = this.$scope.component.lifecycleState;
214 this.$scope.changeLifecycleStateButtons = (this.sdcMenu.roles[this.role].changeLifecycleStateButtons[state] || [])[this.$scope.component.componentType.toUpperCase()];
217 private initScope = (): void => {
218 this.$scope.component = this.injectComponent;
219 this.$scope.menuComponentTitle = this.$scope.component.name;
220 this.$scope.disabledButtons = false;
221 this.$scope.originComponent = this.ComponentFactory.createComponent(this.$scope.component);
222 this.$scope.componentType = this.$scope.component.componentType;
223 this.$scope.version = this.cacheService.get('version');
224 this.$scope.user = this.cacheService.get('user');
225 this.role = this.$scope.user.role;
226 this.category = this.$scope.component.selectedCategory;
227 this.$scope.mode = this.initViewMode();
228 this.$scope.isValidForm = true;
229 this.initChangeLifecycleStateButtons();
230 this.initVersionObject();
231 this.$scope.$state = this.$state;
232 this.$scope.isLoading = false;
233 this.$scope.isComposition = (this.$state.current.name.indexOf(States.WORKSPACE_COMPOSITION) > -1);
234 this.$scope.isDeployment = this.$state.current.name == States.WORKSPACE_DEPLOYMENT;
235 this.$scope.progressService = this.progressService;
236 this.$scope.unsavedChanges = false;
238 this.$scope.hasNoDependencies = true;
239 this.verifyIfDependenciesExist();
241 this.EventListenerService.registerObserverCallback(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.setWorkspaceButtonState);
242 this.$scope.getComponent = (): Component => {
243 return this.$scope.component;
246 this.$scope.updateMenuComponentName = (ComponentName:string):void => {
247 this.$scope.menuComponentTitle = ComponentName;
250 this.$scope.sdcMenu = this.sdcMenu;
251 // Will be called from each step after save to update the resource.
252 this.$scope.setComponent = (component:Component):void => {
253 this.$scope.component = component;
256 this.$scope.setOriginComponent = (component:Component):void => {
257 this.$scope.originComponent = component;
260 this.$scope.uploadFileChangedInGeneralTab = ():void => {
261 // In case user select browse file, and in update mode, need to disable submit for testing and checkin buttons.
262 if (this.$scope.isEditMode() && this.$scope.component.isResource() && (<Resource>this.$scope.component).resourceType == ResourceType.VF) {
263 // NOTE: Commented out the disabling of the workspace buttons on CSAR updating due fix of a bug [417534]
264 // this.$scope.disabledButtons = true;
268 this.$scope.archiveComponent = ():void => {
269 this.$scope.isLoading = true;
270 const typeComponent = this.$scope.component.componentType;
271 this.ComponentServiceNg2.archiveComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=> {
272 this.$scope.isLoading = false;
273 if (this.$state.params.previousState) {
274 switch (this.$state.params.previousState) {
277 this.$state.go(this.$state.params.previousState);
283 this.$scope.component.isArchived = true;
284 this.deleteArchiveCache();
286 this.Notification.success({
287 message: this.$scope.component.name + ' ' + this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TEXT"),
288 title: this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TITLE")
290 }, (error) => { this.$scope.isLoading = false; });
293 this.$scope.restoreComponent = ():void => {
294 this.$scope.isLoading = true;
295 const typeComponent = this.$scope.component.componentType;
296 this.ComponentServiceNg2.restoreComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=> {
297 this.$scope.isLoading = false;
298 this.Notification.success({
299 message: this.$scope.component.name + ' ' + this.$filter('translate')("RESTORE_SUCCESS_MESSAGE_TEXT"),
300 title: this.$filter('translate')("RESTORE_SUCCESS_MESSAGE_TITLE")
302 this.$scope.reload(this.$scope.component);
304 this.$scope.component.isArchived = false;
305 this.deleteArchiveCache();
308 this.$scope.$on('$stateChangeStart', (event, toState, toParams, fromState, fromParams) => {
309 if(this.$scope.isEditMode()){
310 if (fromParams.id == toParams.id && this.$state.current.data && this.$state.current.data.unsavedChanges) {
311 event.preventDefault();
312 if(this.$scope.isValidForm){
313 this.$scope.save().then(() => {
314 this.$scope.onMenuItemPressed(toState.name, toParams);
316 console.error("Save failed, unable to navigate to " + toState.name);
319 console.error("Form is invalid, unable to navigate to " + toState.name);
326 this.$scope.$on('$stateChangeSuccess', (event, toState) => {
327 this.$scope.updateSelectedMenuItem(this.$state.current.name);
330 this.$scope.onMenuItemPressed = (state:string, params:any):ng.IPromise<boolean> => {
332 let deferred:ng.IDeferred<boolean> = this.$q.defer();
333 let goToState = ():void => {
334 this.$state.go(state, Object.assign({
335 id: this.$scope.component.uniqueId,
336 type: this.$scope.component.componentType.toLowerCase(),
337 components: this.components
339 deferred.resolve(true);
342 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
343 (this.$state.current.name === States.WORKSPACE_MANAGEMENT_WORKFLOW || this.$state.current.name === States.WORKSPACE_NETWORK_CALL_FLOW)) {
344 let onGetSuccess = (component:Component) => {
345 this.$scope.isLoading = false;
346 // Update the components
347 this.$scope.component = component;
350 let onFailed = () => {
351 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_ERROR);
352 this.$scope.isLoading = false; // stop the progress.
353 deferred.reject(false);
355 this.$scope.component.getComponent().then(onGetSuccess, onFailed);
359 return deferred.promise;
362 this.$scope.setValidState = (isValid:boolean):void => {
363 this.$scope.isValidForm = isValid;
366 this.$scope.onVersionChanged = (selectedId:string):void => {
367 if (this.$scope.isGeneralView() && this.$state.current.data.unsavedChanges) {
368 this.$scope.changeVersion.selectedVersion = _.find(this.$scope.versionsList, (versionObj)=> {
369 return versionObj.versionId === this.$scope.component.uniqueId;
374 uuid: this.$scope.component.uuid,
375 version: this.$scope.changeVersion.selectedVersion.versionNumber
378 this.eventBusService.notify("VERSION_CHANGED", eventData).subscribe(() => {
379 this.$scope.isLoading = true;
381 this.$state.go(this.$state.current.name, {
383 type: this.$scope.componentType.toLowerCase(),
384 mode: WorkspaceMode.VIEW,
385 components: this.$state.params['components']
390 this.$scope.getLatestVersion = ():void => {
391 this.$scope.onVersionChanged(_.first(this.$scope.versionsList).versionId);
394 this.$scope.create = () => {
396 this.$scope.startProgress("Creating Asset...");
397 _.first(this.$scope.leftBarTabs.menuItems).isDisabled = true;//disabled click on general tab (DE246274)
399 // In case we import CSAR. Notify user that import VF will take long time (the create is performed in the background).
400 if (this.$scope.component.isResource() && (<Resource>this.$scope.component).csarUUID) {
401 this.Notification.info({
402 message: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_DESCRIPTION"),
403 title: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_TITLE")
407 let onFailed = () => {
408 this.$scope.stopProgress();
409 this.$scope.isLoading = false; // stop the progress.
410 _.first(this.$scope.leftBarTabs.menuItems).isDisabled = false;//enabled click on general tab (DE246274)
411 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_ERROR);
412 let modalInstance:ng.ui.bootstrap.IModalServiceInstance;
413 modalInstance && modalInstance.close(); // Close the modal in case it is opened.
414 this.$scope.component.tags = _.without(this.$scope.component.tags, this.$scope.component.name);// for fix DE246217
416 this.$scope.setValidState(true); // Set the form valid (if sent form is valid, the error from server).
419 let onSuccessCreate = (component:Component) => {
421 this.$scope.stopProgress();
422 this.showSuccessNotificationMessage();
424 // Update the components list for breadcrumbs
425 this.components.unshift(component);
427 this.$state.go(States.WORKSPACE_GENERAL, {
428 id: component.uniqueId,
429 type: component.componentType.toLowerCase(),
430 components: this.components
431 }, {inherit: false});
434 console.log(this.$scope.component, "this.$scope.component")
435 if ((<Service>this.$scope.component).serviceType == "Service") {
436 this.ComponentFactory.importComponentOnServer(this.$scope.component).then(onSuccessCreate, onFailed);
438 this.ComponentFactory.createComponentOnServer(this.$scope.component).then(onSuccessCreate, onFailed);
445 this.$scope.save = ():Promise<void> => {
447 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_CLICK);
449 this.$scope.startProgress("Updating Asset...");
450 this.$scope.disableMenuItems();
452 return new Promise<void>((resolve, reject) => {
453 let stopProgressAndEnableUI = () => {
454 this.$scope.disabledButtons = false;
455 this.$scope.isLoading = false;
456 this.$scope.enableMenuItems();
457 this.$scope.stopProgress();
460 let onFailed = () => {
461 stopProgressAndEnableUI();
462 this.$scope.updateUnsavedFileFlag(true);
463 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_ERROR);
468 let onSuccessUpdate = (component:Component) => {
469 stopProgressAndEnableUI();
470 this.showSuccessNotificationMessage();
472 component.tags = _.reject(component.tags, (item)=> {
473 return item === component.name
476 this.$scope.updateBreadcrumbs(component);
478 //update the component
479 this.$scope.setComponent(component);
480 this.$scope.originComponent = this.ComponentFactory.createComponent(this.$scope.component);
482 if (this.cacheService.contains(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
483 this.cacheService.remove(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
485 if (this.cacheService.contains(PREVIOUS_CSAR_COMPONENT)) {
486 this.cacheService.remove(PREVIOUS_CSAR_COMPONENT);
490 this.$state.current.data.unsavedChanges = false;
491 this.$scope.unsavedFile = false;
492 this.$scope.reload(component);
496 this.$scope.component.updateComponent().then(onSuccessUpdate, onFailed);
501 this.$scope.changeLifecycleState = (state:string):void => {
502 if (this.$scope.isGeneralView() && state !== 'deleteVersion') {
503 this.EventListenerService.notifyObservers(EVENTS.ON_LIFECYCLE_CHANGE_WITH_SAVE, state);
505 this.$scope.handleChangeLifecycleState(state);
509 let defaultActionAfterChangeLifecycleState = ():void => {
510 if (this.$state.current.data && this.$state.current.data.unsavedChanges) {
511 this.$state.current.data.unsavedChanges = false;
513 this.$state.go('dashboard');
516 this.$scope.handleChangeLifecycleState = (state:string, newCsarVersion?:string, onError?: Function) => {
517 if ('monitor' === state) {
518 this.$state.go('workspace.distribution');
522 let data = this.$scope.changeLifecycleStateButtons[state];
523 if (!data && this.$stateParams.componentCsar && !this.$scope.isCreateMode()) {
524 data = {text: 'Check Out', url: 'lifecycleState/CHECKOUT'};
526 const onSuccess = (component, url:string):void => {
527 // Updating the component from server response
529 // Creating the data object to notify the plugins with
530 const eventData: any = {
531 uuid: this.$scope.component.uuid,
532 version: this.$scope.component.version
535 // the server returns only metaData (small component) except checkout (Full component) ,so we update only the statuses of distribution & lifecycle
536 this.$scope.component.lifecycleState = component.lifecycleState;
537 this.$scope.component.distributionStatus = component.distributionStatus;
540 case 'lifecycleState/CHECKOUT':
541 this.workspaceNg1BridgeService.updateIsViewOnly(false);
542 this.eventBusService.notify("CHECK_OUT", eventData, false).subscribe(() => {
543 // only checkOut get the full component from server
544 // this.$scope.component = component;
545 // Work around to change the csar version
547 this.cacheService.set(CHANGE_COMPONENT_CSAR_VERSION_FLAG, newCsarVersion);
548 (this.$scope.component as Resource).csarVersion = newCsarVersion;
551 //when checking out a minor version uuid remains
552 const bcIdx = _.findIndex(this.components, (item) => {
553 return item.uuid === component.uuid;
556 this.components[bcIdx] = component;
558 //when checking out a major(certified) version
559 this.components.unshift(component);
561 this.$scope.mode = this.initViewMode();
562 this.initChangeLifecycleStateButtons();
563 this.initVersionObject();
564 this.$scope.isLoading = false;
565 this.EventListenerService.notifyObservers(EVENTS.ON_CHECKOUT, component);
566 this.workspaceService.setComponentMetadata(component.componentMetadata);
568 this.Notification.success({
569 message: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TEXT"),
570 title: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TITLE")
575 case 'lifecycleState/CHECKIN':
576 this.workspaceNg1BridgeService.updateIsViewOnly(true);
577 defaultActionAfterChangeLifecycleState();
578 this.Notification.success({
579 message: this.$filter('translate')("CHECKIN_SUCCESS_MESSAGE_TEXT"),
580 title: this.$filter('translate')("CHECKIN_SUCCESS_MESSAGE_TITLE")
583 case 'lifecycleState/UNDOCHECKOUT':
584 this.eventBusService.notify("UNDO_CHECK_OUT", eventData, false).subscribe(() => {
585 defaultActionAfterChangeLifecycleState();
586 this.Notification.success({
587 message: this.$filter('translate')("DELETE_SUCCESS_MESSAGE_TEXT"),
588 title: this.$filter('translate')("DELETE_SUCCESS_MESSAGE_TITLE")
592 case 'lifecycleState/certify':
593 this.$scope.handleCertification(component);
594 this.verifyIfDependenciesExist();
595 this.$scope.reload(component);
597 case 'distribution/PROD/activate':
598 this.Notification.success({
599 message: this.$filter('translate')("DISTRIBUTE_SUCCESS_MESSAGE_TEXT"),
600 title: this.$filter('translate')("DISTRIBUTE_SUCCESS_MESSAGE_TITLE")
602 this.initChangeLifecycleStateButtons();
605 defaultActionAfterChangeLifecycleState();
607 if (data.url !== 'lifecycleState/CHECKOUT') {
608 this.$scope.isLoading = false;
611 this.ChangeLifecycleStateHandler.changeLifecycleState(this.$scope.component, data, this.$scope, onSuccess);
614 this.$scope.deleteArchivedComponent = (): void => {
615 const modalTitle: string = this.$filter('translate')("COMPONENT_VIEW_DELETE_MODAL_TITLE");
616 const modalMessage: string = this.$filter('translate')("COMPONENT_VIEW_DELETE_MODAL_TEXT");
617 const modalButton = {
619 text: this.sdcMenu.alertMessages.okButton,
620 type: SdcUiCommon.ButtonType.warning,
621 callback: this.$scope.handleDeleteArchivedComponent,
623 } as SdcUiComponents.ModalButtonComponent;
624 this.modalServiceSdcUI.openWarningModal(modalTitle, modalMessage, 'alert-modal', [modalButton]);
627 this.$scope.handleDeleteArchivedComponent = (): void => {
628 this.$scope.isLoading = true;
629 const typeComponent = this.$scope.component.componentType;
630 this.ComponentServiceNg2.deleteComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=> {
631 this.deleteArchiveCache();
632 this.Notification.success({
633 message: this.$scope.component.name + ' ' + this.$filter('translate')("DELETE_SUCCESS_MESSAGE_TEXT"),
634 title: this.$filter('translate')("DELETE_SUCCESS_MESSAGE_TITLE")
636 if (this.$state.params.previousState) {
637 switch (this.$state.params.previousState) {
640 this.$state.go(this.$state.params.previousState);
643 this.$state.go('dashboard');
647 this.$scope.isLoading = false;
649 this.Notification.error({
650 message: this.$scope.component.name + ' ' + this.$filter('translate')('DELETE_FAILURE_MESSAGE_TEXT'),
651 title: this.$filter('translate')('DELETE_FAILURE_MESSAGE_TITLE')
653 this.$scope.isLoading = false;
657 this.$scope.isViewMode = ():boolean => {
658 return this.$scope.mode === WorkspaceMode.VIEW;
661 this.$scope.isDesigner = ():boolean => {
662 return this.role == Role.DESIGNER;
665 this.$scope.isDisableMode = ():boolean => {
666 return this.$scope.mode === WorkspaceMode.VIEW && this.$scope.component.lifecycleState === ComponentState.NOT_CERTIFIED_CHECKIN;
669 this.$scope.isGeneralView = ():boolean => {
670 //we show revert and save icons only in general view
671 return this.$state.current.name === States.WORKSPACE_GENERAL;
674 this.$scope.isCreateMode = ():boolean => {
675 return this.$scope.mode === WorkspaceMode.CREATE;
678 this.$scope.checkDisableButton = (button: any):boolean => {
679 // Logic moved from html to component
680 if (this.$scope.isCreateMode() || button.disabled || this.$scope.disabledButtons || !this.$scope.isValidForm || this.$scope.unsavedChanges || this.$scope.component.isArchived){
684 // Specific verification for Checkout - enabled only in case the component is the latest version.
685 let result: boolean = false;
687 if (button.url === 'lifecycleState/CHECKOUT') {
688 result = !this.$scope.component.isLatestVersion();
693 this.$scope.isEditMode = ():boolean => {
694 return this.$scope.mode === WorkspaceMode.EDIT;
697 this.$scope.goToBreadcrumbHome = ():void => {
698 let bcHome:MenuItemGroup = this.$scope.breadcrumbsModel[0];
699 this.$state.go(bcHome.menuItems[bcHome.selectedIndex].state);
702 this.$scope.showLifecycleIcon = ():boolean => {
703 return this.role == Role.DESIGNER;
706 this.$scope.getStatus = ():string => {
707 if (this.$scope.isCreateMode()) {
711 return this.$scope.component.getStatus(this.sdcMenu);
714 this.initMenuItems();
716 this.$scope.showLatestVersion = (): boolean => {
717 let result: boolean = true;
718 if (!this.$scope.component.isLatestVersion()) {
721 if (ComponentState.NOT_CERTIFIED_CHECKOUT === this.$scope.component.lifecycleState && this.$scope.isViewMode()) {
727 this.$scope.updateSelectedMenuItem = (state:string):void => {
728 let stateArray:Array<string> = state.split('.', 2);
729 let stateWithoutInternalNavigate:string = stateArray[0] + '.' + stateArray[1];
730 let selectedItem:MenuItem = _.find(this.$scope.leftBarTabs.menuItems, (item:MenuItem) => {
731 let itemStateArray:Array<string> = item.state.split('.', 2);
732 let itemStateWithoutNavigation:string = itemStateArray[0] + '.' + itemStateArray[1];
733 return (itemStateWithoutNavigation === stateWithoutInternalNavigate);
736 let selectedIndex = selectedItem ? this.$scope.leftBarTabs.menuItems.indexOf(selectedItem) : 0;
738 if (stateArray[1] === 'plugins') {
739 _.forEach(PluginsConfiguration.plugins, (plugin) => {
740 if (plugin.pluginStateUrl == this.$state.params.path) {
743 else if (this.pluginsService.isPluginDisplayedInContext(plugin, this.role, this.$scope.component.getComponentSubType())) {
749 this.$scope.leftBarTabs.selectedIndex = selectedIndex;
752 this.$scope.isSelected = (menuItem: MenuItem): boolean => {
753 return this.$scope.leftBarTabs.selectedIndex === _.indexOf(this.$scope.leftBarTabs.menuItems, menuItem);
756 this.$scope.$watch('$state.current.name', (newVal: string): void => {
758 this.$scope.isComposition = (newVal.indexOf(States.WORKSPACE_COMPOSITION) > -1);
759 this.$scope.isDeployment = newVal == States.WORKSPACE_DEPLOYMENT;
760 this.$scope.isPlugins = newVal == States.WORKSPACE_PLUGINS;
764 this.$scope.getTabTitle = (): string => {
765 return this.$scope.leftBarTabs.menuItems.find((menuItem: MenuItem) => {
766 return menuItem.state == this.$scope.$state.current.name;
770 this.$scope.reload = (component: Component): void => {
771 const isGeneralTab = this.$state.current.name === States.WORKSPACE_GENERAL;
772 // nullify the componentCsar in case we are in general tab so we know we didnt came from updateVsp Modal
774 this.$state.go(this.$state.current.name, {id: component.uniqueId, componentCsar: null}, {reload: true});
776 this.$state.go(this.$state.current.name, {id: component.uniqueId}, {reload: true});
780 this.$scope.$on('$destroy', () => {
781 this.EventListenerService.unRegisterObserver(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES);
784 this.$scope.openAutomatedUpgradeModal = ():void => {
785 this.$scope.isLoading = true;
786 this.ComponentServiceNg2.getDependencies(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response:Array<IDependenciesServerResponse>)=> {
787 this.$scope.isLoading = false;
788 this.AutomatedUpgradeService.openAutomatedUpgradeModal(response, this.$scope.component, false);
792 this.$scope.handleCertification = (certifyComponent): void => {
793 if (this.$scope.component.getComponentSubType() === ResourceType.VF || this.$scope.component.isService()) {
794 this.ComponentServiceNg2.getDependencies(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response:Array<IDependenciesServerResponse>) => {
795 this.$scope.isLoading = false;
797 const isUpgradeNeeded = _.filter(response, (componentToUpgrade:IDependenciesServerResponse) => {
798 return componentToUpgrade.dependencies && componentToUpgrade.dependencies.length > 0;
800 if (isUpgradeNeeded.length === 0) {
801 this.onSuccessWithoutUpgradeNeeded();
804 this.refreshDataAfterChangeLifecycleState(certifyComponent);
805 this.AutomatedUpgradeService.openAutomatedUpgradeModal(response, this.$scope.component, true);
808 this.onSuccessWithoutUpgradeNeeded();
812 this.$scope.disableMenuItems = () => {
813 this.$scope.leftBarTabs.menuItems.forEach((item: MenuItem) => {
814 item.isDisabled = (States.WORKSPACE_GENERAL !== item.state);
818 this.$scope.enableMenuItems = () => {
819 this.$scope.leftBarTabs.menuItems.forEach((item: MenuItem) => {
820 item.isDisabled = false;
825 this.$scope.startProgress = (message: string): void => {
826 this.progressService.initCreateComponentProgress(this.$scope.component.uniqueId);
827 this.$scope.isCreateProgress = true;
828 this.$scope.progressMessage = message;
831 this.$scope.stopProgress = (): void => {
832 this.$scope.isCreateProgress = false;
833 this.progressService.deleteProgressValue(this.$scope.component.uniqueId);
836 this.$scope.updateBreadcrumbs = (component: Component): void => {
837 // Update the components list for breadcrumbs
838 const bcIdx = this.MenuHandler.findBreadcrumbComponentIndex(this.components, component);
840 this.components[bcIdx] = component;
841 this.initBreadcrumbs(); // re-calculate breadcrumbs
845 this.$scope.updateUnsavedFileFlag = (isUnsaved:boolean) => {
846 this.$scope.unsavedFile = isUnsaved;
851 private onSuccessWithoutUpgradeNeeded = (): void => {
852 this.$scope.isLoading = false;
853 this.Notification.success({
854 message: this.$filter('translate')('SERVICE_CERTIFICATION_STATUS_TEXT'),
855 title: this.$filter('translate')('SERVICE_CERTIFICATION_STATUS_TITLE')
857 this.initVersionObject();
858 this.initChangeLifecycleStateButtons();
861 private refreshDataAfterChangeLifecycleState = (component:Component):void => {
862 this.$scope.isLoading = false;
863 this.$scope.mode = this.initViewMode();
864 this.initChangeLifecycleStateButtons();
865 this.initVersionObject();
866 this.EventListenerService.notifyObservers(EVENTS.ON_LIFECYCLE_CHANGE, component);
869 private initAfterScope = (): void => {
870 // In case user select csar from the onboarding modal, need to disable checkout and submit for testing.
871 if (this.$state.params['disableButtons'] === true) {
872 this.$scope.uploadFileChangedInGeneralTab();
876 private initVersionObject = (): void => {
877 this.$scope.versionsList = (this.$scope.component.getAllVersionsAsSortedArray()).reverse();
878 this.$scope.changeVersion = {
879 selectedVersion: _.find(this.$scope.versionsList, (versionObj) => {
880 return versionObj.versionId === this.$scope.component.uniqueId;
885 private getNewComponentBreadcrumbItem = (): MenuItem => {
887 if (this.$scope.component.isResource() && (<Resource>this.$scope.component).isCsarComponent()) {
888 text = this.$scope.component.getComponentSubType() + ': ' + this.$scope.component.name;
890 text = 'Create new ' + this.$state.params['type'];
892 return new MenuItem(text, null, States.WORKSPACE_GENERAL, 'goToState', [this.$state.params]);
895 private updateMenuItemByRole = (menuItems: any[], role: string) => {
896 const tempMenuItems: any[] = new Array<any>();
897 menuItems.forEach((item: any) => {
898 //remove item if role is disabled
899 if (!(item.disabledRoles && item.disabledRoles.indexOf(role) > -1)) {
900 tempMenuItems.push(item);
903 return tempMenuItems;
906 private updateMenuItemByCategory = (menuItems:Array<any>, category:string) => {
907 let tempMenuItems:Array<any> = new Array<any>();
908 menuItems.forEach((item:any) => {
909 //update flag disabledCategory to true if category is disabled
910 item.disabledCategory = false;
911 if ((item.disabledCategories && item.disabledCategories.indexOf(category) > -1))
913 item.disabledCategory = true;
915 tempMenuItems.push(item);
917 return tempMenuItems;
921 private deleteArchiveCache = () => {
922 this.cacheService.remove('archiveComponents'); // delete the cache to ensure the archive is reloaded from server
925 private initBreadcrumbs = () => {
926 this.components = this.cacheService.get('breadcrumbsComponents');
927 const breadcrumbsComponentsLvl = this.MenuHandler.generateBreadcrumbsModelFromComponents(this.components, this.$scope.component);
929 if (this.$scope.isCreateMode()) {
930 const createItem = this.getNewComponentBreadcrumbItem();
931 if (!breadcrumbsComponentsLvl.menuItems) {
932 breadcrumbsComponentsLvl.menuItems = [];
934 breadcrumbsComponentsLvl.menuItems.unshift(createItem);
935 breadcrumbsComponentsLvl.selectedIndex = 0;
938 this.$scope.breadcrumbsModel = [breadcrumbsComponentsLvl, this.$scope.leftBarTabs];
941 private initMenuItems() {
943 const inCreateMode = this.$scope.isCreateMode();
944 this.$scope.leftBarTabs = new MenuItemGroup();
945 let menuItemsObjects: any[] = this.updateMenuItemByRole(this.sdcMenu.component_workspace_menu_option[this.$scope.component.getComponentSubType()], this.role);
946 if (this.$scope.component.getComponentSubType() === 'SERVICE') {
947 const menuItemsObjectsCategory: any[] = this.updateMenuItemByCategory(menuItemsObjects, this.category);
948 menuItemsObjects = menuItemsObjectsCategory;
951 // Only adding plugins to the workspace if they can be displayed for the current user role
952 _.each(PluginsConfiguration.plugins, (plugin: Plugin) => {
953 if (this.pluginsService.isPluginDisplayedInContext(plugin, this.role, this.$scope.component.getComponentSubType())) {
954 menuItemsObjects.push({
955 text: plugin.pluginDisplayOptions['context'].displayName,
956 action: 'onMenuItemPressed',
957 state: 'workspace.plugins',
958 params: {path: plugin.pluginStateUrl}
963 this.$scope.leftBarTabs.menuItems = menuItemsObjects.map((item: MenuItem) => {
964 const menuItem = new MenuItem(item.text, item.callback, item.state, item.action, item.params, item.blockedForTypes, item.disabledCategory);
965 if (menuItem.params) {
966 menuItem.params.state = menuItem.state;
969 menuItem.params = {state: menuItem.state};
971 menuItem.callback = () => this.$scope[menuItem.action](menuItem.state, menuItem.params);
972 menuItem.isDisabled = (inCreateMode && States.WORKSPACE_GENERAL !== menuItem.state) ||
973 (States.WORKSPACE_DEPLOYMENT === menuItem.state && this.$scope.component.modules
974 && this.$scope.component.modules.length === 0 && this.$scope.component.isResource()) ||
975 (menuItem.disabledCategory === true);
979 if (this.cacheService.get('breadcrumbsComponents')) {
980 this.initBreadcrumbs();
983 this.initBreadcrumbsComponents();
987 private showSuccessNotificationMessage = ():void => {
988 this.Notification.success({
989 message: this.$filter('translate')('IMPORT_VF_MESSAGE_CREATE_FINISHED_DESCRIPTION'),
990 title: this.$filter('translate')('IMPORT_VF_MESSAGE_CREATE_FINISHED_TITLE')
994 private setWorkspaceButtonState = (newState: boolean, callback?: Function) => {
995 this.$scope.unsavedChanges = newState;
996 this.$scope.unsavedChangesCallback = callback;
999 private initBreadcrumbsComponents = (): void => {
1000 let breadcrumbsComponentsObservable;
1001 if (this.$stateParams.previousState === 'dashboard') {
1002 breadcrumbsComponentsObservable = this.homeService.getAllComponents(true);
1003 } else if (this.$stateParams.previousState === 'catalog') {
1004 breadcrumbsComponentsObservable = this.catalogService.getCatalog();
1006 this.cacheService.remove('breadcrumbsComponentsState');
1007 this.cacheService.remove('breadcrumbsComponents');
1010 breadcrumbsComponentsObservable.subscribe((components) => {
1011 this.cacheService.set('breadcrumbsComponentsState', this.$stateParams.previousState);
1012 this.cacheService.set('breadcrumbsComponents', components);
1013 this.initBreadcrumbs();
1018 private verifyIfDependenciesExist(): void {
1019 let containsDependencies = [];
1020 if (this.$scope.component.componentType && this.$scope.component.uniqueId &&
1021 this.$scope.component.lifecycleState === 'CERTIFIED' && (this.$scope.component.isService() || this.$scope.component.getComponentSubType() === 'VF')) {
1022 this.ComponentServiceNg2.getDependencies(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response: IDependenciesServerResponse[]) => {
1023 containsDependencies = response.filter((version) => version.dependencies);
1024 if (containsDependencies.length > 0) {
1025 this.$scope.hasNoDependencies = false;
1027 this.$scope.hasNoDependencies = true;