From 5b593496b8f1b8e8be8d7d2dbcc223332e65a49b Mon Sep 17 00:00:00 2001 From: Michael Lando Date: Sun, 29 Jul 2018 16:13:45 +0300 Subject: re base code Change-Id: I12a5ca14a6d8a87e9316b9ff362eb131105f98a5 Issue-ID: SDC-1566 Signed-off-by: Michael Lando --- .../tabs/composition/composition-view-model.ts | 215 +++++- .../tabs/composition/composition-view.html | 167 +++-- .../workspace/tabs/composition/composition.less | 26 +- .../composition/tabs/details/details-view-model.ts | 28 +- .../composition/tabs/details/details-view.html | 5 +- .../properties-view-model.ts | 12 +- .../tabs/properties-and-attributes/properties.less | 1 + .../tabs/deployment/deployment-view-model.ts | 6 +- .../workspace/tabs/deployment/deployment-view.html | 2 +- .../workspace/tabs/deployment/deployment.less | 3 +- .../disribution-status-modal-view.html | 4 +- .../workspace/tabs/general/general-view-model.ts | 255 +++++-- .../workspace/tabs/general/general-view.html | 64 +- .../workspace/tabs/general/general.less | 36 +- .../resource-input/resource-inputs-view-model.ts | 236 +++---- .../service-input/service-inputs-view-model.ts | 758 ++++++++++----------- .../tabs/properties/properties-view-model.ts | 2 +- .../req-and-capabilities-view-model.ts | 2 +- 18 files changed, 1112 insertions(+), 710 deletions(-) (limited to 'catalog-ui/src/app/view-models/workspace/tabs') diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view-model.ts index 46c2d2edf9..a77377bac4 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view-model.ts +++ b/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view-model.ts @@ -19,22 +19,34 @@ */ 'use strict'; import * as _ from "lodash"; -import {Component, ComponentInstance, IAppMenu} from "app/models"; -import {SharingService, CacheService, EventListenerService, LeftPaletteLoaderService} from "app/services"; -import {ModalsHandler, GRAPH_EVENTS, ComponentFactory, ChangeLifecycleStateHandler, MenuHandler, EVENTS} from "app/utils"; -import {IWorkspaceViewModelScope} from "../../workspace-view-model"; -import {ComponentGenericResponse} from "app/ng2/services/responses/component-generic-response"; -import {Resource} from "app/models/components/resource"; -import {ResourceType,ComponentType} from "app/utils/constants"; -import {ComponentServiceFactoryNg2} from "app/ng2/services/component-services/component.service.factory"; -import {ServiceGenericResponse} from "app/ng2/services/responses/service-generic-response"; -import {Service} from "app/models/components/service"; +import { Component, ComponentInstance, IAppMenu, Requirement, Capability, ButtonModel } from "app/models"; +import { SharingService, CacheService, EventListenerService, LeftPaletteLoaderService } from "app/services"; +import { ModalsHandler, GRAPH_EVENTS, ComponentFactory, ChangeLifecycleStateHandler, MenuHandler, EVENTS, ComponentInstanceFactory } from "app/utils"; +import { IWorkspaceViewModelScope } from "../../workspace-view-model"; +import { ComponentGenericResponse } from "app/ng2/services/responses/component-generic-response"; +import { Resource } from "app/models/components/resource"; +import { ResourceType, ComponentType } from "app/utils/constants"; +import { ComponentServiceFactoryNg2 } from "app/ng2/services/component-services/component.service.factory"; +import { ServiceGenericResponse } from "app/ng2/services/responses/service-generic-response"; +import { Service } from "app/models/components/service"; +import { ZoneInstance } from "app/models/graph/zones/zone-instance"; +import { ComponentServiceNg2 } from "app/ng2/services/component-services/component.service"; +import { ModalService as ModalServiceSdcUI} from "sdc-ui/lib/angular/modals/modal.service" +import { IModalConfig, IModalButtonComponent } from "sdc-ui/lib/angular/modals/models/modal-config"; +import { ValueEditComponent } from "app/ng2/components/ui/forms/value-edit/value-edit.component"; +import { UnsavedChangesComponent } from "../../../../ng2/components/ui/forms/unsaved-changes/unsaved-changes.component"; +import { ModalButtonComponent } from "sdc-ui/lib/angular/components"; + export interface ICompositionViewModelScope extends IWorkspaceViewModelScope { currentComponent:Component; + + //Added for now, in the future need to remove and use only id and type to pass to tabs. selectedComponent: Component; + selectedZoneInstance: ZoneInstance; + componentInstanceNames: Array; isLoading:boolean; graphApi:any; @@ -42,21 +54,24 @@ export interface ICompositionViewModelScope extends IWorkspaceViewModelScope { sdcMenu:IAppMenu; version:string; isViewOnly:boolean; + isCanvasTagging:boolean; isLoadingRightPanel:boolean; disabledTabs:boolean; openVersionChangeModal(pathsToDelete:string[]):ng.IPromise; onComponentInstanceVersionChange(component:Component); isComponentInstanceSelected():boolean; - updateSelectedComponent():void + updateSelectedComponent():void; openUpdateModal(); deleteSelectedComponentInstance():void; onBackgroundClick():void; setSelectedInstance(componentInstance:ComponentInstance):void; + setSelectedZoneInstance(zoneInstance: ZoneInstance):void; + changeZoneInstanceName(newName:string):void; printScreen():void; isPNF():boolean; isConfiguration():boolean; preventMoveTab(state: boolean):void; - + ComponentServiceNg2:ComponentServiceNg2, cacheComponentsInstancesFullData:Component; } @@ -76,8 +91,11 @@ export class CompositionViewModel { 'ChangeLifecycleStateHandler', 'LeftPaletteLoaderService', 'ModalsHandler', + 'ModalServiceSdcUI', 'EventListenerService', - 'ComponentServiceFactoryNg2' + 'ComponentServiceFactoryNg2', + 'ComponentServiceNg2', + 'Notification' ]; constructor(private $scope:ICompositionViewModelScope, @@ -93,8 +111,12 @@ export class CompositionViewModel { private ChangeLifecycleStateHandler:ChangeLifecycleStateHandler, private LeftPaletteLoaderService:LeftPaletteLoaderService, private ModalsHandler:ModalsHandler, + private ModalServiceSdcUI: ModalServiceSdcUI, private eventListenerService:EventListenerService, - private ComponentServiceFactoryNg2: ComponentServiceFactoryNg2) { + private ComponentServiceFactoryNg2: ComponentServiceFactoryNg2, + private ComponentServiceNg2:ComponentServiceNg2, + private Notification:any + ) { this.$scope.setValidState(true); this.initScope(); @@ -104,16 +126,17 @@ export class CompositionViewModel { private initGraphData = ():void => { - if(!this.$scope.component.componentInstances || !this.$scope.component.componentInstancesRelations ) { + if(!this.hasCompositionGraphData(this.$scope.component)) { this.$scope.isLoading = true; let service = this.ComponentServiceFactoryNg2.getComponentService(this.$scope.component); service.getComponentCompositionData(this.$scope.component).subscribe((response:ComponentGenericResponse) => { if (this.$scope.component.isService()) { ( this.$scope.component).forwardingPaths = (response).forwardingPaths; } - this.$scope.component.componentInstances = response.componentInstances; - this.$scope.component.componentInstancesRelations = response.componentInstancesRelations; - this.$scope.component.policies = response.policies; + this.$scope.component.componentInstances = response.componentInstances || []; + this.$scope.component.componentInstancesRelations = response.componentInstancesRelations || []; + this.$scope.component.policies = response.policies || []; + this.$scope.component.groupInstances = response.groupInstances || []; this.$scope.isLoading = false; this.initComponent(); this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_COMPOSITION_GRAPH_DATA_LOADED); @@ -124,25 +147,134 @@ export class CompositionViewModel { this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_COMPOSITION_GRAPH_DATA_LOADED); }; + private hasCompositionGraphData = (component:Component):boolean => { + return !!(component.componentInstances && component.componentInstancesRelations && component.policies && component.groupInstances); + }; private cacheComponentsInstancesFullData:Array; private initComponent = ():void => { this.$scope.currentComponent = this.$scope.component; this.$scope.selectedComponent = this.$scope.currentComponent; + this.$scope.selectedZoneInstance = null; this.updateUuidMap(); this.$scope.isViewOnly = this.$scope.isViewMode(); }; private registerGraphEvents = (scope:ICompositionViewModelScope):void => { this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_NODE_SELECTED, scope.setSelectedInstance); + this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_ZONE_INSTANCE_SELECTED, scope.setSelectedZoneInstance); this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED, scope.onBackgroundClick); + this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_CANVAS_TAG_START, () => { + scope.isCanvasTagging = true; + this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, true, this.showUnsavedChangesAlert); + }); + this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_CANVAS_TAG_END, () => { + scope.isCanvasTagging = false; + this.resetUnsavedChanges(); + }); + this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_ZONE_INSTANCE_NAME_CHANGED, scope.changeZoneInstanceName); + this.eventListenerService.registerObserverCallback(EVENTS.UPDATE_PANEL, this.removeSelectedZoneInstance); }; - private openUpdateComponentInstanceNameModal = ():void => { - this.ModalsHandler.openUpdateComponentInstanceNameModal(this.$scope.currentComponent).then(()=> { - this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_COMPONENT_INSTANCE_NAME_CHANGED, this.$scope.currentComponent.selectedInstance); + private showUnsavedChangesAlert = (afterSave?:Function):Promise => { + let deferred = new Promise((resolve, reject)=> { + const modal = this.ModalServiceSdcUI.openCustomModal( + { + title: "Unsaved Changes", + size: 'sm', + type: 'custom', + + buttons: [ + {id: 'cancelButton', text: 'Cancel', type: 'secondary', size: 'xsm', closeModal: true, callback: () => reject()}, + {id: 'discardButton', text: 'Discard', type: 'secondary', size: 'xsm', closeModal: true, callback: () => { this.resetUnsavedChanges(); resolve()}}, + {id: 'saveButton', text: 'Save', type: 'primary', size: 'xsm', closeModal: true, callback: () => { reject(); this.saveUnsavedChanges(afterSave); }} + ] as IModalButtonComponent[] + }, UnsavedChangesComponent, { isValidChangedData: true}); }); + + return deferred; + } + + private unRegisterGraphEvents = (scope: ICompositionViewModelScope):void => { + this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_NODE_SELECTED, scope.setSelectedInstance); + this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_ZONE_INSTANCE_SELECTED, scope.setSelectedZoneInstance); + this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED, scope.onBackgroundClick); + this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_CANVAS_TAG_START); + this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_CANVAS_TAG_END); + this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_ZONE_INSTANCE_NAME_CHANGED, scope.changeZoneInstanceName); + this.eventListenerService.unRegisterObserver(EVENTS.UPDATE_PANEL, this.removeSelectedZoneInstance); + + }; + + private resetUnsavedChanges = () => { + this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false); + } + + private saveUnsavedChanges = (afterSaveFunction?:Function):void => { + this.$scope.selectedZoneInstance.forceSave.next(afterSaveFunction); + this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false); + } + + private openUpdateComponentInstanceNameModal = ():void => { + + let modalConfig:IModalConfig = { + title: "Edit Name", + size: "sm", + type: "custom", + testId: "renameInstanceModal", + buttons: [ + {id: 'saveButton', text: 'OK', size: 'xsm', callback: this.saveInstanceName, closeModal: false}, + {id: 'cancelButton', text: 'Cancel', size: 'sm', closeModal: true} + ] + }; + + this.ModalServiceSdcUI.openCustomModal(modalConfig, ValueEditComponent, {name: this.$scope.currentComponent.selectedInstance.name, validityChangedCallback: this.enableOrDisableSaveButton}); + + }; + + + private enableOrDisableSaveButton = (shouldEnable: boolean): void => { + let saveButton: ModalButtonComponent = this.ModalServiceSdcUI.getCurrentInstance().getButtonById('saveButton'); + saveButton.disabled = !shouldEnable; + } + + private saveInstanceName = () => { + let currentModal = this.ModalServiceSdcUI.getCurrentInstance(); + let nameFromModal:string = currentModal.innerModalContent.instance.name; + + if(nameFromModal != this.$scope.currentComponent.selectedInstance.name){ + currentModal.buttons[0].disabled = true; + let componentInstanceModel:ComponentInstance = ComponentInstanceFactory.createComponentInstance(this.$scope.currentComponent.selectedInstance); + componentInstanceModel.name = nameFromModal; + + let onFailed = (error) => { + currentModal.buttons[0].disabled = false; + }; + let onSuccess = (componentInstance:ComponentInstance) => { + + this.$scope.currentComponent.selectedInstance.name = componentInstance.name; + //update requirements and capabilities owner name + _.forEach(this.$scope.currentComponent.selectedInstance.requirements, (requirementsArray:Array) => { + _.forEach(requirementsArray, (requirement:Requirement):void => { + requirement.ownerName = componentInstance.name; + }); + }); + + _.forEach(this.$scope.currentComponent.selectedInstance.capabilities, (capabilitiesArray:Array) => { + _.forEach(capabilitiesArray, (capability:Capability):void => { + capability.ownerName = componentInstance.name; + }); + }); + this.ModalServiceSdcUI.closeModal(); + this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_COMPONENT_INSTANCE_NAME_CHANGED, this.$scope.currentComponent.selectedInstance); + }; + + this.$scope.currentComponent.updateComponentInstance(componentInstanceModel).then(onSuccess, onFailed); + } else { + this.ModalServiceSdcUI.closeModal(); + } + }; private removeSelectedComponentInstance = ():void => { @@ -151,6 +283,12 @@ export class CompositionViewModel { this.$scope.selectedComponent = this.$scope.currentComponent; }; + private removeSelectedZoneInstance = ():void => { + this.$scope.currentComponent.selectedInstance = null; + this.$scope.selectedZoneInstance = null; + this.$scope.selectedComponent = this.$scope.currentComponent; + } + private updateUuidMap = ():void => { /** * In case user press F5, the page is refreshed and this.sharingService.currentEntity will be undefined, @@ -165,6 +303,7 @@ export class CompositionViewModel { this.$scope.sdcMenu = this.sdcMenu; this.$scope.isLoading = false; this.$scope.isLoadingRightPanel = false; + this.$scope.isCanvasTagging = false; this.$scope.graphApi = {}; this.$scope.version = this.cacheService.get('version'); this.initComponent(); @@ -175,6 +314,21 @@ export class CompositionViewModel { return this.$scope.currentComponent && this.$scope.currentComponent.selectedInstance != undefined && this.$scope.currentComponent.selectedInstance != null; }; + this.$scope.$on('$destroy', () => { + this.unRegisterGraphEvents(this.$scope); + }) + + this.$scope.restoreComponent = ():void => { + this.ComponentServiceNg2.restoreComponent(this.$scope.selectedComponent.componentType, this.$scope.selectedComponent.uniqueId).subscribe(() => { + this.Notification.success({ + message: '<' + this.$scope.component.name + '> ' + this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TEXT"), + title: this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TITLE") + }); + this.$scope.selectedComponent.archived = false; + } + ) + }; + this.$scope.updateSelectedComponent = ():void => { if (this.$scope.currentComponent.selectedInstance) { let parentComponentUid = this.$scope.currentComponent.selectedInstance.componentUid @@ -215,15 +369,25 @@ export class CompositionViewModel { this.$log.debug('composition-view-model::onNodeSelected:: with id: ' + selectedComponent.uniqueId); this.$scope.currentComponent.setSelectedInstance(selectedComponent); + this.$scope.selectedZoneInstance = null; this.$scope.updateSelectedComponent(); + + + if (this.$state.current.name === 'workspace.composition.api') { this.$state.go('workspace.composition.details'); } }; + this.$scope.setSelectedZoneInstance = (zoneInstance: ZoneInstance): void => { + this.$scope.currentComponent.selectedInstance = null; + this.$scope.selectedZoneInstance = zoneInstance; + }; + this.$scope.onBackgroundClick = ():void => { this.$scope.currentComponent.selectedInstance = null; + this.$scope.selectedZoneInstance = null; this.$scope.selectedComponent = this.$scope.currentComponent; if (this.$state.current.name === 'workspace.composition.api') { @@ -238,6 +402,10 @@ export class CompositionViewModel { this.$scope.openUpdateModal = ():void => { this.openUpdateComponentInstanceNameModal(); }; + + this.$scope.changeZoneInstanceName = (newName:string):void => { + this.$scope.selectedZoneInstance.instanceData.name = newName; + }; this.$scope.deleteSelectedComponentInstance = ():void => { const {currentComponent} = this.$scope; @@ -258,8 +426,7 @@ export class CompositionViewModel { modalText += `

The following service paths will be erased: ${pathNames}

`; } } - - this.ModalsHandler.openAlertModal(title, modalText).then(this.removeSelectedComponentInstance); + this.ModalServiceSdcUI.openAlertModal(title, modalText, "OK", this.removeSelectedComponentInstance, "deleteInstanceModal"); }; this.$scope.openVersionChangeModal = (pathsToDelete:string[]):ng.IPromise => { @@ -308,7 +475,7 @@ export class CompositionViewModel { this.$scope.disabledTabs = state; }; - this.eventListenerService.registerObserverCallback(EVENTS.ON_CHECKOUT, this.$scope.reload); + this.eventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.$scope.reload); } } diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view.html b/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view.html index fceb73b882..4cd33f3210 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view.html +++ b/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view.html @@ -2,7 +2,7 @@
@@ -19,86 +19,107 @@
-
-
-
-
+
+ +
+
+
+
+
-
- -
-
-
+
+ + + + + + + + + + + -
- - - - - - - - - - - +
+
-
+ + + +
+ + + +
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/composition.less b/catalog-ui/src/app/view-models/workspace/tabs/composition/composition.less index f351450e6d..b9bb66cde7 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/composition.less +++ b/catalog-ui/src/app/view-models/workspace/tabs/composition/composition.less @@ -107,7 +107,7 @@ position: fixed; right: -302px; width: 302px; - top: 102px; + top: 103px; transition: right 0.2s; z-index: 9; .box-shadow(-7px -3px 6px -8px @main_color_n); @@ -163,6 +163,13 @@ top: 10px; } + .w-sdc-designer-restore-button { + .hand; + position:absolute; + right: 20px; + top:10px; + width:65px; + } .w-sdc-designer-sidebar-tabs { .bg_c; } @@ -237,7 +244,7 @@ height: 32px; line-height: 32px; margin-top: 1px; - padding: 0 40px 0 20px; + padding: 0 10px 0 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -266,7 +273,7 @@ .sprite-new; .arrow-up; right: 16px; - top: 10px; + top: 13px; transition: .3s all; position: absolute; } @@ -664,8 +671,8 @@ align-items: center; .non-certified { position: relative; - left: 27px; - bottom: 6px; + left: -4px; + top: -4px; .sprite; .s-sdc-state-non-certified; display: block; @@ -682,8 +689,8 @@ .non-certified { position: relative; - left: 43px; - bottom: 3px; + left: 0px; + top: 0px; .sprite; .s-sdc-state-non-certified; display: block; @@ -841,6 +848,11 @@ flex-direction: column; align-items: flex-end; margin-right:10px; + pointer-events: none; + + & > * { + pointer-events: all; + } &.with-sidebar { right:320px; diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view-model.ts index 6e3258f69b..e389395142 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view-model.ts +++ b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view-model.ts @@ -143,19 +143,23 @@ export class DetailsViewModel { this.$scope.currentComponent.changeComponentInstanceVersion(componentUid).then(onSuccess, onCancel); }; - this.serviceService.checkComponentInstanceVersionChange(service, componentUid).subscribe((pathsToDelete:string[]) => { - if (pathsToDelete && pathsToDelete.length) { - this.$scope.isLoading = false; - this.$scope.$parent.isLoading = false; - this.$scope.$parent.openVersionChangeModal(pathsToDelete).then(() => { - this.$scope.isLoading = true; - this.$scope.$parent.isLoading = true; + if (this.$scope.currentComponent.isService()) { + this.serviceService.checkComponentInstanceVersionChange(service, componentUid).subscribe((pathsToDelete:string[]) => { + if (pathsToDelete && pathsToDelete.length) { + this.$scope.isLoading = false; + this.$scope.$parent.isLoading = false; + this.$scope.$parent.openVersionChangeModal(pathsToDelete).then(() => { + this.$scope.isLoading = true; + this.$scope.$parent.isLoading = true; + onUpdate(); + }, onCancel); + } else { onUpdate(); - }, onCancel); - } else { - onUpdate(); - } - }, onCancel); + } + }, onCancel); + } else { + onUpdate(); + } }; } } diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view.html b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view.html index 033c4668f3..9468937610 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view.html +++ b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view.html @@ -26,9 +26,10 @@ data-ng-if="!isComponentInstanceSelected()" data-tests-id="rightTab_version" data-ng-bind="selectedComponent.version"> -
+ + + @@ -147,16 +162,16 @@
- -
- {{(fileModel && fileModel.filename) || importedToscaBrowseFileText}} -
- -
Browse
-
+ +
+ {{(fileModel && fileModel.filename) || importedToscaBrowseFileText }} +
+ +
Browse
+
-
+
@@ -283,7 +298,7 @@
- +
- + + +
+ + +
+ +